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

解密JSEncrypt加密数据时遇BadPaddingException问题求助

问题分析与错误修正

核心错误:RSA密钥逻辑完全颠倒

RSA的标准逻辑是公钥加密、私钥解密,你的代码完全搞反了:

  • 客户端:加载私钥后调用encrypt(),用私钥加密明文,这违背了RSA的安全设计(私钥应仅在服务端保存,客户端只能持有公钥)
  • 服务端:传入PublicKey执行解密操作,公钥无法解密用公钥加密的内容,这在RSA机制里是不可能实现的

客户端代码的其他问题

  1. response.text()异步处理错误
    response.text()返回的是Promise对象,直接赋值给p.textContent会显示[object Promise],正确写法需等待Promise兑现:
    .then(response => response.text())
    .then(text => {
        var main = document.querySelector("main");
        var p = document.createElement("h1");
        p.textContent = text;
        main.appendChild(p);
    })
    
  2. 密钥使用逻辑错误
    客户端应加载公钥而非私钥,调用encryptor.setPublicKey(publicKey)后再加密明文,私钥绝对不能暴露给客户端。

服务端代码的问题

  1. 缺失Base64解码步骤
    JSEncrypt的encrypt()返回的是Base64编码的字符串,服务端拿到的token参数是Base64格式,必须先解码为字节数组才能解密,直接使用原始参数转字节数组会导致解密失败。
  2. 不必要且错误的分块解密
    对于JSEncrypt默认的RSA_PKCS1_PADDING填充方式,cipher.doFinal()可以直接处理完整密文,手动分块的逻辑完全多余,且分块规则不符合RSA解密的要求。
  3. 密钥类型错误
    服务端解密必须使用PrivateKey,需将方法参数改为PrivateKey privateKey,并在初始化Cipher时传入私钥。

修正后的核心代码示例

客户端修正(使用公钥加密)

reader.onloadend = function (e) {
    var publicKey = e.target.result; // 加载公钥文件

    var encryptor = new JSEncrypt();
    encryptor.setPublicKey(publicKey);
    var encryptedText = encryptor.encrypt(plainText);

    const params = new URLSearchParams();
    params.append('token', encryptedText);

    fetch(form.action, {
        method: form.method,
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        body: params
    })
    .then(response => response.text())
    .then(text => {
        var main = document.querySelector("main");
        var p = document.createElement("h1");
        p.textContent = text;
        main.appendChild(p);
    })
    .catch(error => {
        var main = document.querySelector("main");
        var p = document.createElement("h1");
        p.textContent = error.message;
        main.appendChild(p);
    });            
};

服务端修正(使用私钥解密,处理Base64)

import java.util.Base64;
import java.security.PrivateKey;
import javax.crypto.Cipher;

public class RSADecryptor {
    public static String decrypt(String base64CipherText, PrivateKey privateKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        
        // 解码Base64格式的密文
        byte[] cipherText = Base64.getDecoder().decode(base64CipherText);
        // 直接解密完整密文
        byte[] decryptedBytes = cipher.doFinal(cipherText);
        
        return new String(decryptedBytes);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 14:52:47