PyCryptoDome:AES-256使用相同的密钥和放大器提供不同的输出。数据

时间:2017-12-27 10:26:34

标签: python python-3.x aes pycrypto pycryptodome

以下代码每次执行时都会产生不同的ciphertext,这不会发生,因为密钥&每次执行时传递的数据都是相同的。

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from base64 import b64encode, b64decode

key = '/I02fMuSSvnouuu+/vyyD7NuSEVDB/0gte/z50dM0b4='
data = 'hello world!'

cipher = AES.new(b64decode(key), AES.MODE_CBC)
padded_data = pad(data.encode(), cipher.block_size)
print(b64encode(padded_data))
# b'aGVsbG8gd29ybGQhBAQEBA=='
ciphertext = cipher.encrypt(padded_data)
print(b64encode(ciphertext))
# b'rEHH0MWIWCWUldjYBco9TA=='
ciphertext = cipher.encrypt(padded_data)
print(b64encode(ciphertext))
# b'FTpLrkZttDxMlpre3Kq8qQ=='

我实际上是尝试将示例PHP代码复制到Python,PHP代码提供相同的输出,我的Python代码提供不同的输出,其中没有一个与PHP的匹配。

Python版本3.6.x
PyCryptoDome版本3.4.7

2 个答案:

答案 0 :(得分:4)

每次使用Pycryptodome 在CBC模式下生成AES密码对象时,都会创建并使用随机IV。它可以作为名为iv的属性(例如cipher.iv)进行访问。

独特(且不可预测)的IV实现了随机化输出的目标,即使相同的消息被多次加密(使用相同的密钥),这是攻击者经常可以利用的一条信息。

您不会显示PHP代码,但如果其输出每次都 NOT 更改,则表示IV已修复且代码存在安全漏洞。

答案 1 :(得分:0)

我在创建cipher对象时忘了传递iv parameter

应该是 -

cipher = AES.new(b64decode(key), AES.MODE_CBC, iv=b'0123456789abcdef')

是的,正确pointed out by Rawing,重复使用相同的cipher对象进行加密会产生不同的结果,但如果重建cipher对象,它将始终提供相同的输出。 / p>

cipher = AES.new(b64decode(key), AES.MODE_CBC, iv=b'0123456789abcdef')
padded_data = pad(data.encode(), cipher.block_size)
print(b64encode(padded_data))
# b'aGVsbG8gd29ybGQhBAQEBA=='
ciphertext = cipher.encrypt(padded_data)
print(b64encode(ciphertext))
# b'8G0KL2UiCv7Uo+pKMm9G+A=='
ciphertext = cipher.encrypt(padded_data)
print(b64encode(ciphertext))
# b'tBXcf/Nf6MtxM1ulzNnIlw=='


cipher = AES.new(b64decode(key), AES.MODE_CBC, iv=b'0123456789abcdef')
padded_data = pad(data.encode(), cipher.block_size)
ciphertext = cipher.encrypt(padded_data)
print(b64encode(ciphertext))
# b'8G0KL2UiCv7Uo+pKMm9G+A=='