Digital signatures

Digital signatures can be used to sign the message that will authenticate the sender. However, signing a message doesn't prevent a third party from reading the message. To achieve this, we need to encrypt the message and sign it. 

In the following example, we are using a public key and a private key (asymmetric algorithm). We use the sender's private key to sign the message and the receiver's public key to encrypt the message. If you observe the code, we also use hash computing in this example. After encrypting the message, we hash the message.

We are going to use RSACryptoServiceProvider, along with RSAPKCS1SignatureFormatter, which will be used to create a signature.

In the following program, we convert text to a byte array using UnicodeEncoding classes, encrypt the message using the receiver's public key and the symmetric or asymmetric algorithms we learned in previous sections, compute the hash of the content, and then digitally sign the message. Once all of these processes have been implemented, we transmit the data across, where we recompute the hash, verify the signature, and then decrypt the message using the keys.

In the following example, we are using public-private keys to perform encryption. As mentioned previously, simply signing the message doesn't secure the content of the message. Instead, it will allow you to authenticate the sender:

public static void DigitalSignatureSample(string senderPrivatekey, string receiverspublickey, string texttoEncrypt)
{
UnicodeEncoding uc = new UnicodeEncoding();
Console.WriteLine("Converting to bytes from text");
//get bytearray from the message
byte[] databytes = uc.GetBytes(texttoEncrypt);
Console.WriteLine("Creating cryptoclass instance");
//Creating instance for RSACryptoservice provider as we are using for sender and receiver
RSACryptoServiceProvider rsasender = new RSACryptoServiceProvider();
RSACryptoServiceProvider rsareceiver = new RSACryptoServiceProvider();
//getting private and public key
rsasender.FromXmlString(senderPrivatekey);
rsareceiver.FromXmlString(receiverspublickey);
Console.WriteLine("Creating signature formatter instance");
//GEt signature from RSA
RSAPKCS1SignatureFormatter signatureFormatter = new RSAPKCS1SignatureFormatter(rsasender);
//set hashalgorithm
signatureFormatter.SetHashAlgorithm("SHA1");
//encrypt message
Console.WriteLine("encrypting message");
byte[] encryptedBytes = rsareceiver.Encrypt(databytes, false);
//compute hash
byte[] computedhash = new SHA1Managed().ComputeHash(encryptedBytes);
Console.WriteLine("Creating signature");
//create signature for the message
byte[] signature = signatureFormatter.CreateSignature(computedhash);
Console.WriteLine("Signature: " + Convert.ToBase64String(signature));
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
//receive message then recompute hash
Console.WriteLine("recomputing hash");
byte[] recomputedHash = new SHA1Managed().ComputeHash(encryptedBytes);
//signature deformatter
Console.WriteLine("Creating signature dformatter instance");
RSAPKCS1SignatureDeformatter signatureDFormatter = new RSAPKCS1SignatureDeformatter(rsareceiver);
signatureDFormatter.SetHashAlgorithm("SHA1");
//verify signature
Console.WriteLine("verifying signature");
if (!signatureDFormatter.VerifySignature(recomputedHash, signature))
{
Console.WriteLine("Signature did not match from sender");
}
Console.WriteLine("decrypting message");
//decrypt message
byte[] decryptedText = rsasender.Decrypt(encryptedBytes, false);
Console.WriteLine(Encoding.UTF8.GetString(decryptedText));
}

The following is the main program, where we create an instance of the RSACryptoServiceProvider class and collect public and private keys. However, as we are encrypting and decrypting the message in the same method, a single set of public and private keys was used.

As part of this example, we perform both encryption and decryption. We can create multiple RSA providers and use their public-private keys for senders and receivers. You can create different console applications, one as a sender and the other as a receiver, and simulate a real-world scenario. For simplicity's sake, I have used one pair of public-private keys to perform operations:

static void Main(string[] args)
{
#region Digital Signatures
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
string publicKey = rsa.ToXmlString(false);
string pricateKey = rsa.ToXmlString(true);
EncryptDecryptHelper.DigitalSignatureSample(pricateKey, publicKey,"This is a sample text for Digital signatures");
#endregion

// Keep the console window open in debug mode.
System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}

Check the output by changing the input message and algorithms. However, as said earlier, you may need to take care of any syntactical changes before executing:

In a real-world scenario, suppose two entities are communicating via web services where such digital signatures are implemented. The sender will have a set of public and private keys, and the receiver will have public and private keys. Both parties should exchange their respective public keys to facilitate application communication.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.97.170