Python与Java AES跨端解密报OPENSSL_internal:BAD_DECRYPT问题求助
问题分析与解决方案
核心问题原因
- Python加密函数返回错误数据:原
encrypt函数最后错误地将返回值覆盖为原始明文的字节数据,而非加密后的Base64字符串,导致Java端收到明文却尝试解密,触发BadPaddingException。 - 填充方式不兼容:Java使用标准
PKCS5PADDING(AES场景下等价于PKCS7Padding),而Python自定义的pad函数用空格填充到32字节倍数,完全不符合PKCS规范,导致解密时填充验证失败或出现乱码。 - Python解密未处理填充:原
decrypt函数未去除PKCS填充,可能导致结果包含多余无效字符。
修正后的Python代码
确保先安装依赖:pip install pycryptodome
from Crypto.Cipher import AES from Crypto.Random import get_random_bytes from Crypto.Util.Padding import pad, unpad import base64 class CryptoHandler: def __init__(self, key): self.inits = {'key': key} def decrypt(self, message): # 解码Base64 decoded_msg = base64.b64decode(message) # 分离IV(前16字节)与密文 iv = decoded_msg[:16] ciphertext = decoded_msg[16:] cipher = AES.new(self.inits['key'].encode("utf8"), AES.MODE_CBC, iv) # 解密后去除PKCS7填充 plaintext_bytes = unpad(cipher.decrypt(ciphertext), AES.block_size) return plaintext_bytes.decode('utf-8') def encrypt(self, data): # 生成16字节随机IV iv = get_random_bytes(16) cipher = AES.new(self.inits['key'].encode("utf8"), AES.MODE_CBC, iv) # 对明文做PKCS7填充后加密 padded_data = pad(data.encode('utf8'), AES.block_size) ciphertext = cipher.encrypt(padded_data) # 拼接IV与密文,再做Base64编码 encrypted_bytes = iv + ciphertext return base64.b64encode(encrypted_bytes).decode('utf-8')
Java端代码优化(非必需,仅精简冗余)
Java的encrypt函数中有两行冗余代码可删除,不影响功能:
String encryptedString = new String(encrypted, "utf-8"); String toEncrypt = stringIV + encryptedString;
decrypt函数中一行冗余代码可删除:
byte[] original = new byte[base64decoded.length - 16];
验证注意事项
- 确保Java与Python使用完全相同的密钥,且密钥长度符合AES要求(16/24/32字节对应128/192/256位)。
- 两端加密流程一致:IV(16字节)+ 密文 → Base64编码传输;解密时先Base64解码,分离IV与密文再解密。
内容的提问来源于stack exchange,提问作者Shakib Karami
相关产品推荐
相关产品推荐

