Python实现AES加密输出与预期不符 数据长度异常问题排查
问题根因
代码存在3个核心逻辑错误,直接导致运行结果不符合预期:
- 错误使用
__sizeof__()计算数据长度:__sizeof__()返回的是Python对象在内存中占用的总空间,包含对象元数据的内存开销,不是有效数据的长度。计算字节串、字符串的有效数据长度必须使用len(),你替换为len()后iv、密钥长度显示正常也验证了这一点。 - 明文转换逻辑错误:你的
msg和iv、密钥一样,是十六进制格式表示的原始二进制数据,你直接调用msg.encode()是把32个字符长度的十六进制字符串按ASCII编码转成了32字节的文本数据,而非十六进制对应的16字节原始明文。32字节数据经过PKCS7填充后会补16字节凑成3个AES块(共48字节),这就是你看到msg处理后长度为48字节的原因。 - 填充逻辑、输出格式和微控制器端不匹配:你使用的测试向量是标准AES-128-CBC无填充的块加密测试向量,16字节明文刚好匹配AES块大小,微控制器端如果是直接按块加密、没有启用PKCS7填充,Python端额外调用
pad()会多拼接一整块填充数据,加密结果必然错误;同时你最后把密文转成了base64格式,但你预期的expected是十六进制格式的密文,二者格式不匹配无法对比。
修正后可正常运行的代码
from binascii import unhexlify, hexlify from Crypto.Cipher import AES if __name__ == '__main__': iv = "000102030405060708090A0B0C0D0E0F" password = "2b7e151628aed2a6abf7158809cf4f3c" msg = "6bc1bee22e409f96e93d7e117393172a" expected = "7649abac8119b246cee98e9b12e9197d" # 统一把十六进制字符串转成原始字节 iv = unhexlify(iv) key = unhexlify(password) plaintext = unhexlify(msg) # 验证长度:iv、key、明文都是16字节,刚好匹配AES-128-CBC的块大小要求,无需额外填充 print(f"IV长度: {len(iv)} 字节") print(f"密钥长度: {len(key)} 字节") print(f"明文长度: {len(plaintext)} 字节") # 初始化加密器,微控制器端未启用填充时不要调用pad函数 cipher = AES.new(key, AES.MODE_CBC, iv) cipher_text = cipher.encrypt(plaintext) # 把密文转成十六进制字符串,和expected格式一致 cipher_hex = hexlify(cipher_text).decode('utf-8') print(f"加密结果(hex): {cipher_hex}") print(f"预期结果: {expected}") print(f"结果匹配: {cipher_hex.lower() == expected.lower()}") # 解密验证 decipher = AES.new(key, AES.MODE_CBC, iv) decrypt_raw = decipher.decrypt(cipher_text) print(f"解密结果(hex): {hexlify(decrypt_raw).decode('utf-8')}")
运行后可以看到加密结果和给出的expected值完全一致。
注意:如果后续需要加密长度不是16字节整数倍的数据,需要先确认微控制器端使用的填充规则(常见为PKCS7),Python端对应使用相同的填充逻辑即可,避免两端填充规则不匹配导致解密失败。
内容的提问来源于stack exchange,提问作者HansPeterLoft
相关产品推荐
相关产品推荐

