.NET 6中RSA解密报错:参数不正确问题求助
RSA解密:Go可行但.NET 6+报错的解决方案
问题概述
在处理RSA加密消息解密时,已有可正常运行的Go语言实现,但在.NET 6/7中尝试相同逻辑时遇到两类报错:
- 调用
RSA.Decrypt(Data, false)(对应PKCS#1 v1.5填充)时,抛出Internal.Cryptography.CryptoThrowHelper.WindowsCryptographicException: '参数不正确' - 调用
RSA.Decrypt(Data, true)(对应OAEP填充)时,抛出System.Security.Cryptography.CryptographicException: 'Cryptography_OAEPDecoding'
代码对比
可行的Go语言代码
package main import ( "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/base64" "encoding/pem" "fmt" ) func main() { // 示例PKCS#1格式私钥 privateKeyPEM := `-----BEGIN RSA PRIVATE KEY----- MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5 1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh 3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2 pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ 37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0= -----END RSA PRIVATE KEY-----` // 加密后的Base64数据 encryptedDataBase64 := "encrypted_data_here" encryptedData, _ := base64.StdEncoding.DecodeString(encryptedDataBase64) // 解析PKCS#1私钥并解密(默认使用PKCS#1 v1.5填充) block, _ := pem.Decode([]byte(privateKeyPEM)) privateKey, _ := x509.ParsePKCS1PrivateKey(block.Bytes) decryptedData, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, encryptedData) if err != nil { panic(err) } fmt.Println(string(decryptedData)) }
.NET尝试代码(报错版本)
using System; using System.Security.Cryptography; using System.Text; namespace RSADecryptTest { class Program { static void Main(string[] args) { string privateKey = @"-----BEGIN RSA PRIVATE KEY----- MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5 1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh 3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2 pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ 37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0= -----END RSA PRIVATE KEY-----"; string encryptedBase64 = "encrypted_data_here"; byte[] encryptedData = Convert.FromBase64String(encryptedBase64); using (RSA rsa = RSA.Create()) { rsa.ImportFromPem(privateKey); // 尝试PKCS#1 v1.5填充 try { byte[] decryptedData = rsa.Decrypt(encryptedData, RSAEncryptionPadding.Pkcs1); Console.WriteLine(Encoding.UTF8.GetString(decryptedData)); } catch (Exception ex) { Console.WriteLine($"Pkcs1填充报错:{ex.Message}"); } // 尝试OAEP填充 try { byte[] decryptedData = rsa.Decrypt(encryptedData, RSAEncryptionPadding.OaepSHA1); Console.WriteLine(Encoding.UTF8.GetString(decryptedData)); } catch (Exception ex) { Console.WriteLine($"OAEP填充报错:{ex.Message}"); } } } } }
问题分析
- 填充方式不匹配:Go代码使用
rsa.DecryptPKCS1v15(PKCS#1 v1.5填充),.NET中对应RSAEncryptionPadding.Pkcs1,但报错大概率是加密数据的编码问题(比如用了URL-safe Base64而非标准Base64)。 - 密钥解析细节:Go的
x509.ParsePKCS1PrivateKey仅解析PKCS#1格式私钥,.NET的ImportFromPem虽支持该格式,但需确保私钥无格式错误(如换行、首尾标识完整)。 - 加密数据完整性:若加密数据在传输中被截断或编码错误,会导致解密时参数校验失败。
修正后的.NET代码
以下代码完全对齐Go的解密逻辑:
using System; using System.Security.Cryptography; using System.Text; namespace RSADecryptTest { class Program { static void Main(string[] args) { string privateKey = @"-----BEGIN RSA PRIVATE KEY----- MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5 1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh 3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2 pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ 37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0= -----END RSA PRIVATE KEY-----"; // 处理URL-safe Base64转换为标准Base64 string encryptedBase64 = "encrypted_data_here"; encryptedBase64 = encryptedBase64.Replace('-', '+').Replace('_', '/'); if (encryptedBase64.Length % 4 != 0) { encryptedBase64 += new string('=', 4 - encryptedBase64.Length % 4); } byte[] encryptedData = Convert.FromBase64String(encryptedBase64); using (RSA rsa = RSA.Create()) { rsa.ImportFromPem(privateKey.ToCharArray()); try { // 使用PKCS#1 v1.5填充,与Go逻辑完全匹配 byte[] decryptedData = rsa.Decrypt(encryptedData, RSAEncryptionPadding.Pkcs1); Console.WriteLine("解密成功:" + Encoding.UTF8.GetString(decryptedData)); } catch (CryptographicException ex) { Console.WriteLine("解密失败:" + ex.Message); Console.WriteLine("错误详情:" + ex.InnerException?.Message); } } } } }
额外排查步骤
- 确认加密数据为标准Base64编码,若为URL-safe格式需先转换。
- 对比Go和.NET中解析出的RSA参数(如
Modulus、Exponent),确保两者一致。 - 验证加密数据长度与密钥长度匹配(如2048位密钥对应256字节加密数据),避免数据截断。
内容的提问来源于stack exchange,提问作者Muhammad Hannan
相关产品推荐
相关产品推荐

