简体   繁体   中英

How to verify digital signature in C#

I am new here.

I am learning the digital signature in C#. The certificates are generated followed by this document . Other documents I read: RSACng , X509Certificate2 .

I am working on Windows 10 Pro 1809, .Net Core 2.1, VSCode.

    class Program
    {
        static void Main(string[] args)
        {
            var passwd = "password";

            // Get client certificate.
            var clientCertPath = @"./Certificates/test.pfx";
            var clientCert = new X509Certificate2(clientCertPath, passwd);

            // Get server certificate.
            var serverCertPath = @"./Certificates/test.cer";
            var serverCert = new X509Certificate2(serverCertPath);

            // Generate data.
            var translateResultData = BuildData();
            var content = String.Join('&', translateResultData.Select(p => String.Join('=', p.Key, p.Value)));

            // Sign
            var sign = SignatureUtil.Sign(data: content, clientCert: clientCert);
            // translateResultData.TryAdd(key: "sign", value : sign);

            // Copy content ONLY for test.
            var checkSign = sign;
            var checkContent = content;

            // Verify
            var valid = SignatureUtil.Verify(data: checkContent, signature: checkSign, serverCert: serverCert);
            System.Console.WriteLine(valid);
        }
}
    public class SignatureUtil
    {
        public static string Sign(string data, X509Certificate2 clientCert)
        {
            using(var privateKey = clientCert.GetRSAPrivateKey())
            {
                var dataByteArray = Encoding.UTF8.GetBytes(data);
                var signatureByteArray = privateKey.SignData(
                    data: dataByteArray,
                    hashAlgorithm: HashAlgorithmName.SHA256,
                    padding: RSASignaturePadding.Pkcs1);
                return Convert.ToBase64String(signatureByteArray);
            }
        }

        public static bool Verify(string data, string signature, X509Certificate2 serverCert)
        {
            try
            {
                using(var publicKey = serverCert.GetRSAPublicKey())
                {
                    var dataByteArray = Encoding.UTF8.GetBytes(data);
                    var signatureByteArray = Convert.FromBase64String(signature);
                    return publicKey.VerifyData(
                        data: dataByteArray,
                        signature: signatureByteArray,
                        hashAlgorithm: HashAlgorithmName.SHA256,
                        padding: RSASignaturePadding.Pkcs1);
                }
            }
            catch (System.Exception)
            {
                return false;
            }
        }
    }

Expected result: valid should be true because I am checking the original data.
Fact: The Verify method always returns false even the original data are passed.

Can you tell me what I did wrong?

I cannot tell you what is going wrong in your code since I cannot reproduce it. Here is a very detailed answer how you can sign using RSA and SHA256. Your approach and the one described in this answer are conceptually the same, but maybe there is a difference in your code compared to this answer.

And here is a example how in my company certificates associated with smart cards are used for signing and verifying signatures. One big difference is that we do not store the signature as a string but rather keep it as an array of bytes.

public byte[] SignData(byte[] data)
{
    using (var sha256 = SHA256.Create())
    {
        using (var rsa = Certificate.GetRSAPrivateKey())
        {
            return rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1)
        }
    }
}


public bool VerifySignature(byte[] data, byte[] signature)
{
    using (var sha256 = SHA256.Create())
    {
        using (var rsa = Certificate.GetRSAPublicKey())
        {
            return rsa.VerifyData(data, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1)
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM