AES CTR解密:Cryptography与Cryptodome运行结果不一致问题求解
差异原因
两个库对CTR模式的计数器字节序(端序)配置不同,是结果不一致的核心原因:
- 你使用的Cryptodome代码中,通过
Counter.new(nbits=128, little_endian=True)显式指定了计数器使用小端序:计数器数值递增后,会按照小端规则转为16字节块作为AES算法的输入。 - Cryptography库的CTR模式默认使用大端序(网络字节序):计数器数值递增后按照大端规则转为16字节块,和Cryptodome的AES输入块完全不同,最终异或得到的解密结果自然不一致。
修改方案
Cryptography的原生CTR模式不支持直接配置小端序,我们可以手动生成符合小端序规则的密钥流,再和密文异或得到和Cryptodome版本完全一致的解密结果,修改后代码如下:
from cryptography.hazmat.primitives.ciphers import Cipher, modes, algorithms from cryptography.hazmat.backends import default_backend key = b'\x12' * 32 ciphertext = b'Something encrypted' block_size = algorithms.AES.block_size num_blocks = (len(ciphertext) + block_size - 1) // block_size # 使用ECB模式加密小端序计数器生成密钥流 ecb_encryptor = Cipher(algorithms.AES(key), modes.ECB(), backend=default_backend()).encryptor() key_stream = b'' for i in range(num_blocks): # 计数器按小端序转为16字节块 ctr_block = i.to_bytes(16, byteorder='little') key_stream += ecb_encryptor.update(ctr_block) # 密文与密钥流逐字节异或得到明文 plaintext = bytes(a ^ b for a, b in zip(ciphertext, key_stream)) print(plaintext)
该方案性能和原生CTR模式基本持平,完全可以满足文件解压类场景的性能需求。
内容的提问来源于stack exchange,提问作者Michal Charemza
相关产品推荐
相关产品推荐

