PyCryptoDome/cryptography python 中与 AES-CFB 的不平等
PyCryptoDome/cryptography inequality with AES-CFB in python
虽然 运行 进行了一项测试以确保两个不同的库提供相同的输出,但我发现它们与 CFB
不同。复制问题的代码是:
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from Crypto.Cipher import AES
KEY = b'legoroojlegorooj'
IV = b'legoroojlegorooj'
aes = Cipher(algorithms.AES(KEY), modes.CFB(IV), default_backend()).encryptor()
output_data = aes.update(b'Feathers fall as fast as bowling balls.') + aes.finalize()
del aes
ctr = AES.new(KEY, AES.MODE_CFB, iv=IV)
output_data2 = ctr.encrypt(b'Feathers fall as fast as bowling balls.')
assert output_data == output_data2 # AssertionError
任何帮助解决这个问题的人都将不胜感激。
此代码适用于 modes.OFB(IV)
和 AES.MODE_OFB
。
在CFB mode中必须指定移位寄存器的大小,因此不同的库通常使用不同的默认值。为了区别,以位为单位的移位寄存器的大小通常附加到 CFB,即 CFB8 使用 8 位移位寄存器,CFB128 使用 128 位移位寄存器。
Cryptography has the two variants CFB8 and CFB128, where the latter is simply called CFB. PyCryptodome允许使用参数segment_size
设置8位的整数倍,默认值为8位。
因此在当前代码中 Cryptography 使用 CFB128 而 PyCryptodome 使用 CFB8(其默认值),这导致了不同的结果。
以下组合有效:
PyCryptodome 与 segment_size=128
和 Cryptography 与 CFB。两者对应CFB128:
# CFB with a 128 bit shift-register
# Output as hex-string: 63230751cc1efe25b980d9e707396a1a171cd413e6e77f1cd7a2d3deb2217255a36ae9cbf86c66
...
aes = Cipher(algorithms.AES(KEY), modes.CFB(IV), default_backend()).encryptor()
...
ctr = AES.new(KEY, AES.MODE_CFB, iv=IV, segment_size=128)
...
PyCryptodome 使用 segment_size=8
(默认值)和 Cryptography 使用 CFB8。都对应CFB8:
# CFB with a 8 bit shift-register
# Output as hex-string: 63d263889ffe94dd4740580067ee798da474c567b8b54319a5022650085c62674628f7c9e790c3
...
aes = Cipher(algorithms.AES(KEY), modes.CFB8(IV), default_backend()).encryptor()
...
ctr = AES.new(KEY, AES.MODE_CFB, iv=IV, segment_size=8)
...
请注意,(1) Python 两个库都为 OFB mode 提供相同的结果,因为它们都使用 OFB128。 (2) CFB128 比 CFB8 快:在 CFB8 中,每个块必须调用 AES 加密 16 次,而在 CFB128 中为 1 次。
虽然 运行 进行了一项测试以确保两个不同的库提供相同的输出,但我发现它们与 CFB
不同。复制问题的代码是:
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from Crypto.Cipher import AES
KEY = b'legoroojlegorooj'
IV = b'legoroojlegorooj'
aes = Cipher(algorithms.AES(KEY), modes.CFB(IV), default_backend()).encryptor()
output_data = aes.update(b'Feathers fall as fast as bowling balls.') + aes.finalize()
del aes
ctr = AES.new(KEY, AES.MODE_CFB, iv=IV)
output_data2 = ctr.encrypt(b'Feathers fall as fast as bowling balls.')
assert output_data == output_data2 # AssertionError
任何帮助解决这个问题的人都将不胜感激。
此代码适用于 modes.OFB(IV)
和 AES.MODE_OFB
。
在CFB mode中必须指定移位寄存器的大小,因此不同的库通常使用不同的默认值。为了区别,以位为单位的移位寄存器的大小通常附加到 CFB,即 CFB8 使用 8 位移位寄存器,CFB128 使用 128 位移位寄存器。
Cryptography has the two variants CFB8 and CFB128, where the latter is simply called CFB. PyCryptodome允许使用参数segment_size
设置8位的整数倍,默认值为8位。
因此在当前代码中 Cryptography 使用 CFB128 而 PyCryptodome 使用 CFB8(其默认值),这导致了不同的结果。
以下组合有效:
PyCryptodome 与
segment_size=128
和 Cryptography 与 CFB。两者对应CFB128:# CFB with a 128 bit shift-register # Output as hex-string: 63230751cc1efe25b980d9e707396a1a171cd413e6e77f1cd7a2d3deb2217255a36ae9cbf86c66 ... aes = Cipher(algorithms.AES(KEY), modes.CFB(IV), default_backend()).encryptor() ... ctr = AES.new(KEY, AES.MODE_CFB, iv=IV, segment_size=128) ...
PyCryptodome 使用
segment_size=8
(默认值)和 Cryptography 使用 CFB8。都对应CFB8:# CFB with a 8 bit shift-register # Output as hex-string: 63d263889ffe94dd4740580067ee798da474c567b8b54319a5022650085c62674628f7c9e790c3 ... aes = Cipher(algorithms.AES(KEY), modes.CFB8(IV), default_backend()).encryptor() ... ctr = AES.new(KEY, AES.MODE_CFB, iv=IV, segment_size=8) ...
请注意,(1) Python 两个库都为 OFB mode 提供相同的结果,因为它们都使用 OFB128。 (2) CFB128 比 CFB8 快:在 CFB8 中,每个块必须调用 AES 加密 16 次,而在 CFB128 中为 1 次。