How to compute the ECDSA signature using a P-256 key in a PEM file using C#.NET?

Viewed 1864

I am new to cryptography and in over my head trying to sort it out on Windows, using C#.NET

I generated an elliptic curve P-256 (a.k.a. secp256r1 and prime256v1) key using the following command:

openssl ecparam –name prime256v1 -genkey –noout –out private.key

I generated a certificate signing request using the following command:

openssl req –new –key private.key –out certreq.csr –sha256

Another team sent me a base-64 encoded certificate in response. So far so good.

I have now received some "test" data that I need to compute the ECDSA signature of, using the private-key. The private key looks something like:

-----BEGIN EC PRIVATE KEY-----
FunnyHow?LIKEACLOWN?DOIAMUSEYOU?DOIMAKEYOULAUGH?==
-----END EC PRIVATE KEY-----

I have been struggling with code similar to the following so far:

byte[] cngBlob; // This was calculated based on another StackOverFlow post
byte[] testData       = "JoePesciWasGreatInGoodfellas";
CngKey cngKey         = CngKey.Import(cngBlob, CngKeyBlobFormat.EccPrivateBlob);
ECDsaCng eCDsaCng     = new ECDsaCng(cngKey);
byte[] signatureECDSA = eCDsaCng.SignData(testData);

I tried calculating byte[] cngBlob using the private-key file, based on Microsoft CNG | How to import PEM encoded ECDSA private key into MS Key Storage Provider but however am not getting the correct answer in byte[] signatureECDSA.

How do I read in the private key from the file and then use it to compute the ECDSA signature of the test data?

I have started to delve into the fascinating world of cryptography but it will take me some time to get familiar with it. Am I on the right track here? Any tips in the meantime to help me with this issue would be much appreciated.

1 Answers

It turns out that the code above was the correct approach, but for a mistake I made. I had actually calculated a hash of the test data using the method

byte[] HashAlgorithm.ComputeHash(byte[] buffer)

and it was this hashed value of the test data that I was trying to sign. My test data above should probably have looked like

     byte[] testData = null;
     using (SHA256 sha256 = SHA256.Create())
     {
        testData = sha256.ComputeHash("JoePesciWasGreatInGoodfellas");
     }

I did not realize that calculating the hash would make all the difference.

The correct call I had to use to sign the hashed test data turns out to be

byte[] signatureECDSA = eCDsaCng.SignHash(testData);

Here is what the final corrected code would look like:

byte[] cngBlob; // This was calculated based on another StackOverFlow post
byte[] testData = null;
using (SHA256 sha256 = SHA256.Create())
{
    testData = sha256.ComputeHash("JoePesciWasGreatInGoodfellas");
}
CngKey cngKey         = CngKey.Import(cngBlob, CngKeyBlobFormat.EccPrivateBlob);
ECDsaCng eCDsaCng     = new ECDsaCng(cngKey);
byte[] signatureECDSA = eCDsaCng.SignHash(testData);

Note: As mentioned in the earlier post, please refer to the excellent information at Microsoft CNG | How to import PEM encoded ECDSA private key into MS Key Storage Provider to see to to create cngBlob from a private key in a PEM file.

Related