如何在 Python 中使用 AES 加密而不加盐?

How to encrypt with AES in Python with no salt?

我想在 Python 中使用 AES 加密一些数据,这样同一数据的两次加密会产生相同的输出(在两次加密中使用相同的密钥)。我尝试使用静态 IV,但在给定一个输入的情况下我仍然得到两个不同的输出。

这是我所做的:

from Crypto.Cipher import AES

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

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

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

演示 (python3):

from Crypto.Cipher import AES
key = 16 * b'[=10=]'
iv = 16 * b'[=10=]'
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 模式,每次我们加密另一个块时,密钥状态都会改变,我们会得到不同的输出,这取决于之前加密的内容。

欧洲央行模式

>>> ecb = AES.new(16 * b'[=11=]', 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'

每次加密都会产生相同的结果。不需要静脉注射。

CBC 模式

>>> cbc = AES.new(16 * b'[=12=]', AES.MODE_CBC, 16 * b'[=12=]')
>>> 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 块密码的进一步讨论。