You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何安全将RSA加解密字节转换为字符串且不丢失数据?

解决RSA解密时的BadPaddingException:安全的字节-字符串转换方案

你的问题根源出在自定义的字节与字符串互转方法上:直接将byte强制转换为char再转回byte会导致数据丢失或篡改——因为byte的取值范围是-128~127,而char是16位无符号Unicode字符,当byte为负数时,转成char后再转回byte就会变成完全不同的值。这就导致解密时传入的字节数组和加密时的原始字节数组不一致,最终触发BadPaddingException。

为什么Eclipse中看似正常?

这只是巧合:如果加密后的字节恰好都在0~127的ASCII范围内,转换不会出问题,但RSA加密后的2048位字节数组大概率包含负数字节,这些字节在非Eclipse环境下会暴露转换逻辑的缺陷(不同环境的字符编码处理差异放大了问题),本质上这个自定义转换方法是完全不安全的。

正确的解决方案:使用Base64编码

Base64是专门设计用来将二进制数据转换为安全ASCII字符串的标准方案,完全可逆且不会丢失任何数据。Java 8及以上版本自带了java.util.Base64类,直接用它替换你的自定义转换方法即可。

修改后的代码示例:

替换原有的字符串-字节转换逻辑,改用Base64处理:

import java.util.Base64;
import java.nio.charset.StandardCharsets;

// 加密字符串(用Base64编码加密后的字节)
public static String encrypt(String message, PublicKey publicKey) throws Exception {
    byte[] encryptedBytes = RSA.encrypt(message.getBytes(StandardCharsets.UTF_8), publicKey);
    return Base64.getEncoder().encodeToString(encryptedBytes);
}

// 解密字符串(先Base64解码,再解密)
public static String decrypt(String encryptedMessage, PrivateKey privateKey) throws Exception {
    byte[] encryptedBytes = Base64.getDecoder().decode(encryptedMessage);
    byte[] decryptedBytes = RSA.decrypt(encryptedBytes, privateKey);
    return new String(decryptedBytes, StandardCharsets.UTF_8);
}

同时建议在字符串转字节时指定固定字符集(比如StandardCharsets.UTF_8),避免依赖系统默认字符集导致的潜在问题。

优化你的RSA核心方法

另外,你的RSA加解密核心方法可以明确指定算法模式和填充方式,避免依赖JVM默认值(不同环境的默认填充可能有差异),进一步提升跨环境一致性:

public static byte[] encrypt(byte[] data, PublicKey key) throws Exception {
    // 指定标准的RSA/ECB/PKCS1Padding填充方式
    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    cipher.init(Cipher.ENCRYPT_MODE, key);
    return cipher.doFinal(data);
}

public static byte[] decrypt(byte[] data, PrivateKey key) throws Exception {
    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    cipher.init(Cipher.DECRYPT_MODE, key);
    return cipher.doFinal(data);
}

总结

  • 永远不要直接将任意字节数组转换为字符串(除非你100%确定所有字节都在ASCII范围内),必须使用Base64这类专门的二进制转文本编码方案。
  • 明确指定加密算法的模式和填充方式,避免依赖JVM默认值引发的兼容性问题。
  • 使用固定字符集处理字符串与字节的转换,消除系统默认字符集的影响。

内容的提问来源于stack exchange,提问作者Forseth11

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:29:48