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

Java RSA+Base64解密抛出BadPaddingException: Decryption error问题

问题定位

你的代码触发javax.crypto.BadPaddingException: Decryption error有3个核心错误,按影响优先级排序:

  1. 密钥对不匹配:你在类的构造方法中每次实例化都会生成全新的RSA密钥对。如果加密操作和解密操作使用的不是同一个EncryptionUtil实例,加密用的公钥和解密用的私钥完全不属于同一对密钥,RSA算法无法正常解密,必然抛出padding错误。这是此类报错最常见的触发原因。
  2. Cipher实例线程不安全:你把Cipher定义为类成员变量全局共享,而Cipher本身是有状态的对象。多线程并发调用加解密方法时,会出现Cipher的工作模式(加密/解密)、密钥被其他线程覆盖的问题,导致传入的解密数据和当前Cipher的状态不匹配,触发异常。
  3. 编解码未指定字符集:代码中所有字符串和字节数组的转换都没有指定字符集,程序运行在不同操作系统、不同语言环境下时,会因为默认字符集差异导致Base64编解码、明文转码出错,间接触发解密异常。
修复方案

按照以下规则调整代码即可解决问题:

  • 不要在工具类构造时动态生成密钥对:RSA密钥对应提前生成后持久化存储(比如配置文件、密钥库),加解密时统一加载匹配的公钥、私钥;如果是临时内存使用场景,必须保证加解密操作调用的是同一个持有固定密钥对的实例。
  • 不要全局共享Cipher实例:每次执行加解密操作时单独初始化Cipher对象,方法执行完后自动回收,避免多线程状态冲突。
  • 所有字节、字符串转换操作统一指定UTF-8字符集,消除环境差异带来的编解码错误。

修复后的核心参考代码:

import org.apache.commons.codec.binary.Base64;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.nio.charset.StandardCharsets;
import java.security.*;

public class EncryptionUtil {

    static final String SECRET_ALGO = "RSA";
    static final String CIPHER_TOKENIZER_TRANSFORMER = "RSA/ECB/PKCS1Padding";
    static final int KEY_SIZE = 1024;

    private final KeyPair pair;

    // 构造方法仅在需要临时生成密钥对时使用,生产环境建议替换为从配置加载已生成的密钥对
    public EncryptionUtil(){
        try{
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(SECRET_ALGO);
            keyPairGen.initialize(KEY_SIZE);
            pair = keyPairGen.generateKeyPair();
        }catch (NoSuchAlgorithmException e) {
            throw new IllegalStateException("Cannot Build Encryption Utils with given params");
        }
    }

    public String decrypt(String encrypted) {
        try {
            // 每次调用单独初始化Cipher,不共享实例
            Cipher cipher = Cipher.getInstance(CIPHER_TOKENIZER_TRANSFORMER);
            cipher.init(Cipher.DECRYPT_MODE, pair.getPrivate());
            byte[] decodeBytes = new Base64().decode(encrypted.getBytes(StandardCharsets.UTF_8));
            return new String(cipher.doFinal(decodeBytes), StandardCharsets.UTF_8);
        } catch (NoSuchPaddingException | NoSuchAlgorithmException | BadPaddingException | IllegalBlockSizeException | InvalidKeyException e) {
            throw new FiveXXServiceException(e.getMessage(), ErrorCode.DECRYPTION_EXCEPTION);
        }
    }

    public String encrypt(String text) {
        try {
            // 每次调用单独初始化Cipher,不共享实例
            Cipher cipher = Cipher.getInstance(CIPHER_TOKENIZER_TRANSFORMER);
            cipher.init(Cipher.ENCRYPT_MODE, pair.getPublic());
            byte[] encryptBytes = cipher.doFinal(text.getBytes(StandardCharsets.UTF_8));
            return new String(new Base64().encode(encryptBytes), StandardCharsets.UTF_8);
        } catch (NoSuchPaddingException | NoSuchAlgorithmException | BadPaddingException | IllegalBlockSizeException | InvalidKeyException e) {
            throw new FiveXXServiceException(e.getMessage(), ErrorCode.ENCRYPTION_EXCEPTION);
        }
    }

}

注意:1024位RSA密钥安全强度已经不足,生产环境建议替换为2048位及以上长度;RSA/ECB/PKCS1Padding模式仅适合加密短数据,1024位密钥最大可加密数据长度为117字节,超过长度需要结合对称加密算法使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 01:48:46