Reputation: 15
I can decrypt a password protected PKCS8 DER key with the following code:
MemoryStream ms = new MemoryStream(privateKey);
AsymmetricKeyParameter keyparams = Org.BouncyCastle.Security.PrivateKeyFactory.DecryptKey(password.ToCharArray(), ms);
RSAParameters rsaparams = DotNetUtilities.ToRSAParameters((RsaPrivateCrtKeyParameters)keyparams);
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(rsaparams);
return rsa;
Now, I have to recreate the same type of key when it is given to me in a different format (in this example it was given to me as a PFX file). So I have to create a password protected PKCS8 DER key from the PFX private key. After reading the Bouncy Castle source code, I managed to find the PrivateKeyFactory.EncryptKey
function, but I can't get it to work. The code I have is the following:
X509Certificate2 cert = new X509Certificate2(pfx_bytes, password,X509KeyStorageFlags.Exportable);
var pkey = cert.PrivateKey;
var bcCert = DotNetUtilities.FromX509Certificate(cert);
var bcPkey = DotNetUtilities.GetKeyPair(pkey).Private;
return PrivateKeyFactory.EncryptKey(Org.BouncyCastle.Asn1.DerObjectIdentifier.Der, password.ToCharArray(), Encoding.UTF8.GetBytes(Guid.NewGuid().ToString()), 10, bcPkey);
When I run the previous code, I get the exception "System.ArgumentException
: attempt to use non-PBE algorithm with PBE EncryptedPrivateKeyInfo generation".
Google searches reveal nothing except the source code for the function, and though I've tried to follow it to find the solution I haven't been able to.
Can someone please point me in the right direction as to how I could use the function to create a password protected PKCS8 DER key from a standard .net Private key?
Upvotes: 0
Views: 4053
Reputation: 357
PBE algorithms supported by PBEUtil:
PBEwithMD2andDES-CBC, PBEwithMD2andRC2-CBC, PBEwithMD5andDES-CBC, PBEwithMD5andRC2-CBC, PBEwithSHA1andDES-CBC, PBEwithSHA1andRC2-CBC, PBEwithSHA-1and128bitRC4, PBEwithSHA-1and40bitRC4, PBEwithSHA-1and3-keyDESEDE-CBC, PBEwithSHA-1and2-keyDESEDE-CBC, PBEwithSHA-1and128bitRC2-CBC, PBEwithSHA-1and40bitRC2-CBC, PBEwithHmacSHA-1, PBEwithHmacSHA-224, PBEwithHmacSHA-256, PBEwithHmacRIPEMD128, PBEwithHmacRIPEMD160, and PBEwithHmacRIPEMD256.
Example:
private static string EncryptPrivateKey(AsymmetricKeyParameter privateKey)
{
var encKey = PrivateKeyFactory.EncryptKey("PBEwithSHA1andDES-CBC", "test".ToCharArray(),
new byte[256], 1, privateKey);
return Convert.ToBase64String(encKey);
}
Upvotes: 0
Reputation: 4042
The first argument to PrivateKeyFactory.EncryptKey is supposed to identify an algorithm to encrypt with. The simplest way is to give the ObjectIdentifier (OID) of a standard PBE algorithm e.g. PKCSObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc instead of DerObjectIdentifier.Der . You could take a look at PbeUtilities class if you want to see what other algorithms are available.
Upvotes: 1