January 6th, 2009
Encrypting and Decrypting a C# string - 11
If you're new here, you may want to subscribe to my RSS feed. Thanks for visiting!
The .NET C# library provides all the basic elements for encrypting a string with a passphrase and decrypting it later. Doing this however requires a few steps in between. This post show a simple set of routines to help you do just that. We use the TripleDES encryption suite to do the actual encryption, with a little help from the MD5 hash sum generator.
The complete source code is listed below, but lets have a little look at how it works first.
The problem
I want to take a string, and then encrypt it using a password. The result should be a Base64 encoded string that I can store somewhere relatively safe.
// The message to encrypt.
string Msg = "This world is round, not flat, don't believe them!";
string Password = "secret";
string EncryptedString = EncryptString(Msg, Password);
string DecryptedString = DecryptString(EncryptedString, Password);
Console.WriteLine("Message: {0}",Msg);
Console.WriteLine("Password: {0}",Password);
Console.WriteLine("Encrypted string: {0}",EncryptedString);
Console.WriteLine("Decrypted string: {0}",DecryptedString);
In the EncryptString function we apply the TripleDES algorithm with a 128 bit key. But first we need to turn the above passphrase (‘secret’) into a 128 bit key. One useful coincidence is that the MD5 hash algorithm accepts a set of bytes of any length and turns them into a 128 bit hash. So by running the password through the MD5 hashing algorithm we create our key.
// Step 1. We hash the passphrase using MD5
// We use the MD5 hash generator as the result is a 128 bit byte array
// which is a valid length for the TripleDES encoder we use below
MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider();
byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(Passphrase));
The TripleDES algorithm itself turns a byte array into an encrypted byte array. So we first need to convert our C# message string (which is Unicode encoded) into a byte array through the System.Text.UTF8Encoding encoder.
The key is used to initialize the TripleDES algorithm. In addition we need to specify that we will only encode something once (CipherMode.ECB) and because its unlikely that our source string fits into a single TripleDES block we need to specify how we want to pad any remaining bytes (PaddingMode.PKCS7).
// Step 2. Create a new TripleDESCryptoServiceProvider object
TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider();
// Step 3. Setup the encoder
TDESAlgorithm.Key = TDESKey;
TDESAlgorithm.Mode = CipherMode.ECB;
TDESAlgorithm.Padding = PaddingMode.PKCS7;
The encrypted byte array is finally converted into a Base64 encoded string for easy storage. The DecryptString function is very similar to the encryption function, except that it turns the Base64 encoded encrypted message back into the original UTF8 string.
Drawbacks to the above method
To keep the code above straightforward we made use of the fact that an MD5 hash is exactly 128 bits in length. The C# TripleDES code accepts three possible key lengths: 64 bit, 128 bit and 192 bit. Only 192 bit keys are truly TripleDES, the 128 bit key length we obtain from the MD5 hash is only sufficient for Double DES. According to Wikipedia, that would make its real key strength only equivalent to 80 bits.
The Source code
using System;
using System.Text;
using System.Security.Cryptography;
namespace EncryptStringSample
{
class MainClass
{
public static string EncryptString(string Message, string Passphrase)
{
byte[] Results;
System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();
// Step 1. We hash the passphrase using MD5
// We use the MD5 hash generator as the result is a 128 bit byte array
// which is a valid length for the TripleDES encoder we use below
MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider();
byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(Passphrase));
// Step 2. Create a new TripleDESCryptoServiceProvider object
TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider();
// Step 3. Setup the encoder
TDESAlgorithm.Key = TDESKey;
TDESAlgorithm.Mode = CipherMode.ECB;
TDESAlgorithm.Padding = PaddingMode.PKCS7;
// Step 4. Convert the input string to a byte[]
byte[] DataToEncrypt = UTF8.GetBytes(Message);
// Step 5. Attempt to encrypt the string
try
{
ICryptoTransform Encryptor = TDESAlgorithm.CreateEncryptor();
Results = Encryptor.TransformFinalBlock(DataToEncrypt, 0, DataToEncrypt.Length);
}
finally
{
// Clear the TripleDes and Hashprovider services of any sensitive information
TDESAlgorithm.Clear();
HashProvider.Clear();
}
// Step 6. Return the encrypted string as a base64 encoded string
return Convert.ToBase64String(Results);
}
public static string DecryptString(string Message, string Passphrase)
{
byte[] Results;
System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();
// Step 1. We hash the passphrase using MD5
// We use the MD5 hash generator as the result is a 128 bit byte array
// which is a valid length for the TripleDES encoder we use below
MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider();
byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(Passphrase));
// Step 2. Create a new TripleDESCryptoServiceProvider object
TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider();
// Step 3. Setup the decoder
TDESAlgorithm.Key = TDESKey;
TDESAlgorithm.Mode = CipherMode.ECB;
TDESAlgorithm.Padding = PaddingMode.PKCS7;
// Step 4. Convert the input string to a byte[]
byte[] DataToDecrypt = Convert.FromBase64String(Message);
// Step 5. Attempt to decrypt the string
try
{
ICryptoTransform Decryptor = TDESAlgorithm.CreateDecryptor();
Results = Decryptor.TransformFinalBlock(DataToDecrypt, 0, DataToDecrypt.Length);
}
finally
{
// Clear the TripleDes and Hashprovider services of any sensitive information
TDESAlgorithm.Clear();
HashProvider.Clear();
}
// Step 6. Return the decrypted string in UTF8 format
return UTF8.GetString( Results );
}
public static void Main(string[] args)
{
// The message to encrypt.
string Msg = "This world is round, not flat, don't believe them!";
string Password = "secret";
string EncryptedString = EncryptString(Msg, Password);
string DecryptedString = DecryptString(EncryptedString, Password);
Console.WriteLine("Message: {0}",Msg);
Console.WriteLine("Password: {0}",Password);
Console.WriteLine("Encrypted string: {0}",EncryptedString);
Console.WriteLine("Decrypted string: {0}",DecryptedString);
}
}
}
Tags: decryption, encryption, Learn C#, md5, strings









Except where otherwise noted, content on this site is
December 1st, 2009 at 11:08 pm
thanks for the encrypt/decrypt lesson. thanks a lot. GOD Bless!
January 25th, 2010 at 3:33 am
Great example, just what I needed for encrypting a timestamp in a URL parameter. Just to confirm – the rendered string is always UTF-8 and thus safe for inclusion in a link, correct?
March 31st, 2010 at 3:09 am
Just as the last person said, this is an excellent demonstration of how to encrypt and decrypt strings. This one helped me with a fun little program where i wanted to encrypt a credit card number, thanks again!!!
August 10th, 2010 at 6:29 am
Thanks for the lesson and source code. While using the above codes I experience some errors decrypting some messages, especially when it contained some spaces. After searching the internets, I found a fix. Apparently when converting from a Base64 string to byte, it does not like the space in the message. I inserted this line of code, in between Step 3 and 4 for the decrypt method:
Message = Message.Replace(” “, “+”);
Hope this helps others who experience this issue.
September 11th, 2010 at 8:16 am
Thanks! Good to find simple encryption techniques for stings, as they are useful for keeping cookies private. Many other pages just deal with https instead of manually encrypting strings.
October 3rd, 2010 at 6:59 am
Hi,
Thanks for this tutorial it’s really good but sometimes I get this error:
// Step 4. Convert the input string to a byte[]
byte[] DataToDecrypt = Convert.FromBase64String(Message);
Invalid length for a Base-64 char array.
I tried it with this string “wwwrw”
secret string “jomaih”
Thank you,
November 6th, 2010 at 5:54 am
Thanks for the Post.
I started to get some errors when the encrypted message had a space character into.
After doing some research, it seems that the convert part in step 4 of the decryption method does not like spaces.
Before step 4, I replace the space to a “+”, according to other sources the plus sign is the same as a space and it works perfectly.
// Step 3. Setup the decoder
TDESAlgorithm.Key = TDESKey;
TDESAlgorithm.Mode = CipherMode.ECB;
TDESAlgorithm.Padding = PaddingMode.PKCS7;
//Fix for base64 error when message has a space, This is the line of code to add
Message = Message.Replace(” “, “+”);
// Step 4. Convert the input string to a byte[]
byte[] DataToDecrypt = Convert.FromBase64String(Message);
January 16th, 2011 at 6:06 pm
Thanks a lot for nice and easy to use functions.
January 23rd, 2011 at 1:32 pm
another issue that if message string contain special characters then Error occurs
Example: message=”ѳ÷YïÁ¡g/”;
Invalid character in a Base-64 string
// Step 4. Convert the input string to a byte[]
byte[] DataToDecrypt = Convert.FromBase64String(Message);
February 12th, 2011 at 1:44 am
Very useful information!!
March 17th, 2011 at 10:18 am
how to get passphase if i have encrypt and decrypt string??
Thanks alot