Creating And Managing Digital Certificates In C# Using Visual Studio

Introduction

Digital Certificates are used for secure communication between the two parties. In digital certification, we ensure that the people, who are using our apps or Services are securely communicating with each other and those people can be the individual consumers or businesses.

In Digital Certification, we use both Hashing and Asymmetric encryption to create the digital signatures.

After encrypting the hash of data, we obtain a digital signature later, which is used for verification for the data.

C#

Background

There are a lot more people and private businesses who have their presence on the  internet for the public as well as private communication, according to their business needs.

The number of people and online businesses are continuously increasing. As the communication is becoming cheaper and more easily available, people start spending more time online and most of the time, they do personal communications as well.

As the Internet is open for all, everybody can connect and start the communication. The internet was originally designed for communication but not security. Thus, some internet criminals started taking advantage of internet vulnerabilities for illegal gains.

Now, the business needs security to succeed on the internet and that’s where digital certification comes into play.

Digital Certificates provide us a secure and confidential way to communicate.

key

Public Key Infrastructure (PKI)

Digital Certificates are a part of PKI (Public Key Infrastructure), which is a cryptographic system to create digital certificates.

PKI uses two keys, where one is a public key and the other one is a private key. PKI is actually based on Asymmetric Encryption. The public key is known by all and the private key is only known by the key owner. It should be kept in a secure place.

The unique thing about the keys is that both are mathematically related to each other in such a way, so that the message can be encrypted by the private key and only the corresponding public key can decrypt the message.

If you know the public key, it is impossible to infer the private key.

key

Simple Scenario

Suppose, we have two persons, namely Ahmed and Fatima. They both want to communicate securely. Thus, what process should they have to follow for a secure and confidential communication?

  1. First, Ahmed hashes his message to generate hash.

  2. Afterwards, he encrypts the hash with his private key to create a digital signature.

  3. When Fatima receives Ahmed’s message on the other hand, she also receives the digital signature.

  4. Fatima decrypts the signature with her public key to get hash from the signature.

  5. Now, Fatima has both the signatures- hash and message. Fatima will hash her message to compare whether her hash and hash from Ahmed matches or not.

If both the hashes match, we can say Fatima received the actual message from Ahmed, else the message was changed.

Certificate Authority (CA)

In digital certification, CA (Certification Authority) is the third party individual, who issues certificates that are trustworthy to all the other parties involved in the communication.

Certification authority issues the certificates, which contain a public key, certificate subject and the details about the authority itself.

For now, about CA, you just keep in mind that there are some authorities, who issue certificates and you need to trust them, so that secure communication can take place.

Creating Certificate with Makecert.exe.

At the development level, we can use a tool Makecert.exe to create X.509 certificates for the testing purposes.

X.509 Certificate- X.509 certificate is a standard, which is widely used for defining the digital certificate. X.509 uses PKI (Public Key Infrastructure) to verify the identity of the user with the public key.

To create a certificate, use makecert to open Visual Studio developer command prompt as an administrator and run the command, given below.

makecert -n "cn=sampleCertSubject" -sr currentuser -ss sampleCertStore

The command will create a new certificate and install it into a certificate store name sampleCertStoreat current user location.

Introduction Digital Certificates are used for secure communication between two parties. In digital certification we ensure that the peoples who are using our apps or services are securely communicating with each other and those peoples can be individual consumers or businesses. In Digital Certification we use both Hashing and Asymmetric encryption for creating digital signatures. After encrypting the hash of data we obtain a digital signature later which is used for verifications for data. Background As there are a lot more peoples and private businesses have their presence on internet for public and as well se private communication according to their business needs. The number of peoples and businesses online is continuing increasing. As the communication is becoming cheaper and easily available so people start spending more time online and most of the time they do personal communications as well. As Internet is open for all, everybody can get connected and start communication. Internet was originally designed for communication in mind but not security So some internet criminals started taking advantages from internet vulnerabilities for illegal gains. Now the business need security to succeed on internet and that’s where digital certification comes into play. Digital Certificates provide us secure and confidential way to communicate. Public Key Infrastructure (PKI) Digital certificates are part of PKI (Public Key Infrastructure) which is a cryptographic system for creating digital certificates. PKI uses two keys one is public key and the other one is private key. PKI actually based on Asymmetric Encryption. The public key is known by all and private key is only known by key owner and should be kept in secure place. The unique thing about the keys is that both are mathematically related to each other in such a way so that the message can be encrypted byprivate key and only the corresponding public key can decrypt the message. If you know the public key, then it is impossible to infer the private key. Simple Scenario Suppose we have to persons Ahmed and Fatima. They both want to communicate securely. So what process they should have to follow for secure and confidential communication. First Ahmed hashes his message to generate hash. Then he encrypts the hash with his private key to create digital signature. When Fatima receives Ahmed’s message on other hand then she also receives digital signature. Fatima decrypts the signature with her public key to get hash from signature. Now Fatima has both signature hash and message, Fatima will hash her message to compare whether her hash and hash from Ahmed match are not. If the both hashes matched, then we can say Fatima received the actual message from Ahmed otherwise the message was changed. Certificate Authority (CA) In digital certification CA (Certification Authority) is third part individual that issues certificates that are trustworthy to all other parties involved in communication. Certification authority issues the certificates that contain public key, certificate subject, and details about authority itself. For now, about CA you just keep in mind there are some authorities who issue certificates and you need to trust them so that secure communication can happen Creating Certificate with Makecert.exe. At development level we can use a tool Makecert.exe to create X.509 certificates for testing purposes. X.509 Certificate: X.509 certificate is standard that is widely used for defining digital certificate. X.509 uses PKI (Public Key Infrastructure) to verify the identity of user with public key. To create certificate using makecert open visual studio developer command prompt as administrator and run the following command. makecert -n "cn=sampleCertSubject" -sr currentuser -ss sampleCertStore The command will create a new certificate and install that into a certificate store name sampleCertStoreat current user location. Managing Certificate At this point we successfully created a certificate in store named sampleCertStore. Now we can use our certificate from sampleCertStore to successfully sign and verify data. Signing Data Now if Ahmed has to send data to Fatima then he needs to sign data with private key. To sign data, hehas to follow some simple steps that are explained in following code snippet. Once he signed the data then he should send both signature and data. classX509CertTest { staticvoid Main(string[] args) { string messageToFatima = "My personal data"; //retrieve certificate from store// X509Certificate2 certificate = GetCertFromStore(); //**signing data**// //to sign we need the hash of data// byte[] hashBytes = GetDataHash(messageToFatima); byte[] signature= GetDigitalSignature(hashBytes); } privatestaticbyte[] GetDigitalSignature(byte[] hashBytes) { X509Certificate2 certificate = GetCertFromStore(); /*use any asymmetric crypto service provider for encryption of hash with private key of cert. */ RSACryptoServiceProvider rsaCryptoService = (RSACryptoServiceProvider) certificate.PrivateKey; /*now lets sign the hash 1.spevify hash bytes 2. and hash algorithm name to obtain the bytes */ return rsaCryptoService.SignHash(hashBytes,CryptoConfig.MapNameToOID("SHA1") ); } privatestaticbyte[] GetDataHash(string sampleData) { //choose any hash algorithm SHA1Managed managedHash=newSHA1Managed(); return managedHash.ComputeHash(Encoding.Unicode.GetBytes(sampleData)); } privatestaticX509Certificate2 GetCertFromStore() { //to access to store we need to specify store name and location X509Store x509Store = newX509Store("sampleCertStore",StoreLocation.CurrentUser); //obtain read only access to get cert x509Store.Open(OpenFlags.ReadOnly); return x509Store.Certificates[0]; } } Verifying Data On other hand when Fatima receives Ahmed’s message and signature then she uses her public key to verify the message. privatestaticbool VerifyData(byte[] signature, string messageFromAhemd) { var messageHash = GetDataHash(messageFromAhemd); X509Certificate2 certificate = GetCertFromStore(); RSACryptoServiceProvider cryptoServiceProvider=(RSACryptoServiceProvider)certificate.PublicKey.Key; return cryptoServiceProvider.VerifyHash(messageHash, CryptoConfig.MapNameToOID("SHA1"), signature); } Following here is the complete source code using System; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Text; namespace CertTest { classX509CertTest { staticvoid Main(string[] args) { string messageToFatima = "My personal data"; //retrieve certificate from store// X509Certificate2 certificate = GetCertFromStore(); //**signing data**// //to sign we need the hash of data// byte[] hashBytes = GetDataHash(messageToFatima); byte[] signature= GetDigitalSignature(hashBytes); bool isVerified = VerifyData(signature, messageToFatima); Console.WriteLine($"IsVerified: {isVerified}"); Console.ReadLine(); } privatestaticbool VerifyData(byte[] signature, string messageFromAhemd) { var messageHash = GetDataHash(messageFromAhemd); X509Certificate2 certificate = GetCertFromStore(); RSACryptoServiceProvider cryptoServiceProvider=(RSACryptoServiceProvider)certificate.PublicKey.Key; return cryptoServiceProvider.VerifyHash(messageHash, CryptoConfig.MapNameToOID("SHA1"), signature); } privatestaticbyte[] GetDigitalSignature(byte[] hashBytes) { X509Certificate2 certificate = GetCertFromStore(); /*use any asymmetric crypto service provider for encryption of hash with private key of cert. */ RSACryptoServiceProvider rsaCryptoService = (RSACryptoServiceProvider) certificate.PrivateKey; /*now lets sign the hash 1.spevify hash bytes 2. and hash algorithm name to obtain the bytes */ return rsaCryptoService.SignHash(hashBytes,CryptoConfig.MapNameToOID("SHA1") ); } privatestaticbyte[] GetDataHash(string sampleData) { //choose any hash algorithm SHA1Managed managedHash=newSHA1Managed(); return managedHash.ComputeHash(Encoding.Unicode.GetBytes(sampleData)); } privatestaticX509Certificate2 GetCertFromStore() { //to access to store we need to specify store name and location X509Store x509Store = newX509Store("sampleCertStore",StoreLocation.CurrentUser); //obtain read only access to get cert x509Store.Open(OpenFlags.ReadOnly); return x509Store.Certificates[0]; } } }

Managing Certificate

At this point, we successfully created a certificate in store named sampleCertStore.

Now, we can use our certificate from sampleCertStore to successfully sign and verify the data.

Signing Data

Now, if Ahmed has to send the data to Fatima, he needs to sign the data with the private key.

To sign the data, he has to follow some simple steps, which are explained in the code snippet, given below. Once he signs the data, he should send both signature and data.

  1. classX509CertTest {    
  2.     staticvoid Main(string[] args) {    
  3.         string messageToFatima = "My personal data";    
  4.     
  5.         //retrieve certificate from store//    
  6.         X509Certificate2 certificate = GetCertFromStore();    
  7.     
  8.         //**signing data**//    
  9.     
  10.         //to sign we need the hash of data//    
  11.         byte[] hashBytes = GetDataHash(messageToFatima);    
  12.     
  13.     
  14.         byte[] signature = GetDigitalSignature(hashBytes);    
  15.     }    
  16.     
  17.     
  18.     privatestaticbyte[] GetDigitalSignature(byte[] hashBytes) {    
  19.         X509Certificate2 certificate = GetCertFromStore();    
  20.         /*use any asymmetric crypto service provider for encryption of hash   
  21.         with private key of cert.   
  22.         */    
  23.         RSACryptoServiceProvider rsaCryptoService = (RSACryptoServiceProvider) certificate.PrivateKey;    
  24.     
  25.         /*now lets sign the hash   
  26.         1.spevify hash bytes   
  27.         2. and hash algorithm name to obtain the bytes   
  28.         */    
  29.         return rsaCryptoService.SignHash(hashBytes, CryptoConfig.MapNameToOID("SHA1"));    
  30.     }    
  31.     
  32.     privatestaticbyte[] GetDataHash(string sampleData) {    
  33.         //choose any hash algorithm    
  34.         SHA1Managed managedHash = newSHA1Managed();    
  35.     
  36.         return managedHash.ComputeHash(Encoding.Unicode.GetBytes(sampleData));    
  37.     }    
  38.     
  39.     privatestaticX509Certificate2 GetCertFromStore() {    
  40.         //to access to store we need to specify store name and location    
  41.         X509Store x509Store = newX509Store("sampleCertStore", StoreLocation.CurrentUser);    
  42.     
  43.         //obtain read only access to get cert    
  44.         x509Store.Open(OpenFlags.ReadOnly);    
  45.     
  46.         return x509Store.Certificates[0];    
  47.     }    
  48. }     
Verifying Data

On other hand, when Fatima receives Ahmed’s message and the signature, she uses her public key to verify the message.
  1. privatestaticbool VerifyData(byte[] signature, string messageFromAhemd)  
  2. {  
  3.     var messageHash = GetDataHash(messageFromAhemd);  
  4.     X509Certificate2 certificate = GetCertFromStore();  
  5.     RSACryptoServiceProvider cryptoServiceProvider = (RSACryptoServiceProvider) certificate.PublicKey.Key;  
  6.     return cryptoServiceProvider.VerifyHash(messageHash, CryptoConfig.MapNameToOID("SHA1"), signature);  
  7. }  
The complete source code is given below.
  1. using System;    
  2. using System.Security.Cryptography;    
  3. using System.Security.Cryptography.X509Certificates;    
  4. using System.Text;    
  5.     
  6. namespace CertTest {    
  7.     classX509CertTest {    
  8.         staticvoid Main(string[] args) {    
  9.             string messageToFatima = "My personal data";    
  10.     
  11.             //retrieve certificate from store//    
  12.             X509Certificate2 certificate = GetCertFromStore();    
  13.     
  14.             //**signing data**//    
  15.     
  16.             //to sign we need the hash of data//    
  17.             byte[] hashBytes = GetDataHash(messageToFatima);    
  18.     
  19.     
  20.             byte[] signature = GetDigitalSignature(hashBytes);    
  21.             bool isVerified = VerifyData(signature, messageToFatima);    
  22.     
  23.             Console.WriteLine($ "IsVerified: {isVerified}");    
  24.     
  25.             Console.ReadLine();    
  26.         }    
  27.     
  28.         privatestaticbool VerifyData(byte[] signature, string messageFromAhemd) {    
  29.             var messageHash = GetDataHash(messageFromAhemd);    
  30.     
  31.             X509Certificate2 certificate = GetCertFromStore();    
  32.     
  33.             RSACryptoServiceProvider cryptoServiceProvider = (RSACryptoServiceProvider) certificate.PublicKey.Key;    
  34.     
  35.             return cryptoServiceProvider.VerifyHash(messageHash, CryptoConfig.MapNameToOID("SHA1"), signature);    
  36.         }    
  37.     
  38.         privatestaticbyte[] GetDigitalSignature(byte[] hashBytes) {    
  39.             X509Certificate2 certificate = GetCertFromStore();    
  40.             /*use any asymmetric crypto service provider for encryption of hash   
  41.             with private key of cert.   
  42.             */    
  43.             RSACryptoServiceProvider rsaCryptoService = (RSACryptoServiceProvider) certificate.PrivateKey;    
  44.     
  45.             /*now lets sign the hash   
  46.             1.spevify hash bytes   
  47.             2. and hash algorithm name to obtain the bytes   
  48.             */    
  49.             return rsaCryptoService.SignHash(hashBytes, CryptoConfig.MapNameToOID("SHA1"));    
  50.         }    
  51.     
  52.         privatestaticbyte[] GetDataHash(string sampleData) {    
  53.             //choose any hash algorithm    
  54.             SHA1Managed managedHash = newSHA1Managed();    
  55.     
  56.             return managedHash.ComputeHash(Encoding.Unicode.GetBytes(sampleData));    
  57.         }    
  58.     
  59.         privatestaticX509Certificate2 GetCertFromStore() {    
  60.             //to access to store we need to specify store name and location    
  61.             X509Store x509Store = newX509Store("sampleCertStore", StoreLocation.CurrentUser);    
  62.     
  63.             //obtain read only access to get cert    
  64.             x509Store.Open(OpenFlags.ReadOnly);    
  65.     
  66.             return x509Store.Certificates[0];    
  67.         }    
  68.     }    
  69. }