简体   繁体   中英

C# - How to Decrypt an Encrypted Private Key with Bouncy Castle

I have a private key that was generated by running:

openssl req -new -sha384 -x509 -days 63524 -subj "/C=CA/ST=State/L=City/O=Org/CN=Org-CA" -extensions v3_ca -keyout Org-CA.key -out Org-CA.pem -passout pass:pass1234

I need to use this private key and certificate to sign client CSRs. I used to use OpenSSL to do this, but I need to do this in C# instead.

I've found examples of what I want to do online, but those examples are using bouncy castle and an un-encrypted private key.

The key file looks like this:

-----BEGIN ENCRYPTED PRIVATE KEY-----
....
-----END ENCRYPTED PRIVATE KEY-----

And I'm trying to load it by doing this:

var privatekey = File.ReadAllBytes(@"Org-CA.key");
var rsaKeyParameters = PrivateKeyFactory.DecryptKey("pass1234".ToArray(), privatekey);

But thats not working. I get an error saying Wrong number of elements in sequence (Parameter 'seq')'

Is this how I'm supposed to be decrypting and loading the private key?

Depending on your .NET version, you may not need BouncyCastle at all. As of .NET Core 3.1 there is RSA.ImportEncryptedPkcs8PrivateKey() for DER encoded encrypted private PKCS#8 keys and as of .NET 5.0 there is even RSA.ImportFromEncryptedPem() for PEM encoded encrypted keys.


Otherwise with C#/BouncyCastle the import of an encrypted private PKCS#8 key is available eg with:

using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.OpenSsl;
...
string encPkcs8 = @"-----BEGIN ENCRYPTED PRIVATE KEY-----
                    ...
                    -----END ENCRYPTED PRIVATE KEY-----"; 
StringReader stringReader = new StringReader(encPkcs8);
PemReader pemReader = new PemReader(stringReader, new PasswordFinder("<your password>"));
RsaPrivateCrtKeyParameters keyParams = (RsaPrivateCrtKeyParameters)pemReader.ReadObject();
...

with the following implementation of the IPasswordFinder interface:

private class PasswordFinder : IPasswordFinder
{
    private string password;
    public PasswordFinder(string pwd) => password = pwd;
    public char[] GetPassword() => password.ToCharArray();
}

If necessary, a conversion from keyParams to System.Security.Cryptography.RSAParameters is possible with:

using Org.BouncyCastle.Security;
...
RSAParameters rsaParameters = DotNetUtilities.ToRSAParameters(keyParams);

which can be imported directly eg with RSA.ImportParameters() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM