C#中使用Bouncy Castle解密加密私钥报错:Wrong number of elements in sequence的解决方法
解决Bouncy Castle加载加密PKCS#8私钥的错误
你遇到的问题是因为直接将带PEM头的私钥字节传给PrivateKeyFactory.DecryptKey导致的——这个方法需要的是DER编码的加密私钥核心内容,而不是包含-----BEGIN ENCRYPTED PRIVATE KEY-----头尾的完整PEM文件字节。另外,你的私钥是标准PKCS#8加密格式,需要用Bouncy Castle中专门处理PKCS#8加密私钥的类来解析。
正确的加载和解密步骤
以下是完整的C#代码示例,用Bouncy Castle正确加载并解密你的加密私钥:
using System.IO; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.OpenSsl; using Org.BouncyCastle.Pkcs; using Org.BouncyCastle.Security; // 读取PEM格式的加密私钥文件内容 string privateKeyPem = File.ReadAllText(@"Org-CA.key"); char[] password = "pass1234".ToCharArray(); // 使用PemReader解析PEM格式 using (var reader = new StringReader(privateKeyPem)) { var pemReader = new PemReader(reader, new PasswordFinder(password)); // 读取加密的PKCS#8私钥信息 var encryptedKeyInfo = (Pkcs8EncryptedPrivateKeyInfo)pemReader.ReadObject(); // 解密得到私钥信息 var privateKeyInfo = encryptedKeyInfo.DecryptPrivateKeyInfo(password); // 转换为AsymmetricKeyParameter(这里是RSA私钥,对应你的OpenSSL生成的RSA密钥) AsymmetricKeyParameters privateKeyParams = PrivateKeyFactory.CreateKey(privateKeyInfo); // 现在你可以用这个privateKeyParams来签署客户端CSR了 } // 辅助类:提供密码给PemReader public class PasswordFinder : IPasswordFinder { private readonly char[] _password; public PasswordFinder(char[] password) => _password = password; public char[] GetPassword() => _password; }
错误原因详解
你之前的代码问题在于:
- 直接读取整个PEM文件的字节数组(包含PEM头尾的字符串),而
PrivateKeyFactory.DecryptKey需要的是去掉PEM头尾后的DER编码字节。 - PKCS#8加密私钥有特定的ASN.1结构,需要通过
Pkcs8EncryptedPrivateKeyInfo来解析,而不是直接调用DecryptKey方法——这个方法更适用于PKCS#1格式的加密私钥(比如-----BEGIN RSA PRIVATE KEY-----带加密的格式),而非你当前使用的PKCS#8加密格式。
补充说明
在获取到privateKeyParams后,你可以继续用Bouncy Castle的API来处理客户端CSR的签署,比如解析CSR为Pkcs10CertificationRequest,然后创建X509V3CertificateGenerator来生成签署后的证书。
内容的提问来源于stack exchange,提问作者Zeus82




