Cryptography and .NET - Part 5 (Digital Signatures)
In the previous article of this series (Part
Part 4) we learnt to create hash values. Continuing our journey ahead we
will cover Digital Signatures. Digital signatures are used to verify identity of
the sender and ensure data integrity. They are often used along with public key
How Digital Signature work
In Part 1 we mentioned how digital signatures work.
- Sender applies hash algorithm to the data being sent and creates a
message digest. Message digest is compact representation of the data being
- Sender then encrypts the message digest with the private key to get a
- Sender sends the data over a secure channel
- Receiver receives the data and decrypts the digital signature using
public key and retrieves the message digest
- Receiver applies the same hash algorithm as the sender to the data and
creates a new message digest
- If sender's digest and receiver's digest match then it means that the
message really came from the said sender.
.NET Framework provides classes RSACryptoServiceProvider,
RSAPKCS1SignatureFormatter and RSAPKCS1SignatureDeformatter that allow you
create and verify digital signatures. All of them reside in
In this example we will be creating a class called DigitalSignatureHelper
that allows us to generate digital signatures and verify signatures. Note in
order to run this example you need MD5HashHelper that we developed in the
public class DigitalSignatureHelper
public byte CreateSignature(byte hash)
RSACryptoServiceProvider RSA =
RSAPKCS1SignatureFormatter RSAFormatter =
public bool VerifySignature(byte hash,byte signedhash)
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
RSAParameters RSAKeyInfo=new RSAParameters();
RSAKeyInfo.Modulus = m_public.Modulus;
RSAKeyInfo.Exponent = m_public.Exponent;
RSAPKCS1SignatureDeformatter RSADeformatter =
return RSADeformatter.VerifySignature(hash, signedhash);
Let's understand the code step-by-step.
- We create a class called DigitalSignatureHelper with two private
variables and two methods.
- The class level variables m_private and m_public are of type
RSAParameters and are used to store public and private key information.
- The method CreateSignature() accepts the hash value that has to be
signed and returns the digitally signed hash as a return value
- Inside this function we create an instance of a class called
- We also create an instance of a class called RSAPKCS1SignatureFormatter
and pass the instance of RSACryptoServiceProvider in its constructor.
- The RSAPKCS1SignatureFormatter class is used to create PKCS #1 (Public
Key Cryptographic Signature) version 1.5 signature. Where as
RSACryptoServiceProvider provides encryption services.
- Since we will be using MD5 as a hashing algorithm, we call
SetHashAlgorithm() method of RSAPKCS1SignatureFormatter and pass "MD5"
as a parameter. If your hashing algorithm is SHA1 you would have passed SHA1
- Then we call ExportParameters() method of RSACryptoServiceProvider to
get public and private keys generated. We store these keys the class level
variables m_public and m_private respectively.
- Finally we call CreateSignature() method of RSAPKCS1SignatureFormatter
class which returns the signature. The same is returned as the return value
of the function.
- The VerifySignature() method accepts two parameters - original hash
value and signed hash value. It compares the hashes and return true if they
- Inside this function we create an instance of
- We need to supply key information during signature verification and
hence we create an instance of RSAParameters structure.
- The Modulus and Exponent properties of this structure are set to the
equivalent properties of previously obtained public key (m_public).
- We then call ImportParameters() method of RSACryptoServiceProvider to
import the key information into the instance.
- Then we create an instance of RSAPKCS1SignatureDeformatter class. This
class is used to verify RSA PKCS #1 version 1.5 signatures.
- Again, we set the hashing algorithm to MD5 using SetHashAlgorithm()
method of RSAPKCS1SignatureDeformatter class.
- Finally we call VerifySignature() method of RSAPKCS1SignatureDeformatter
class and pass original hash value and signed hash value to it. This method
returns true if the signature is verified successfully else it returns
false. The same return value is returned as to the caller.
Complete source code along with a sample usage is available for download with
this article (see top).
In this article we learnt about digital signatures. Digital signatures allow
you to verify that the data came from known sender. The classes RSACryptoServiceProvider,
RSAPKCS1SignatureFormatter and RSAPKCS1SignatureDeformatter from
System.Security.Cryptography allow you to work with digital signatures.