Monthly Archives: March 2008

In this part we are going to learn how to ensure that data coming to you has not been tampered with during the transfer. The technique that we will be using is hash. Hash values allow us to verify the integrity of data. The hash value of received data can be compared to the hash value of data that was sent to check if the data is tampered.

.NET Framework classes for creating hashes

.NET Framework provides following main classes to work with hashes:

SHA1Managed

MD5CryptoServiceProvider

MACTripleDES

Since SHA1 is now a broken algorithm, we will use MD5CryptoServiceProvider to generate hash values.

ExampleWe are going to create a helper class that will help us create and verify hash values using MD5 algorithm. The class contains two methods – GetHash() and VerifyHash(). The former accepts string whose hash value is to be generated and returns the computed hash as a byte array. The later accepts the message as it was received and the hash generated previously and returns true if the message is not altered during transmit otherwise returns false.

MD5HashHelper.cs

C#

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

publicclassMD5HashHelper

{

publicbyte[]GetHash(stringmessage)

{

byte[]data;

data=System.Text.UTF8Encoding.ASCII.GetBytes(message);

MD5CryptoServiceProvider md5=newMD5CryptoServiceProvider();

returnmd5.ComputeHash(data,0,data.Length);

}

publicboolVerifyHash(stringmessage,byte[]hash)

{

byte[]data;

data=System.Text.UTF8Encoding.ASCII.GetBytes(message);

MD5CryptoServiceProvider md5=newMD5CryptoServiceProvider();

byte[]hashtemp=md5.ComputeHash(data,0,data.Length);

for(intx=0;x<hash.Length;x++)

{

if(hash[x]!=hashtemp[x])

{

returnfalse;

}

}

returntrue;

}

}

Let’s dissect the code step by step:

We first need to import System.Security.Cryptography namespace in your class

The GetHash() accepts string whose hash value is to be generated and returns the computed hash as a byte array.

Inside the function we used UTF8Encoding class and get a byte representation of the string to be transferred.

We then create an instance of MD5CryptoServiceProvider class and call it’s ComputeHash by passing the byte created above to it.

The ComputeHash() function generates the hash for the given data and returns another byte array that represents the hash value of the data.

The VerifyHash() function accepts the message as it was received and the hash generated previously and returns true if the message is not altered during transmit otherwise returns false.

Inside this function we again use UTF8Encoding class and generate byte representation of the received message.

We then compute hash for this data using the same ComputeHash() method of MD5CryptoServiceProvider class.

Finally, we run a for loop and check each and every byte of original hash value and the hash we generated above. If both the hash values are matching we can conclude that the data is not tampered.

Introduction

Data encrypted by public key can be decrypted only by the corresponding private key and vice a versa. One of the most popular algorithm for encrypting and decrypting data using this technique is RSA. The acronym RSA stands for Rivest, Shamir, and Adelman who are the inventors of the technique. The .NET framework provides a class called RSACryptoServiceProvider that encapsulates this algorithm. In this article we are going to learn how to use this class to secure your data.

Developing a class for encryption and decryption

Many developers don’t want to go into the internals of Cryptography. They simply need a quick and easy way to secure their data. So we are going to develop such reusable class that will do the job of encrypting and decrypting for us.

We will create a class called PublicKeySecurityHelper which will have two methods – Encrypt and Decrypt. In addition we will also create a helper class called MyRSAInfo. This class will simply store certain pieces of data (such as public key and private key).

Encrypting data

First we import the required namespaces. Especially System.Security.Cryptography is important one because it contains our core class RSACryptoServiceProvider.

We create a method called Encrypt() that accepts the string to be encrypted and returns an instance of a class called RSAInfo.

RSAInfo is our custom class defined at the bottom of the code. It consists of four public members – PublicKey, PrivateKey, Parameters and Data.

The PublicKey and PrivateKey members store the generated public key and private key respectively.

The Parameters variable is of type CspParameters. This is used to automatically generate public and private keys and reuse them later on.

The Data is an array of bytes and stores the encrypted version of the data

Inside the Encrypt() method we create an instance of CspParameters class and set its Flag property to CspProviderFlags.UseMachineKeyStore. This enumerated value specifies from where the key information should be picked up i.e. from default key container or from machine level key store.

Then we create new instance of RSACryptoServiceProvider class passing the CspParameters instance.

We then call Encrypt() method of RSACryptoServiceProvider class and pass data to be encrypted. Since this parameter is byte array we convert our string into byte array using GetBytes() method. The second parameter of the method indicates whether to use OAEP padding (true) or PKCS#1 v1.5 padding (false). The former can be used only on Windows XP machines and hence we pass False. The Encrypt() method of RSACryptoServiceProvider class returns a byte array that contains encrypted version of the data.

Finally, we fill all the members of RSAInfo class and return to the caller. Note how we call ToXmlString() method first passing False and then passing True to get public and private keys respectively.

Decrypting data

In order to decrypt the data we create a method called Decrypt() that accepts an instance of RSAInfo class. This instance must be the one returned by the Encrypt() method explained earlier.

Inside Decrypt() method we create an instance of RSACryptoServiceProviderclass again passing the same CspParameters.

We then call FromXmlString() method of the RSACryptoServiceProvider class and pass the private key generated before. More details here.

Finally, we call Decrypt() method of RSACryptoServiceProvider class and pass the encrypted data. The second parameter of Decrypt method has the same significance as that of the corresponding parameter of Encrypt() method

Summary

Public key encryption is a secure way to transfer data over networks. The fact that the private key is not sent in unsafe manner makes it more secure and robust. This technique is used in Secure Socket Layer (SSL) or HTTPS based web sites. The .NET framework class RSACryptoServiceProvider allows you to generate public and private keys, encrypt and decrypt data.