如何在没有盐的Python中用AES加密?

时间:2017-11-24 12:36:25

标签: python encryption aes salt

我想在Python中使用AES加密某些数据,以便对相同数据的两次加密提供相同的输出(在两次加密中使用相同的密钥)。我尝试使用静态IV但是在给定一个输入的情况下我仍然得到两个不同的输出。

这是我做的:

from Crypto.Cipher import AES

iv = 16 * '\x00'
cipher = AES.new(key, AES.MODE_CBC, iv)

如果我决定多次加密相同的数据,我想获得相同的密码。 你知道如何防止使用盐吗? 谢谢!

1 个答案:

答案 0 :(得分:2)

这里的cipher对象是状态,并使用提供的密钥数据和初始化向量进行初始化。一旦开始使用此初始化的密钥状态,就会对使用CBC模式时加密的每个块进行修改。这就是密码块的链接。要进行两次单独的加密,您需要使用两个单独的密钥状态。或者,如上所述,您可以使用在加密块时不影响keystate的模式(ECB)。

演示(python3):

from Crypto.Cipher import AES
key = 16 * b'\0'
iv = 16 * b'\0'
plaintext = 16 * b'\x41'
a = AES.new(key, AES.MODE_CBC, iv)
b = AES.new(key, AES.MODE_CBC, iv)
ar = a.encrypt(plaintext)
br = b.encrypt(plaintext)
>>> ar
b'\xb4\x9c\xbf\x19\xd3W\xe6\xe1\xf6\x84\\0\xfd[c\xe3'
>>> br
b'\xb4\x9c\xbf\x19\xd3W\xe6\xe1\xf6\x84\\0\xfd[c\xe3'

ECB模式的缺点是每次我们用这个密钥加密这个明文,我们就会得到这个结果。使用CBC模式,每次我们加密另一个块时,keystate都会被更改,我们会得到一个不同的输出,这取决于之前加密的内容。

ECB模式

>>> ecb = AES.new(16 * b'\0', AES.MODE_ECB)
>>> ecb.encrypt(16 * b'\x41')
b'\xb4\x9c\xbf\x19\xd3W\xe6\xe1\xf6\x84\\0\xfd[c\xe3'
>>> ecb.encrypt(16 * b'\x41')
b'\xb4\x9c\xbf\x19\xd3W\xe6\xe1\xf6\x84\\0\xfd[c\xe3'

每次加密都会产生相同的结果。不需要iv。

CBC模式

>>> cbc = AES.new(16 * b'\0', AES.MODE_CBC, 16 * b'\0')
>>> cbc.encrypt(16 * b'\x41')
b'\xb4\x9c\xbf\x19\xd3W\xe6\xe1\xf6\x84\\0\xfd[c\xe3'
>>> cbc.encrypt(16 * b'\x41')
b'o\x9fv\x9a\x9c\xaa\x03\x13\xba\x17\x8c\x1c.\x0f`v'
>>> cbc.encrypt(16 * b'\x41')
b'\n1\x165\xb5?\x04h\xa8\r>k\xdbK\xbc4'

第一个块加密与ECB模式相同,但后续块不同。

关于分组密码modes of operation的更多讨论可以在网上找到。