分组密码和AES加密不匹配

时间:2016-08-29 12:52:29

标签: python-3.x cryptography aes

我使用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类本身就可以了。它正确加密和解​​密。

2 个答案:

答案 0 :(得分:2)

问题是你在AESCipher的实例化期间生成了一个新密钥。如果您使用相同的实例进行加密和解密,您也将使用相同的密钥,一切都会正常。如果您使用不同的AESCipher个实例,那么您将拥有不同的密钥和错误的解密文本。

键通常从外部传递到函数中,而不是由密码对象本身生成。

答案 1 :(得分:1)

encr不等于C,因为每个tweak(IV)都不同。

十六进制显示encrC,因此请确认tweak位于您预期的位置。在方法调试中,通过十六进制转储所有输入和输出:ciphertweakmsgself.key

decrypt中将enc[16:]放入临时变量中以更好地隔离函数并获得调试输出。

正如Artjom B.指出,AESCipher有两个独立的实例,init函数创建密钥,因此密钥不同,所以我们希望加密数据不同。

实例化不同:BCAESCipher使得查看问题变得更加困难。