makerofthings7
makerofthings7

Reputation: 61433

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

Cryptography Application Block

Win32 PFXImportCertStore

Import PEM

Microsoft's CLR Security enhancements

Microsoft CNG

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?

Upvotes: 6

Views: 6285

Answers (1)

Rowan Smith
Rowan Smith

Reputation: 2180

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.

Upvotes: 2

Related Questions