DES密钥解密后使用报错:javax.crypto.BadPaddingException求助
解决javax.crypto.BadPaddingException: Given final block not properly padded问题
你遇到的填充错误,根源大概率是解密时使用的DES密钥不正确,而DES密钥错误通常是因为RSA解密环节出了问题,或者数据在存储/传输中损坏了。下面是几个针对性的排查和修复方案:
1. 明确指定RSA加密/解密的填充模式
你当前创建RSA Cipher时只写了"RSA",不同加密提供商(比如BouncyCastle)的默认填充模式可能存在差异,这会导致解密后的DES密钥字节数组损坏。建议加密和解密环节都明确指定填充模式,保持一致:
加密DES密钥时修改:
Cipher cifradorRSAOficina = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");
解密DES密钥时修改:
Cipher cifradorRSA = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");
2. 修复密钥文件读取的不完整问题
你的代码中使用FileInputStream.read()一次性读取密钥文件,但这个方法不能保证一次性读取所有字节(比如文件较大或者IO流存在缓冲时),会导致读取的公钥/私钥不完整,进而加密/解密的DES密钥错误。
替换原来的文件读取代码,使用更可靠的方式:
读取公钥文件:
// 替换原来的in.read(bufferPub, ...)代码 byte[] bufferPub = Files.readAllBytes(ficheroClavePublica.toPath());
读取私钥文件:
// 替换原来的in.read(bufferPriv, ...)代码 byte[] bufferPriv = Files.readAllBytes(ficheroClavePrivada.toPath());
3. 检查加密数据和DES密钥的存储/传输完整性
如果你的paqueteCred在存储或传输加密数据(datosPeregrinoCifrados)和加密后的DES密钥时,使用了字符流或者未正确处理二进制数据(比如直接把byte[]转成String),会导致字节丢失或篡改。确保:
- 所有二进制数据(加密后的DES密钥、加密的用户数据)都以二进制格式存储/传输
- 如果必须转成字符串,使用Base64编码(比如
Base64.getEncoder().encodeToString(byte[])),解码时用Base64.getDecoder().decode(String)
4. 验证DES密钥的一致性
可以在加密端输出claveDES.getEncoded()的十六进制字符串,在解密端输出claveSecretaB的十六进制字符串,对比两者是否完全一致。如果不一致,说明RSA解密环节确实出了问题,回到前两步排查。
额外建议:
DES算法的ECB模式安全性较低,建议换成DES/CBC/PKCS5Padding模式(需要生成并存储初始化向量IV),不过这不是当前填充错误的直接原因,只是安全优化。
内容的提问来源于stack exchange,提问作者Paula
相关产品推荐
相关产品推荐

