如何使用RSA私钥解密RSA加密的AES密钥,Java代码输出乱码如何解决
RSA解密乱码问题排查点
Cipher实例化未指定完整的算法/模式/填充参数
你代码里写的是Cipher.getInstance("RSA"),这种写法依赖JDK默认的填充和工作模式,不同JDK版本/安全提供商的默认值可能不同,常见默认值为RSA/ECB/PKCS1Padding,如果加密端使用的填充规则和你解密端的默认值不匹配(比如加密用了OAEP填充RSA/ECB/OAEPWithSHA-256AndMGF1Padding),就会导致解密后的数据异常。
你需要和加密端确认使用的完整RSA算法参数,解密时显式指定,示例:
// 若加密用的是PKCS1填充 final Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); // 若加密用的是OAEP填充,按实际使用的哈希算法调整参数 final Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
解密结果是二进制AES密钥,直接转字符串必然乱码
你加密的内容本身是AES密钥,AES密钥是随机生成的二进制字节(16字节对应AES128、24字节对应AES192、32字节对应AES256),不属于UTF-8/GBK等编码的可打印文本,你直接用new String(decrypted)把二进制字节转成字符串,自然会出现乱码,这属于正常现象。
你不需要把它转成字符串,直接用解密得到的decrypted字节数组作为AES密钥去解密后续业务数据即可。如果需要打印验证密钥是否正确,可以转成十六进制或者Base64格式查看:
// 转Base64打印 String aesKeyBase64 = Base64.getEncoder().encodeToString(decrypted); System.out.println("解密得到的AES密钥(Base64):" + aesKeyBase64); // 转十六进制打印 StringBuilder hex = new StringBuilder(); for (byte b : decrypted) { hex.append(String.format("%02x", b)); } System.out.println("解密得到的AES密钥(十六进制):" + hex);
其他排查点
- 确认你使用的私钥和加密时使用的公钥是配对的密钥对
- 确认密文没有被截断、修改,当前使用的密文是完整的Base64编码内容
- 确认加密端是用公钥对AES密钥进行加密的,符合RSA公钥加密、私钥解密的常规流程
内容的提问来源于stack exchange,提问作者Prolahcen
相关产品推荐
相关产品推荐

