块密码和 AES 加密不匹配
block cipher and AES encryption mismatch
我正在使用 AES 和加密来实现以下两个 classes。这是 AESCipher class,它接受一条消息,return 使用 Crypto python 库对其进行加密。
BS = 16
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
unpad = lambda s : s[:-ord(s[len(s)-1:])]
class AESCipher:
def __init__(self,sec_param):
self.sec_param = sec_param
self.key = os.urandom(sec_param)
#msg is string only
def encrypt( self, msg):
msg = pad(msg)
tweak = Random.new().read( AES.block_size )
cipher = AES.new(self.key, AES.MODE_CFB, tweak )
return base64.b64encode(tweak + cipher.encrypt( msg ) )
def decrypt(self, enc):
enc = base64.b64decode(enc)
tweak = enc[:16]
cipher = AES.new(self.key, AES.MODE_CFB, tweak)
return unpad(cipher.decrypt( enc[16:] ))
和 class BC,代表分组密码。
class BC(object):
def __init__(self, sec_param):
self.sec_param = sec_param
def encrypt(self, message):
return AESCipher(sec_param).encrypt(message)
def decrypt(self, encryption):
return AESCipher(self.sec_param).decrypt(encryption)
然而,我的问题是,虽然这看起来应该有效,但实际上无效。我正在调用 AESCipher 来加密和解密,就像在 AESCipher class 中一样,但结果不同,并且在这种情况下解密不会 return 原始消息。我不知道为什么会发生这种情况,因为它与被调用的 methods/classes 相同。
示例:
msg = '100011010111110'
sec_param = 16
bc = BC(sec_param)
encr = bc.encrypt(msg)
decr = bc.decrypt(encr)
new_cipher = AESCipher(sec_param)
C = new_cipher.encrypt(msg)
D= new_cipher.decrypt(C)
我希望 encr 等于 C,decr 等于 D。我还希望 decr 实际上 return 消息。但是其中 none 发生了。这是什么原因?
edit1:AESCipher class 有自己的作品。它正确地加密和解密。
encr
不等于C
因为各自有不同的tweak
(IV).
十六进制显示 encr
和 C
所以验证 tweak
是否在您期望的位置。在通过十六进制转储所有输入和输出的调试方法中:cipher
、tweak
、msg
和 self.key
.
在 decrypt
中将 enc[16:]
放入临时变量中以更好地隔离函数并获得调试输出。
正如 Artjom B. 所指出的,AESCipher
有两个单独的实例化,并且 init 函数创建了密钥,所以密钥是不同的,所以我们期望加密数据是不同的。
实例化不同:BC
和 AESCipher
使得问题更难发现。
问题是您在 AESCipher
的实例化过程中生成了一个新密钥。如果你使用同一个实例进行加密和解密,你也将使用相同的密钥,一切都会OK。如果您使用不同的 AESCipher
个实例,那么您将有不同的密钥和错误的解密文本。
密钥通常从外部传递到函数中,而不是由密码对象本身生成。
我正在使用 AES 和加密来实现以下两个 classes。这是 AESCipher class,它接受一条消息,return 使用 Crypto python 库对其进行加密。
BS = 16
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
unpad = lambda s : s[:-ord(s[len(s)-1:])]
class AESCipher:
def __init__(self,sec_param):
self.sec_param = sec_param
self.key = os.urandom(sec_param)
#msg is string only
def encrypt( self, msg):
msg = pad(msg)
tweak = Random.new().read( AES.block_size )
cipher = AES.new(self.key, AES.MODE_CFB, tweak )
return base64.b64encode(tweak + cipher.encrypt( msg ) )
def decrypt(self, enc):
enc = base64.b64decode(enc)
tweak = enc[:16]
cipher = AES.new(self.key, AES.MODE_CFB, tweak)
return unpad(cipher.decrypt( enc[16:] ))
和 class BC,代表分组密码。
class BC(object):
def __init__(self, sec_param):
self.sec_param = sec_param
def encrypt(self, message):
return AESCipher(sec_param).encrypt(message)
def decrypt(self, encryption):
return AESCipher(self.sec_param).decrypt(encryption)
然而,我的问题是,虽然这看起来应该有效,但实际上无效。我正在调用 AESCipher 来加密和解密,就像在 AESCipher class 中一样,但结果不同,并且在这种情况下解密不会 return 原始消息。我不知道为什么会发生这种情况,因为它与被调用的 methods/classes 相同。
示例:
msg = '100011010111110'
sec_param = 16
bc = BC(sec_param)
encr = bc.encrypt(msg)
decr = bc.decrypt(encr)
new_cipher = AESCipher(sec_param)
C = new_cipher.encrypt(msg)
D= new_cipher.decrypt(C)
我希望 encr 等于 C,decr 等于 D。我还希望 decr 实际上 return 消息。但是其中 none 发生了。这是什么原因?
edit1:AESCipher class 有自己的作品。它正确地加密和解密。
encr
不等于C
因为各自有不同的tweak
(IV).
十六进制显示 encr
和 C
所以验证 tweak
是否在您期望的位置。在通过十六进制转储所有输入和输出的调试方法中:cipher
、tweak
、msg
和 self.key
.
在 decrypt
中将 enc[16:]
放入临时变量中以更好地隔离函数并获得调试输出。
正如 Artjom B. 所指出的,AESCipher
有两个单独的实例化,并且 init 函数创建了密钥,所以密钥是不同的,所以我们期望加密数据是不同的。
实例化不同:BC
和 AESCipher
使得问题更难发现。
问题是您在 AESCipher
的实例化过程中生成了一个新密钥。如果你使用同一个实例进行加密和解密,你也将使用相同的密钥,一切都会OK。如果您使用不同的 AESCipher
个实例,那么您将有不同的密钥和错误的解密文本。
密钥通常从外部传递到函数中,而不是由密码对象本身生成。