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

问题描述 投票:0回答:2

以下代码每次执行时都会生成不同的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

python python-3.x aes pycrypto pycryptodome
2个回答
4
投票

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

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

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


0
投票

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

应该是这样的 -

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

是的,正确的pointed out by Rawing,重复使用相同的cipher对象加密将给出不同的结果,但如果你重建cipher对象,它将始终给出相同的输出。

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=='
© www.soinside.com 2019 - 2024. All rights reserved.