我使用AES和Crypto来实现以下两个类。这是AESCipher类,它接收消息,并使用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:] ))
和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进行加密和解密很多,但结果不同,在这种情况下解密不会返回原始消息。我不知道为什么会发生这种情况,因为它与被调用的方法/类相同。
示例:
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实际返回msg。但这些都不会发生。是什么原因?
edit1:AESCipher类本身就可以了。它正确加密和解密。
答案 0 :(得分:2)
问题是你在AESCipher
的实例化期间生成了一个新密钥。如果您使用相同的实例进行加密和解密,您也将使用相同的密钥,一切都会正常。如果您使用不同的AESCipher
个实例,那么您将拥有不同的密钥和错误的解密文本。
键通常从外部传递到函数中,而不是由密码对象本身生成。
答案 1 :(得分:1)
encr
不等于C
,因为每个tweak
(IV)都不同。
十六进制显示encr
和C
,因此请确认tweak
位于您预期的位置。在方法调试中,通过十六进制转储所有输入和输出:cipher
,tweak
,msg
和self.key
。
在decrypt
中将enc[16:]
放入临时变量中以更好地隔离函数并获得调试输出。
正如Artjom B.指出,AESCipher
有两个独立的实例,init函数创建密钥,因此密钥不同,所以我们希望加密数据不同。
实例化不同:BC
和AESCipher
使得查看问题变得更加困难。