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.