Sunday, December 3, 2006

TripleDES Encryption in .NET

Encryption of sensitive data is very important in most of the software applications today. In this feed I’ll show you how to encrypt and decrypt a string data using the encryption classes contained within .NET. The method I’m going to employ here is a “private-key” algorithm that uses one key to encrypt and the same key to decrypt the data. I’ll be using the TripleDES encryption algorithm which is considered to be very secure. It performs three times as much encryption as the standard DES.

DES, Data Encryption Standard, encrypts data using 64-bit or 8-byte blocks and employs 16 rounds of encryption to every block of data. It uses a key size of 56 bits, 8 bits reduced from 64 bits which serve as parity bits. As mentioned earlier, TripleDES, which performs 3 times the encryption as DES requires 168-bit key and encrypts each block three times. That is, each block of data is actually encrypted 48 times, making TripleDES more secure.

In this example, instead of using a 24-byte private key directly, I’m converting a pass phrase into a TripleDES key using the Hash Computation algorithm found in MD5CryptoServiceProvider class. I am doing this because the pass phrase makes more sense when you want to share the private key among those whom you want to share your secure data with. You definitely don’t want to memorize a private key of this kind {12, 26, 13, 44, 95,16,17,38,29, 10, 11, 22, 43, 24, 15, 56, 37, 78, 29, 27, 23, 52, 43, 4} to decrypt or encrypt your data.

Let’s look at the code now. To begin with, we’ll add a few namespaces.

using System;
using System.Text;
using System.Security.Cryptography;
Add an initialization vector as the private member of that class. 
private string Key = "";
private readonly byte[] IVector = new byte[8] { 27, 9, 45, 27, 0, 72, 171, 54 };

An initialization vector is used to mask the encryption method in private-key algorithms as they are known to process data in blocks. In most general terms, a block cipher will move to the next block after encrypting each block of data using the same key. Say, if the alternate block has the same data, then the encrypted equivalent also would be having the same encrypted data because they were encrypted with the same key. An initialization vector, in combination with the private key, uses the previous block’s information in encrypting subsequent blocks thereby generating different encrypted data even though they’re the same.

The above initialization vector contains 8 bytes. This can be replaced with your choice. Take a look at the Encrypt Method.

 
private string Encrypt(string inputString)
{

    byte[] buffer = Encoding.ASCII.GetBytes(inputString);
    TripleDESCryptoServiceProvider tripleDes = new TripleDESCryptoServiceProvider();
    MD5CryptoServiceProvider MD5 = new MD5CryptoServiceProvider();
    tripleDes.Key = MD5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(Key));
    tripleDes.IV = IVector;
    ICryptoTransform ITransform = tripleDes.CreateEncryptor();        
    return Convert.ToBase64String(ITransform.TransformFinalBlock(buffer, 0, buffer.Length));
}

I’m first converting the plain text string to a byte Array since many cryptographic methods expect the data to be in this format. I’m then instantiating couple of objects, firstly, TripleDESCryptoServiceProvider which accepts the initialization vector and the private key, and secondly, MD5CryptoServiceProvider which is used to compute the Hash and create a valid TripleDES private key from the Pass Phrase that I was telling you about. The ICryptoTransform defines the basic operations of cryptographic transformations. The TransformFinalBlock method transforms the input byte array into an encrypted byte array by applying the private key and the initialization vector. This is finally converted into a Base64String and returns the encrypted string to the calling method.

The process of decrypting the data is very much similar to encrypting the data because they use exactly the same private key. The Decrypt method shown below does the decryption process.

 
private string Decrypt(string inputString)
{
    byte[] buffer = Convert.FromBase64String(inputString);
    TripleDESCryptoServiceProvider tripleDes = new TripleDESCryptoServiceProvider();
    MD5CryptoServiceProvider MD5 = new MD5CryptoServiceProvider();
    tripleDes.Key = MD5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(Key));
    tripleDes.IV = IVector;
    ICryptoTransform ITransform = tripleDes.CreateDecryptor();
    return Encoding.ASCII.GetString(ITransform.TransformFinalBlock(buffer, 0, buffer.Length));
}

This completes the encryption/decryption process of a string data by employing the classes and methods contained in the System.Security.Cryptography namespace. The screenshots of the sample application that I created is shown below.

You can create your own Encryptor/Decryptor class library with these methods and develop more secure enterprise applications. Some of the areas of interest would be like encrypting the Passwords before saving it to the database or encrypting the QueryStrings in your web applications.

Hope this was helpful….

3 comments:

Anonymous said...

Thank you very much. This is the first sample I could find that compiled and worked.

Robert said...

Thanks - your decrypt method was exactly what I was looking for.

Jon S said...

Brilliant thanks very much. very simple and easy to understand. transfer the code in vb.net.


(just replace your key and IV with my constant ones and your away!)
***********
Public Function encryptString(ByVal str As String) As String
'//Create a new RSA key. This key will encrypt a symmetric key,
'//which will then be imbedded in the XML document.

'//Get a byte array of the str as encryption works on byte blocks
Dim enc As New ASCIIEncoding
Dim byteData() As Byte = enc.GetBytes(str)

'//Create encryption object
Dim tDes As New TripleDESCryptoServiceProvider()

'//Specify Initialisation Vector as encryption key to use
tDes.IV = IVECTOR
tDes.Key = UNIVERAL_KEY_192

'//Adds key and IVector to Encrypt object
Dim ITransform As CryptoAPITransform
ITransform = tDes.CreateEncryptor()

Return Convert.ToBase64String(ITransform.TransformFinalBlock(byteData, 0, byteData.Length))

End Function

Public Function decryptString(ByVal base64_str As String) As String
'//Perform as decrypt of encytpted data with above method

'//Get byte array from string
Dim encData() As Byte = Convert.FromBase64String(base64_str)

'//Create encryption object
Dim tDes As New TripleDESCryptoServiceProvider()

'//Specify Initialisation Vector as encryption key to use
tDes.IV = IVECTOR
tDes.Key = UNIVERAL_KEY_192

'//Adds key and IVector to decrypt object
Dim ITransform As CryptoAPITransform
ITransform = tDes.CreateDecryptor()

Return Encoding.ASCII.GetString(ITransform.TransformFinalBlock(encData, 0, encData.Length()))
End Function
**********

Regards Jon