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.
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.
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.
Example
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?
- First, Ahmed hashes his message to generate hash.
- Afterwards, he encrypts the hash with his private key to create a digital signature.
- When Fatima receives Ahmed’s message on the other hand, she also receives the digital signature.
- Fatima decrypts the signature with her public key to get hash from the signature.
- 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.
How to Manage 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.
How to Sign 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.
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];
}
}
How to Verify Data?
On other hand, when Fatima receives Ahmed’s message and the signature, 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);
}
The complete source code is given below.
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];
}
}
}