14

Knowing little about cryptography I have great problems with what seems to be a simple task.

I have .pem certificate, bytes of data, and signature of that data. I want to check if someone changed the data by matching it against signature.

My try:

private bool VerifySignature(byte[] data, byte[] signature)
{
  try
  {
    X509Certificate certificate = new X509Certificate("cert_filename.pem");
    if (certificate == null)
      return false;

    DSACryptoServiceProvider dsa = (DSACryptoServiceProvider)certificate.PublicKey.Key;

    return dsa.VerifyData(data, signatureData);
  }
  catch
  {
    return false;
  }
}

But it gives me an error

'Algorithm of certificates key is not supported' (System.NotSupportedException).

Looking into loaded certificate it says that the signature algorithm is 'sha1ecdsa'.

I am trying only to verify data against signature. What am I missing here? I would like to do it without any external solutions as it seems to be really trivial task.

Update: I am trying to achieve same functionality as in below Java code:

private boolean verify(byte[] data, byte[] signature)
{
  boolean isLicenseCorrect = false;

  Signature sig = Signature.getInstance("SHA1WithECDSA");
  sig.initVerify(certificate.getPublicKey());
  sig.update(data);

  return sig.verify(signature);
}
Jasper
  • 6,693
  • 3
  • 32
  • 43
kasper
  • 591
  • 2
  • 7
  • 18
  • as per ur update if you want to convert the java code to C# [link](http://dotnetslackers.com/articles/security/Hashing_MACs_and_Digital_Signatures_in_NET.aspx) this might help have a look – too_cool May 20 '15 at 06:40

2 Answers2

6

Although DSA and ECDSA are related, they are not the same. Why not try ECDsaCryptoServiceProvider? Note that the ECDSA support for Elliptic Curves only includes NIST named curves.

Maarten Bodewes
  • 80,169
  • 13
  • 121
  • 225
  • Unfortunately I cannot access this class in my Windows Forms code. I have only ECDsa and ECDsaCng, none of which I am able to use. – kasper May 11 '15 at 14:48
  • OK, so *why* are you not able to use those classes? They should provide a better target as `DSACryptoServiceProvider` is simply never going to work. Note that I don't have your setup (I'm not using Windows Forms myself, I just know things about crypto and what I see passing by here on SO). – Maarten Bodewes May 11 '15 at 15:00
  • As I have mentioned before, I don't know much about crypto, and can't figure out by myself how to solve my task. There are many articles on the net that uses RSACryptoServiceProvider or DSACryptoServiceProvider, but I couldn't make it work with them. – kasper May 13 '15 at 07:08
  • I've added Java code I'd like to port to C# as a reference. – kasper May 19 '15 at 10:10
0

.NET 4.6.1 added improved support for ECDSA. While I'm not a fan of your catch-everything-and-return-false, I'll keep it here for comparison:

private bool VerifySignature(byte[] data, byte[] signature)
{
    try
    {
        // new cannot return null, so no point in a null check. It would have thrown.

        using (X509Certificate certificate = new X509Certificate("cert_filename.pem"))
        using (ECDsa ecdsa = certificate.GetECDsaPublicKey())
        using (RSA rsa = certificate.GetRSAPublicKey())
        // Improved DSA is 4.6.2
        {
            // You said the cert was ECDSA-SHA1, but that doesn't mean the original data was.
            // I assumed it was.
            if (ecdsa != null)
                return ecdsa.VerifyData(data, signature, HashAlgorithmName.SHA1);

            if (rsa != null)
                return rsa.VerifyData(data, signature, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1);

            return false;
        }
    }
    catch
    {
        return false;
    }
}

Note that in .NET 4.6 the RSA base class has the Sign/Verify methods defined, and in 4.6.1 the ECDsa base class got a similar treatment. New code shouldn't talk about the *CryptoServiceProvider types unless loading pre-existing named keys.

It's also worth noting that the Get[Algorithm]PublicKey methods return null when the public key isn't of that algorithm type, so a null-check is warranted.

bartonjs
  • 23,118
  • 2
  • 51
  • 90