Search code examples
cryptographyecdsa

ECDsaCng signature generation using SignData or SignHash give different result


I am trying to generate signature using ECDSA with secp256r1 curve (P256) and SHA256 algorithm for message hash. Also i am using NET libraries. Code below,

using System;
using System.Security.Cryptography;

namespace ProjetTest
{
    public static class TestProgram
    {
        public static void Main()
        {
            var data = new byte[100];
            new Random().NextBytes(data);
            var dataHash = new SHA256Cng().ComputeHash(data);

            var cng = new ECDsaCng(256);
            cng.HashAlgorithm = CngAlgorithm.Sha256;
            var signOnHash = cng.SignHash(dataHash);
            var signOnData = cng.SignData(data);
        }
    }
}

SignOnHash and SignOnData should contain same byte array, but they don't. Need help.


Solution

  • The issue is that the (EC)DSA algorithm itself is non-deterministic - it internally depends on a secure random number generator. So you'll have to wait a very long time before you generate the same signature.

    The fact that RSA is deterministic for the older - but more prevalent - PKCS#1 v1.5 padding is a fluke, that was solved with the introduction of PSS padding. So in general you should expect that signature algorithms create signatures that are hard to distinguish from random.

    You can try this yourself by removing new Random().NextBytes(data); statement, the results should be different each time even without it. Note that the private key can be calculated from ECDSA signatures if the underlying random is broken, as fail0verflow has shown.