.NET Core C#用RSACryptoServiceProvider解密Java RSA加密字符串报错
问题
我正在开发一个C# .NET Core应用,需要解密由Java使用RSA/ECB/OAEPWithSHA-256AndMGF1Padding加密的字符串。尝试用RSACryptoServiceProvider解密时,一直抛出错误:Internal.Cryptography.CryptoThrowHelper.WindowsCryptographicException: 'Incorrect parameter'。已通过在线工具将PEM格式私钥转为XML格式,相关代码及密钥信息如下:
原代码
// encrypted string result is hello const string encryptedString = "HhB77zNHCiB/CWa8v5VcaUNdi/M/mE9us8mQ4be1o2f3G/rQpsAcD8aue4QRJsOliekHIqaI9vrkyyLIDTJQDbkb15rweHZwwUr0YFqHFAq/PMt9tBph2U7n9zZN0zVDiFP/J4J8FZBGsLFx432YQP7DEi62fbHYY8fm1lXLx/Q="; const string privateKey = "<RSAKeyValue><Modulus>utm7gcfK7JCTi1gRIcz2/BjtOpAAjqvd0uMKd2AAzxgFCEKCraPNKFjKv5OaEGq6bnbgt2BGx/5m5CrgjR26FMeA924QBoYZodGoSBV4klcoVihXtznWv96FYmuMya+BX5Q5fqM6TJ3iJbXI3+/o5eyblXj/mjjZ+yKGQjUn6Wc=</Modulus><Exponent>AQAB</Exponent><P>9+F18Oi6wKgCp4vSySDjKQmzIajs+QPsiOscmZxk/QV9T1Tg+QSi3s3sLxQFGnCU8Q0OE9d4idv6TLtS/ibl1w==</P><Q>wPiE2XzmTsEkOGO6KFfNHqkeh6uwd/WxHcRQgUfhFefl30YtIh1fj+Zq+b/rmzpkPPIVdl6zUbrWeldsfj2G8Q==</Q><DP>LyV52j1Zr+UExDtK9yhDLH4EzSUlFWPSrGQTh4AAkUNnBxy8wYBJPhlqj7W+Fr5NBeAWyl1UNtxZKhkC+wYI9w==</DP><DQ>ipw4uQxpVhqQDN09o6rl0OdD4commRRnY+1WsnZSLO0FBmsfEkktEm09XCZKc5bu14RAfGUrw0JEu14+tTM20Q==</DQ><InverseQ>7KvNQ83Bl1OFVOs4NZt2rFvPFQjSfSEdStyglsABSyBQUpC5IoJsj1SXrXQPPOFDgdDBXXsfJJRHEAl125CTmA==</InverseQ><D>UQkzODL1QCnnw4w7SeSBzY3l/PsNMtM5DkgnduRtFWP+crmdwT8EMBZqQDH8pFgVaOknxn/70qrz5srtvmYBGFjHdVRqBz01huykyIzxYhKATiljp+Akf72ljpIfs4zJ5bIQyA9OMYZKoIUjiUlCKBX29baxJ6tNAObOrwgAyGE=</D></RSAKeyValue>"; using (var rsa = new RSACryptoServiceProvider(1024)) { try { var base64Encrypted = encryptedString; // server decrypting data with private key rsa.FromXmlString(privateKey); var resultBytes = Convert.FromBase64String(base64Encrypted); var decryptedBytes = rsa.Decrypt(resultBytes, false); var decryptedData = Encoding.UTF8.GetString(decryptedBytes); Console.WriteLine(decryptedData.ToString()); } finally { rsa.PersistKeyInCsp = false; } }
转换前的PEM私钥
-----BEGIN RSA PRIVATE KEY----- MIICXQIBAAKBgQC62buBx8rskJOLWBEhzPb8GO06kACOq93S4wp3YADPGAUIQoKt o80oWMq/k5oQarpuduC3YEbH/mbkKuCNHboUx4D3bhAGhhmh0ahIFXiSVyhWKFe3 Oda/3oVia4zJr4FflDl+ozpMneIltcjf7+jl7JuVeP+aONn7IoZCNSfpZwIDAQAB AoGAUQkzODL1QCnnw4w7SeSBzY3l/PsNMtM5DkgnduRtFWP+crmdwT8EMBZqQDH8 pFgVaOknxn/70qrz5srtvmYBGFjHdVRqBz01huykyIzxYhKATiljp+Akf72ljpIf s4zJ5bIQyA9OMYZKoIUjiUlCKBX29baxJ6tNAObOrwgAyGECQQD34XXw6LrAqAKn i9LJIOMpCbMhqOz5A+yI6xyZnGT9BX1PVOD5BKLezewvFAUacJTxDQ4T13iJ2/pM u1L+JuXXAkEAwPiE2XzmTsEkOGO6KFfNHqkeh6uwd/WxHcRQgUfhFefl30YtIh1f j+Zq+b/rmzpkPPIVdl6zUbrWeldsfj2G8QJALyV52j1Zr+UExDtK9yhDLH4EzSUl FWPSrGQTh4AAkUNnBxy8wYBJPhlqj7W+Fr5NBeAWyl1UNtxZKhkC+wYI9wJBAIqc OLkMaVYakAzdPaOq5dDnQ+HKJpkUZ2PtVrJ2UiztBQZrHxJJLRJtPVwmSnOW7teE QHxlK8NCRLtePrUzNtECQQDsq81DzcGXU4VU6zg1m3asW88VCNJ9IR1K3KCWwAFL IFBSkLkigmyPVJetdA884UOB0MFdex8klEcQCXXbkJOY -----END RSA PRIVATE KEY-----
问题分析与解决方法
问题主要出在以下两点:
- 填充模式不匹配:Java使用的是
OAEPWithSHA-256AndMGF1Padding,而原代码中rsa.Decrypt(resultBytes, false)的第二个参数false对应PKCS#1 v1.5填充,两者完全不兼容,这是抛出错误的核心原因。 - API选择过时:
RSACryptoServiceProvider是.NET Framework时代的旧API,在.NET Core/.NET 5+中已被标记为过时,推荐使用更通用的RSA抽象类。
修正后的代码
// encrypted string result is hello const string encryptedString = "HhB77zNHCiB/CWa8v5VcaUNdi/M/mE9us8mQ4be1o2f3G/rQpsAcD8aue4QRJsOliekHIqaI9vrkyyLIDTJQDbkb15rweHZwwUr0YFqHFAq/PMt9tBph2U7n9zZN0zVDiFP/J4J8FZBGsLFx432YQP7DEi62fbHYY8fm1lXLx/Q="; const string privateKey = "<RSAKeyValue><Modulus>utm7gcfK7JCTi1gRIcz2/BjtOpAAjqvd0uMKd2AAzxgFCEKCraPNKFjKv5OaEGq6bnbgt2BGx/5m5CrgjR26FMeA924QBoYZodGoSBV4klcoVihXtznWv96FYmuMya+BX5Q5fqM6TJ3iJbXI3+/o5eyblXj/mjjZ+yKGQjUn6Wc=</Modulus><Exponent>AQAB</Exponent><P>9+F18Oi6wKgCp4vSySDjKQmzIajs+QPsiOscmZxk/QV9T1Tg+QSi3s3sLxQFGnCU8Q0OE9d4idv6TLtS/ibl1w==</P><Q>wPiE2XzmTsEkOGO6KFfNHqkeh6uwd/WxHcRQgUfhFefl30YtIh1fj+Zq+b/rmzpkPPIVdl6zUbrWeldsfj2G8Q==</Q><DP>LyV52j1Zr+UExDtK9yhDLH4EzSUlFWPSrGQTh4AAkUNnBxy8wYBJPhlqj7W+Fr5NBeAWyl1UNtxZKhkC+wYI9w==</DP><DQ>ipw4uQxpVhqQDN09o6rl0OdD4commRRnY+1WsnZSLO0FBmsfEkktEm09XCZKc5bu14RAfGUrw0JEu14+tTM20Q==</DQ><InverseQ>7KvNQ83Bl1OFVOs4NZt2rFvPFQjSfSEdStyglsABSyBQUpC5IoJsj1SXrXQPPOFDgdDBXXsfJJRHEAl125CTmA==</InverseQ><D>UQkzODL1QCnnw4w7SeSBzY3l/PsNMtM5DkgnduRtFWP+crmdwT8EMBZqQDH8pFgVaOknxn/70qrz5srtvmYBGFjHdVRqBz01huykyIzxYhKATiljp+Akf72ljpIfs4zJ5bIQyA9OMYZKoIUjiUlCKBX29baxJ6tNAObOrwgAyGE=</D></RSAKeyValue>"; using (var rsa = RSA.Create()) { try { rsa.FromXmlString(privateKey); var encryptedBytes = Convert.FromBase64String(encryptedString); // 指定OAEP填充,哈希算法为SHA256,匹配Java的加密配置 var decryptedBytes = rsa.Decrypt(encryptedBytes, RSAEncryptionPadding.OaepSHA256); var decryptedData = Encoding.UTF8.GetString(decryptedBytes); Console.WriteLine(decryptedData); } finally { rsa.Clear(); } }
额外说明
- 无需将PEM私钥转为XML,可直接用
rsa.ImportFromPem(privateKeyPem)方法导入,避免在线转换可能带来的错误。 - RSA跨语言加密解密的核心要求是:密钥对完全匹配,填充、哈希算法的配置严格一致。
内容的提问来源于stack exchange,提问作者JoelFerreira
相关产品推荐
相关产品推荐

