0

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?

vinothp
  • 9,939
  • 19
  • 61
  • 103
user1543495
  • 15
  • 2
  • 6
  • http://www.codeproject.com/Articles/25487/Cryptographic-Interoperability-Keys PrivateKeyToPKCS8 method perhaps – m0s Jul 22 '12 at 07:59

2 Answers2

1

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.

Peter Dettman
  • 3,867
  • 20
  • 34
0

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);

    }
daveBM
  • 344
  • 1
  • 10