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

Java中RSA解密出现BadPaddingException问题求助

问题分析与解决:C# RSA加密AES密钥后Java解密抛出BadPaddingException

核心错误:AES密钥的字节转换逻辑错误

你在C#中生成AES密钥时,已经将二进制密钥转换为Base64字符串返回,但加密时却把这个Base64字符串当成普通文本用Encoding.UTF8.GetBytes()转成字节数组——这相当于加密的是Base64文本内容,而非原始的AES二进制密钥。这种错误的转换会导致加密后的内容不符合PKCS1Padding规范,直接触发Java端的BadPaddingException。

修正后的C#加密代码(原生RSACryptoServiceProvider版本)

public string Encrypt(string plainAesKey)
{
    string publicKeyFileName = publicKeyPath;
    string cipherText = string.Empty;

    using (var rsa = new RSACryptoServiceProvider())
    {
        var param = getCertificate(publicKeyFileName);
        rsa.ImportParameters(param);
        // 关键修正:将Base64字符串解码为原始AES二进制密钥,而非转UTF8字节
        var plainTextBytes = Convert.FromBase64String(plainAesKey);
        byte[] cipherTextBytes = rsa.Encrypt(plainTextBytes, RSAEncryptionPadding.Pkcs1);
        cipherText = Convert.ToBase64String(cipherTextBytes);
    }
    return cipherText;
}

修正后的C#加密代码(BouncyCastle版本)

static string contentRootPath = "Content";
string publicKeyPath = Path.Combine(contentRootPath, "RSAKeys", "publicKey.cer");

public string EncryptDataWithBouncyCastle(string aesKey)
{
    string publicFilePath = publicKeyPath;
    try
    {
        using (FileStream fs = File.OpenRead(publicFilePath))
        {
            X509CertificateParser parser = new X509CertificateParser();
            X509Certificate certificate = parser.ReadCertificate(fs);

            RsaKeyParameters publicKey = (RsaKeyParameters)certificate.GetPublicKey();

            var rsaCipher = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");
            rsaCipher.Init(true, publicKey);

            // 关键修正:解码Base64得到原始AES密钥字节
            byte[] aesKeyBytes = Convert.FromBase64String(aesKey);
            byte[] EncData = rsaCipher.DoFinal(aesKeyBytes);

            return Convert.ToBase64String(EncData);
        }
    }
    catch (Exception e)
    {
        return e.Message.ToString();
    }
}

其他可能导致BadPaddingException的原因及排查步骤

  1. 密钥对不匹配
    确认C#加密使用的公钥与Java解密使用的私钥属于同一RSA密钥对。可以用公钥加密一段简单文本(如"test"),再用私钥解密,验证是否能正常得到明文。

  2. 公钥提取错误
    检查getCertificate方法是否正确从.cer文件中提取公钥。标准的X.509证书公钥提取代码示例:

    private RSAParameters getCertificate(string publicKeyFileName)
    {
        X509Certificate2 cert = new X509Certificate2(publicKeyFileName);
        using (RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PublicKey.Key)
        {
            return rsa.ExportParameters(false);
        }
    }
    
  3. Java端Cipher配置问题
    确保Java端的Cipher算法与C#完全一致。部分JCE提供者可能需要明确指定提供者,可尝试修改为:

    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "SunJCE");
    
  4. Base64编码/解码不一致
    确认C#生成的Base64字符串没有额外的换行或空格,Java端使用Base64.decodeBase64()能正确解码。如果C#生成的Base64带有换行,需先去除后再传递给Java。

验证步骤

  1. 用修正后的C#代码加密AES密钥,得到加密后的Base64字符串。
  2. 在Java端解密该字符串,确认得到32字节的原始AES密钥(AES256密钥长度固定为32字节)。
  3. 用该AES密钥加密一段测试文本,再用Java解密,验证整个流程是否正常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 22:06:00