Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using CngKey to Generate RSA key pair in PEM (DKIM compatible) using C#.... similar to "openssl rsa"

Is it possible to generate an RSA key pair, export that into ASN1 format compatible with DKIM's PEM-like format, using only C#?

I'd like to reduce my dependencies on 3rd parties, but here are some that I have found

Bouncy Castle

  • https://stackoverflow.com/a/251757

Cryptography Application Block

  • http://msdn.microsoft.com/en-us/library/dd203099.aspx
  • https://stackoverflow.com/a/243787

Win32 PFXImportCertStore

  • http://msdn.microsoft.com/en-us/library/aa387314(v=vs.85).aspx
  • http://msdn.microsoft.com/en-us/library/aa387313(v=vs.85)

Import PEM

  • This code only imports PEM data, but is different from OpenSSL in that it fixes an issue with .NET 4.0 and leading zeros in the key http://www.codeproject.com/Articles/162194/Certificates-to-DB-and-Back

Microsoft's CLR Security enhancements

  • http://clrsecurity.codeplex.com/

Microsoft CNG

  • http://msdn.microsoft.com/en-us/magazine/cc163389.aspx

Here is code for the Microsoft CNG provider with the .NET dll on codeplex (above)... however I don't know how to export and import both the public and private keys in DKIM compatible ASN1 format.

     byte[] pkcs8PrivateKey = null;
        byte[] signedData = null;

        CngKey key = CngKey.Create(CngAlgorithm2.Rsa);
       byte[] exportedPrivateBytes = key.Export(CngKeyBlobFormat.GenericPrivateBlob);

       string exportedPrivateString= Encoding.UTF8.GetString(exportedPrivateBytes);

        pkcs8PrivateKey = Encoding.UTF8.GetBytes(exportedPrivateString);

        using (CngKey signingKey = CngKey.Import(pkcs8PrivateKey, CngKeyBlobFormat.Pkcs8PrivateBlob))
        {
            using (RSACng rsa = new RSACng(signingKey))
            {
                rsa.SignatureHashAlgorithm = CngAlgorithm.Sha1;
                signedData = rsa.SignData(dataToSign);
            }
        }

Question

Are there any direct examples of using Microsoft's libraries (Win32, PFX, or CLR on Codeplex) that illustrate how to create a key pair and export / import those values in PEM format?

like image 874
makerofthings7 Avatar asked Jun 29 '12 17:06

makerofthings7


1 Answers

So you just need a pkcs8 of the key then.

CngKeyCreationParameters ckcParams = new CngKeyCreationParameters()
{
    ExportPolicy = CngExportPolicies.AllowPlaintextExport,
    KeyCreationOptions = CngKeyCreationOptions.None,
    KeyUsage = CngKeyUsages.AllUsages,                
};
ckcParams.Parameters.Add(new CngProperty("Length", BitConverter.GetBytes(2048), CngPropertyOptions.None));

myCngKey = CngKey.Create(CngAlgorithm.Rsa, null, ckcParams);

byte[] privatePlainTextBlob = myCngKey.Export(CngKeyBlobFormat.Pkcs8PrivateBlob);
Console.WriteLine(Convert.ToBase64String(privatePlainTextBlob));
}

Now your key pair is contained in the PKCS#8 ASN.1 encoded string.

like image 170
Rowan Smith Avatar answered Oct 12 '22 08:10

Rowan Smith