Dart与Python AES-CTR加密结果不一致,Python仅生成部分密文
问题分析
你遇到的核心问题是Dart端的加密库默认对明文做了PKCS7填充,而Python端直接加密原始明文:
- Dart的
encrypt库在AES-CTR模式下,默认会将明文填充至AES块大小(16字节),所以"test"(4字节)被填充为16字节后加密,得到16字节密文。 - Python的
pycryptodome库在CTR模式下不自动填充,直接加密4字节的"test",得到4字节密文,因此仅前4字节与Dart结果匹配。
解决方案
有两种方式可以让两端加密结果完全一致,选其一即可:
方案1:Dart端禁用填充
修改Dart代码中AES模式的初始化,明确指定不使用填充:
enc.Encrypter encrypter = enc.Encrypter(enc.AES( aesKey, mode: enc.AESMode.ctr, padding: null, // 禁用填充 ));
这样加密"test"会直接生成4字节密文,与Python端的加密结果完全一致。
方案2:Python端添加PKCS7填充
在Python端对明文执行与Dart端一致的PKCS7填充后再加密:
首先实现PKCS7填充函数:
def pkcs7_pad(data, block_size=16): padding_len = block_size - len(data) % block_size return data + bytes([padding_len]) * padding_len
然后修改加密逻辑:
test = "test".encode('utf-8') # 先填充再加密 padded_test = pkcs7_pad(test) encrypted = cipher.encrypt(padded_test)
此时Python生成的16字节密文会与Dart端完全匹配。
额外验证
你已经确认两端的SHA256密钥一致,且Counter的初始化(大端字节序)正确,这部分无需修改。前4字节密文匹配也证明了密钥和Counter逻辑是正确的,问题仅出在明文填充的差异上。
内容的提问来源于stack exchange,提问作者Bagheera
相关产品推荐
相关产品推荐

