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 模式下,必须指定移位寄存器的大小,因此不同的库通常使用不同的默认值。为了区分,移位寄存器的大小通常附加到CFB,即CFB8使用8位的移位寄存器,CFB128使用128位的移位寄存器。

密码学有两个变体CFB8和CFB128,后者简称为CFB。PyCryptodome允许使用默认值为 8 位的参数segment_size进行 8 位整数倍的设置。

因此,在当前代码中,Cryptography使用CFB128,PyCryptodome使用CFB8(其默认值(,这会导致不同的结果。

以下组合有效:

  • PyCryptodomewithsegment_size=128andCryptographywith 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)
    ...
    
  • PyCryptodomewithsegment_size=8(默认值(和Cryptographywith 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 模式提供了相同的结果,因为两者都使用 OFB128。(2( CFB128 比 CFB8 快:在 CFB8 中,每个块必须调用 AES 加密 16 次,而 CFB128 需要调用 1 次。

最新更新