以下代码每次执行时都会产生不同的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
答案 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=='