使用RSA.ImportRSAPrivateKey报错:Universal类值应为2实际为16
解决C#导入RSA私钥时的"Universal class value '16'"异常
我有一个无密码的RSA私钥文件和证书文件,用curl命令curl -E file.crt --key file.key ....能正常调用接口,但用C#代码导入私钥时抛出异常:
The provided data is tagged with 'Universal' class value '16', but it should have been 'Universal' class value '2'.
我的C#解码代码如下:
var key = File.ReadAllText(path) .Replace("-----BEGIN RSA PRIVATE KEY-----", string.Empty) .Replace("-----END RSA PRIVATE KEY-----", string.Empty) .Replace("\n", string.Empty); using var rsa = RSA.Create(); rsa.ImportRSAPrivateKey(Convert.FromBase64String(key), out _);
问题原因
你当前的私钥是PKCS#1格式(标识为-----BEGIN RSA PRIVATE KEY-----),而.NET的RSA.ImportRSAPrivateKey方法仅支持PKCS#8格式的私钥(标识为-----BEGIN PRIVATE KEY-----),格式不匹配导致抛出ASN.1解析异常。
两种解决方法
方法1:用OpenSSL转换私钥格式
通过OpenSSL将PKCS#1格式的私钥转为PKCS#8格式,命令如下:
openssl pkcs8 -topk8 -inform PEM -in file.key -outform PEM -nocrypt -out file_pkcs8.key
转换完成后,直接用你的原C#代码读取新生成的file_pkcs8.key即可,无需修改代码逻辑。
方法2:在C#中直接解析PKCS#1格式私钥
如果不想转换文件格式,可以使用第三方库BouncyCastle直接解析PKCS#1私钥:
- 先安装NuGet包:
Org.BouncyCastle - 使用以下代码导入私钥:
using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.OpenSsl; using Org.BouncyCastle.Security; using System.IO; using System.Security.Cryptography; var keyText = File.ReadAllText(path); using var reader = new StringReader(keyText); var pemReader = new PemReader(reader); var rsaParams = (RsaPrivateCrtKeyParameters)pemReader.ReadObject(); using var rsa = DotNetUtilities.ToRSA(rsaParams);
补充说明
curl工具原生支持PKCS#1格式的私钥,所以你用curl调用时不会出现格式问题,但.NET的核心加密API对私钥格式有明确要求,需要注意区分两种格式的差异。
内容的提问来源于stack exchange,提问作者Gargoyle
相关产品推荐
相关产品推荐

