PyCryptodome AES CBC解密后数据不匹配问题排查求助
解决AES-128 CBC加解密后明文不一致的问题
我来帮你排查这个问题!AES-CBC模式解密后和原明文不一致,大概率是几个核心环节没处理对,我先梳理常见坑点,再给你完整的可运行代码。
常见问题排查方向
- 初始化向量(IV)不匹配:CBC模式必须使用随机生成的IV,且加密和解密必须用同一个IV——这是最容易踩的坑!很多人要么加密时没生成IV,要么解密时用了新的IV,直接导致解密结果乱码。
- 填充/去填充操作不一致:加密时用
pad处理明文,解密时必须用unpad还原,而且两者的块大小必须统一(AES固定是16字节)。 - 密文处理不当:加密后的字节流如果直接存储或传输,可能会出现编码问题,建议用Base64编码后再处理,解密时先解码。
- 密钥不一致:虽然你的密钥
b'Sixteen byte key'刚好符合AES-128的16字节要求,但要确保解密时用的密钥和加密时完全一样。
完整的正确实现代码
from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad from Crypto.Random import get_random_bytes import base64 # AES-128要求密钥必须是16字节,你的密钥是合法的 key = b'Sixteen byte key' plaintext = 'Jeevan B Manoj'.encode("UTF-8") # ---------------- 加密流程 ---------------- # 生成随机IV,长度等于AES块大小(16字节),IV不需要保密,但必须和密文一起传递 iv = get_random_bytes(AES.block_size) # 创建CBC模式的加密器 cipher_encrypt = AES.new(key, AES.MODE_CBC, iv) # 对明文填充后加密(因为AES要求明文长度是块大小的整数倍) ciphertext = cipher_encrypt.encrypt(pad(plaintext, AES.block_size)) # 将IV和密文拼接后用Base64编码,方便存储/传输 encrypted_data = base64.b64encode(iv + ciphertext).decode('utf-8') print("加密结果:", encrypted_data) # ---------------- 解密流程 ---------------- # 先解码Base64数据 encrypted_bytes = base64.b64decode(encrypted_data) # 从开头提取IV(前16字节) iv_decrypt = encrypted_bytes[:AES.block_size] # 剩余部分是密文 ciphertext_decrypt = encrypted_bytes[AES.block_size:] # 创建CBC模式的解密器,必须使用加密时的密钥和IV cipher_decrypt = AES.new(key, AES.MODE_CBC, iv_decrypt) # 解密后去除填充,还原明文 decrypted_text = unpad(cipher_decrypt.decrypt(ciphertext_decrypt), AES.block_size) print("解密结果:", decrypted_text.decode('utf-8'))
关键细节解释
- IV的处理:加密时生成随机IV,并且和密文绑定在一起(这里是拼接后编码),解密时从加密数据中提取IV,确保加密解密用同一个IV。
- 填充操作:
pad会自动把明文补全到16字节的整数倍,unpad则会在解密后移除这些填充字节,两者必须配对使用。 - Base64编码:加密后的字节流是二进制数据,直接转字符串可能会有乱码,用Base64编码成可打印字符串,避免数据损坏。
对比你的代码片段,大概率是没正确处理IV,或者解密时遗漏了unpad步骤,你可以对照上面的代码调整试试。
内容的提问来源于stack exchange,提问作者Jeevan
相关产品推荐
相关产品推荐

