AES CTR 解密:Cryptography 和 Cryptodome 给出不同的结果

Mic*_*mza 2 python cryptography aes python-cryptography pycryptodome

下面的代码片段使用 Cryptodome 进行 AES 解密,效果符合我的预期:

from Crypto.Cipher import AES
from Crypto.Util import Counter

key = b'\x12' * 32
decryptor = AES.new(key, AES.MODE_CTR,counter=Counter.new(nbits=128, little_endian=True))
print(decryptor.decrypt(b'Something encrypted'))
Run Code Online (Sandbox Code Playgroud)

下面使用Python Cryptography,并给出不同的结果:

from cryptography.hazmat.primitives.ciphers import Cipher, modes, algorithms

key = b'\x12' * 32
decryptor = Cipher(algorithms.AES(key), modes.CTR(b'\0' * 16)).decryptor()
print(decryptor.update(b'Something encrypted'))
Run Code Online (Sandbox Code Playgroud)

为什么?如何更改 Python Cryptography 版本以输出与 Cryptodome 相同的结果?

(上下文正在编写用于解压缩文件的 AES 解密代码,并且正在考虑使用 Python 加密)

Top*_*aco 5

在 PyCryptodome 中,计数器默认从 1 开始。此外,小端的计数器计数如下:0x0100...0000, 0x0200...0000, 0x0300...0000等等。

由于在密码学中无法配置计数器的字节序并且使用大字节序,因此无法实现此计数。虽然起始值可以显式设置为0x0100...00,但计数器将进行计数:0x0100...0000, 0x0100...0001, 0x0100...0002等等。

这可以通过以下代码进行验证:

from Crypto.Cipher import AES
from Crypto.Util import Counter
key = b'\x12' * 32
decryptor = AES.new(key, AES.MODE_CTR,counter=Counter.new(nbits=128, little_endian=True, initial_value=1))
print(decryptor.decrypt(b'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx').hex())

from cryptography.hazmat.primitives.ciphers import Cipher, modes, algorithms
key = b'\x12' * 32
decryptor = Cipher(algorithms.AES(key), modes.CTR(b'\x01' + b'\0' * 15)).decryptor()
print(decryptor.update(b'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx').hex())
Run Code Online (Sandbox Code Playgroud)

输出:

faebe2ab213094fcd5c9ec3dae32372b 13b3b971b7694faa5e15f5387ac5a67f bc5dbc82ce54cf1bbe2719488b322078
faebe2ab213094fcd5c9ec3dae32372b 6ddda72218780c287bc74956395bf7db 0603820b26889ec64e7f7964a14518c5
Run Code Online (Sandbox Code Playgroud)

由于第一个块的计数器值匹配,因此第一个块是相同的。然而,由于后续块的值不同,后续块也不同。

当 PyCryptodome 配置为小端时,我目前没有看到如何使用加密库来生成 PyCryptodome 库结果。