Elliptic Curve DSA

Yesterday I gave a quick rundown of all the new cryptographic algorithms available in the Orcas January CTP.  Today, let's dive in a little deeper to the first of the elliptic curve algorithms, ECDSA.  (ECDSA, along with the rest of the CNG classes in the .NET Framework, is only available on Windows Vista).

ECDSA is an implementation of the digital signature standard using elliptic curves, which makes the ECDsaCng class a sort of cousin of the DSACryptoServiceProvider class.  Because DSA and ECDSA are cousins rather than just different implementations of the same algorithm, there is a new base class ECDsa that elliptic curve DSA implementations derive from.  You also cannot sign some data with DSACryptoServiceProvider and then verify that signature with ECDsaCng.

Let's take a look at a basic example of using ECDSA:

ECDsaCng dsa = new ECDsaCng();

dsa.HashAlgorithm = CngAlgorithm.Sha256;

 

byte[] data = new byte[] { 21, 5, 8, 12, 2007 };

byte[] signature = dsa.SignData(data);

 

if (dsa.VerifyData(data, signature))

    Console.WriteLine("Verified");

else

    Console.WriteLine("Not verified");

First we create a new ECDsaCng object, which will generate a random key for us to use.  Next, we setup the hash algorithm to use on the input data when creating the signature.  Finally, we can call SignData to create a signature over a blob of data, and VerifyData to verify that the signature is correct.

There are also SignHash/VerifyHash APIs available -- SignData will essentially just hash the data with the hash algorithm specified on the ECDsaCng object (defaulting to SHA-256) and then do a SignHash on the resulting hash value.

Sidebar: CNG Pseudo-Enums

I showed the HashAlgorithm property in the example, even though I was setting it back to the default value, because it uses the CngAlgorithm class which is the first of several pseudo-enums that will show up when you play with the CNG classes.  CNG itself is very configurable, and it takes most of its configuration options as strings.  With our managed APIs, we didn't want to limit the set of parameters you can pass to CNG to the set that we had predefined a mapping from a traditional enum to a CNG string for.  We also wanted to preserve type safety (having everything be a string makes it unclear which strings can go where), and provide pre-defined values for the common cases.

The result is a set of pseudo-enumerations like CngAlgorithm.  CngAlgorithm isn't an enum, it's a class.  We've provided a set of CngAlgorithms representing the common algorithm names as static properties, which allow you to use it with enum-like syntax.  There's also a CngAlgorithm constructor which takes a string, which means that if you need to use a CNG algorithm that isn't in the list you can construct a CngAlgorithm to reference that algorithm.

Each of the pseudo enums also behave just as you would expect when dealing with them directly.  You can compare them with your language of choice's equality comparison operators, get their hash code, and convert them to their underlying strings.  In addition to CngAlgorithm other pseudo-enums you'll find are CngAlgorithmGroup, CngKeyFormat, and CngProvider.

The default constructor generates a random key for use with the P-521 curve, described in appendix 6 of FIPS 186-2.  There is also a constructor which accepts the curve you wish to work with; currently ECDsaCng supports P-192, P-256 and P-521. Or, if you don't want to generate a random key you can pass in an existing key to the constructor and it will work with that.

Incidentally, the CngKey class is your one stop shop for anything to do with CNG keys (stored by NCrypt).  You can use this class to create a new random key, open or delete an existing key, get the properties of a key, import / export the key, etc.  We also expose a SafeNCryptKeyHandle which represents the underlying NCRYPT_KEY_HANDLE, allowing you to easily P/Invoke for any other functionality not exposed in the CngKey class itself.

In addition to exporting the ECDSA key via the CngKey property of the ECDsaCng object, you can also export the key into XML.  However, since there is currently no standard format for elliptic curve XML, you need to specify which format you want the XML to appear in (not specifying a format will cause an exception).  Currently, we only support one option which is the format described in RFC 4050.

So that concludes our whirlwind tour of the ECDsaCng class.  Next time we'll take a look at the elliptic curve Diffie-Hellman support in Orcas.