PyCryptoDome:AES-256 使用相同的密钥和数据提供不同的输出
PyCryptoDome : AES-256 giving different output with same key & data
以下代码每次执行时都会产生不同的 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 代码给出不同的输出,none 其中匹配 PHP 一个。
Python 版本 3.6.x
PyCryptoDome 版本 3.4.7
我在创建 cipher
对象时忘记传递 iv
parameter。
应该是这样的-
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=='
每次使用 Pycryptodome 生成 CBC 模式的 AES 密码对象时,都会创建并使用随机 IV。它可以作为名为 iv
的属性访问(例如 cipher.iv
)。
独特的(不可预测的)IV 实现了随机化输出的目标,即使同一条消息被多次加密(使用相同的密钥),这是攻击者经常可以利用的一条信息。
你没有显示 PHP 代码,但是如果它的输出每次 NOT 都改变,这意味着 IV 是固定的并且代码有一个安全漏洞。
以下代码每次执行时都会产生不同的 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 代码给出不同的输出,none 其中匹配 PHP 一个。
Python 版本 3.6.x
PyCryptoDome 版本 3.4.7
我在创建 cipher
对象时忘记传递 iv
parameter。
应该是这样的-
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=='
每次使用 Pycryptodome 生成 CBC 模式的 AES 密码对象时,都会创建并使用随机 IV。它可以作为名为 iv
的属性访问(例如 cipher.iv
)。
独特的(不可预测的)IV 实现了随机化输出的目标,即使同一条消息被多次加密(使用相同的密钥),这是攻击者经常可以利用的一条信息。
你没有显示 PHP 代码,但是如果它的输出每次 NOT 都改变,这意味着 IV 是固定的并且代码有一个安全漏洞。