Condividi tramite


How to Sign and Verify the signature with .NET and a certificate (C#)

Hi all,

Today I'm posting a sample which shows how to sign a text with a certificate in my Personal store (this cert will have public and private key associated to it) and how to verify that signature with a .cer file (for i.e. WinForms) applications or a client certificate (for i.e. ASP.NET) (both will only have public key associated to them).

 using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;

namespace ConsoleApplication1
{
    class Program
    {
        static byte[] Sign(string text, string certSubject)
        {
            // Access Personal (MY) certificate store of current user
            X509Store my = new X509Store(StoreName.My, StoreLocation.CurrentUser);
            my.Open(OpenFlags.ReadOnly);

            // Find the certificate we'll use to sign            
            RSACryptoServiceProvider csp = null;
            foreach (X509Certificate2 cert in my.Certificates)
            {
                if (cert.Subject.Contains(certSubject))
                {
                    // We found it. 
                    // Get its associated CSP and private key
                    csp = (RSACryptoServiceProvider)cert.PrivateKey;
                }
            }
            if (csp == null)
            {
                throw new Exception("No valid cert was found");
            }

            // Hash the data
            SHA1Managed sha1 = new SHA1Managed();
            UnicodeEncoding encoding = new UnicodeEncoding();
            byte[] data = encoding.GetBytes(text);
            byte[] hash = sha1.ComputeHash(data);

            // Sign the hash
            return csp.SignHash(hash, CryptoConfig.MapNameToOID("SHA1"));            
        }

        static bool Verify(string text, byte[] signature, string certPath)
        {
            // Load the certificate we'll use to verify the signature from a file 
            X509Certificate2 cert = new X509Certificate2(certPath);
            // Note: 
            // If we want to use the client cert in an ASP.NET app, we may use something like this instead:
            // X509Certificate2 cert = new X509Certificate2(Request.ClientCertificate.Certificate);

            // Get its associated CSP and public key
            RSACryptoServiceProvider csp = (RSACryptoServiceProvider)cert.PublicKey.Key;

            // Hash the data
            SHA1Managed sha1 = new SHA1Managed();
            UnicodeEncoding encoding = new UnicodeEncoding();
            byte[] data = encoding.GetBytes(text);
            byte[] hash = sha1.ComputeHash(data);

            // Verify the signature with the hash
            return csp.VerifyHash(hash, CryptoConfig.MapNameToOID("SHA1"), signature);
        }

        static void Main(string[] args)
        {
            // Usage sample
            try
            {
                // Sign text
                byte[] signature = Sign("Test", "cn=my cert subject");

                // Verify signature. Testcert.cer corresponds to "cn=my cert subject"
                if (Verify("Test", signature, @"C:\testcert.cer"))
                {
                    Console.WriteLine("Signature verified");
                }
                else
                {
                    Console.WriteLine("ERROR: Signature not valid!");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("EXCEPTION: " + ex.Message);
            }
            Console.ReadKey();
        }
    }
}

I hope this helps.

Cheers,

 

Alex (Alejandro Campos Magencio)

Comments

  • Anonymous
    June 25, 2008
    i want a C++ script to develop user name 'n password frame interface could u help me plzzzmy email is hashim.zied@hotmail.com
  • Anonymous
    June 25, 2008
    I'm sorry. I can't attend those kind of specific requests.
  • Anonymous
    July 14, 2008
    Thank you for the posting.There was no finding practical example of digital signature, and this posting helped me a lot.
  • Anonymous
    August 24, 2008
    The comment has been removed
  • Anonymous
    August 25, 2008
    I'm sorry. I can't attend requests for custom samples. But if you contact MS Technical Support we can assist you to create one.Cheers,Alex
  • Anonymous
    October 05, 2008
    The comment has been removed
  • Anonymous
    March 22, 2009
    Hi Alex!I've create my own cer with Office tool for VBA and I can see it in storage, but with 'csp = (RSACryptoServiceProvider)cert.PrivateKey;'(Sign process)I get nothing, it generates empty field...What's wrong, where am I the idiot?:)
  • Anonymous
    March 22, 2009
    Sorry my bad, wrong spaces after "CN_=_"
  • Anonymous
    May 18, 2009
    My main aim is to provide capabilility to server to access client and logout  the running application(s).I need to have following support in certificate.I need to generate the Certificate at runtime at the time of installation from the 3rd Party CA and install them to local machine where  my application running.Client Config need to be updated with the certificate generated. Client also hold the server certificate without its private key, So that Server and client can communicate in reverse mode scenario.Server Certificate also need to be in the trusted people storeI am using WCF.Please Guide me.
  • Anonymous
    June 18, 2009
    Thanks man,i tried so many ways to verify signature but i am getting.ur code is outstanding,its working fine......thanks once again......my mail-id:prabhugtec@gmail.com
  • Anonymous
    September 09, 2009
    I'm studying how to create and verify a digital signature, but I have a problem in create and use a certificate. I don't know why it can not get the information in certificate store. I use makecert.exe to create the certificate. Can you help me how to create a certificate use for this example? Thank in advance.
  • Anonymous
    December 13, 2010
    nice 1
  • Anonymous
    December 13, 2010
    Nice artical, but can you please tell me how to get certificate from CurrentUser Store. I am able to get it in ASPNET server but not in IIS Server. Thanks.
  • Anonymous
    September 27, 2012
    Hi ,I understand your code but the problem is that i want to sign the contents at client side instand or server side, your code is showing seems its doing on server side, can you have an example where can we sign the contents to client side using javascript and will verify at server side code using C#.please mail me if you have solution : my  Mail id :hiren.sojitra@gmail.com
  • Anonymous
    January 28, 2013
    Thanks a  lot for ur valuable post.I want to add the digital signature to my file. This i want to do this by programming not using MS  office.I am using c#. Can any one help me in any  way.
  • Anonymous
    April 15, 2013
    HiI got an bad hash error in SHA-256 Algorithm........Please anyone  Help meMy Sample Code is           SHA256Managed sha2 = new SHA256Managed();           UnicodeEncoding encoding = new UnicodeEncoding();           byte[] data = encoding.GetBytes(text);           ConsoleApplication1.Program.writeByteArrayToFile(data, "Data");           byte[] hash = sha2.ComputeHash(data);return csp.SignHash(hash, CryptoConfig.MapNameToOID("SHA-256"));My Email Id:saran_kamal@yahoo.co.in
  • Anonymous
    April 22, 2013
    it is saying that no valid cer was found,could u please help me
  • Anonymous
    September 23, 2013
    Dear all,I want Sign and Verify file excel in c#Thansk all.
  • Anonymous
    October 27, 2013
    Not able to fetch the client certificate..
  • Anonymous
    November 20, 2013
    How can we access to the private certificate key?Dear Alejandro,Thanks a lot for your post, It's really interesting.I need to retrieve cert private key to sign an xml document.I can not give asp.net user right access to it, because it's going to be a web app.There should be a way to ask the user which certificate want him to use for the sign and ask him to permit to access to the private key.I found a class on win apps (X509Certificate2UI) but as far as I know there is no equivalent class on C# .net web environment.                   csp = (RSACryptoServiceProvider)cert.PrivateKey;Thanks in advance,Best wishesRafa
  • Anonymous
    January 19, 2014
    Hi, Thanks a lot for the code.Question: I've got an expired certificate and I still success signing data.I thought that it would be impossible to sign with an expired certificate.Can you please help with that issue.Thanks in advance.
  • Anonymous
    August 04, 2014
    How can we have attached signature ?
  • Anonymous
    March 21, 2015
    The post is very helpful. Thanks Alex.