Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating an ECC Private/Public key with native C#

I've been looking around for hours on Google and Microsoft's Crypto API on how to generate a public and private ECC key pair. The ECDiffieHellmanCng Class (http://msdn.microsoft.com/en-us/library/system.security.cryptography.ecdiffiehellmancng.aspx#Y3081) lists an example but I don't know how to access the private key directly.

For a little background on the program, it's a C# console app for managing TrueCrypt sessions, AES pre-shared key encryption, and ECDH/AES encryption. I need a function to merely create a public/private key pair to save to files, then documentation of how to use those generated keys in a wrapped AES encrypted file (instead of generating it at runtime like the example shows). Also I am aware off all the vulnerabilities that arise with saving files to the harddrive however I'm not worried about that with this program and I'm considering the 2 client computers to be secure.

Also note, I don't want to use the BouncyCastle API.

like image 519
Jim Avatar asked Apr 22 '12 02:04

Jim


2 Answers

I believe this is what you are looking for? If yes, please mark as (my first!) answer :-)

Most of this related to the CngKey, that can be used in many variations.

    static void test1()
    {
        CngKey k;

        if (CngKey.Exists("myECDH", CngProvider.MicrosoftSoftwareKeyStorageProvider, CngKeyOpenOptions.MachineKey))
        {
            k = CngKey.Open("myECDH", CngProvider.MicrosoftSoftwareKeyStorageProvider, CngKeyOpenOptions.MachineKey);
        }
        else
        {
            k = CngKey.Create(CngAlgorithm.ECDiffieHellmanP256, "myECDH", new CngKeyCreationParameters
        {
            ExportPolicy = CngExportPolicies.AllowPlaintextExport,
            KeyCreationOptions = CngKeyCreationOptions.MachineKey,
            KeyUsage = CngKeyUsages.AllUsages,
            Provider = CngProvider.MicrosoftSoftwareKeyStorageProvider,
            UIPolicy = new CngUIPolicy(CngUIProtectionLevels.None)
        });
        }

        byte[] privateBytes = k.Export(CngKeyBlobFormat.EccPrivateBlob);
        byte[] publicBytes = k.Export(CngKeyBlobFormat.EccPublicBlob);

        //This:
        var privateTester1 =
            new ECDiffieHellmanCng(CngKey.Import(privateBytes, CngKeyBlobFormat.EccPrivateBlob,
                CngProvider.MicrosoftSoftwareKeyStorageProvider));

        //Or that:
        var privateTester2 = new ECDiffieHellmanCng(k);
    }
like image 81
Henrik N. Avatar answered Sep 20 '22 08:09

Henrik N.


Elliptic Curve DiffieHellman is not an encryption algorithm, it is a key agreement protocol. Over an insecure channel, it gives you and the other party a common shared secret. This is frequently used for say an AES key to conduct secure communication.

Given another party's public key, you can get the derived shared secret key material with this api call. Note that as per the remarks section, the CNG APi does some post processing on the derived secret so it may or may not agree with what true-crypt generates.

To get the actual private key(which is not the shared secret), you can use use the following. You may want a different export format, they are listed here

using (ECDiffieHellmanCng alice = new ECDiffieHellmanCng())
    { 
    // Any  code you have  specifies the key your using or generates  one 
    var privatekey = alice.Key.Export(CngKeyBlobFormat.Pkcs8PrivateBlob)
    }

Note you may wind up with an error saying that the export policy does not allow exporting the private key. In that case, you need to create and user a key with a policy that does allow export

like image 41
imichaelmiers Avatar answered Sep 19 '22 08:09

imichaelmiers