2009/04/01

TripleDES String Encryption/Decryption (6/12/2011 updated)

Here is how I encrypt/decrypt string by using the TripleDES.
public string TripleDESforString(string rawString, string key, string IV, bool toEncrypt)
{
  try
  {
    //Create a PasswordDeriveBytes object and then create a TripleDES key from the password and salt.
    PasswordDeriveBytes oPasswordDeriveBytes = new PasswordDeriveBytes(key, Encoding.UTF8.GetBytes(FormatStringLength(IV, 8, '9')));
    TripleDESCryptoServiceProvider oTDES = new TripleDESCryptoServiceProvider();
    oTDES.Padding = PaddingMode.PKCS7;
    oTDES.Mode = CipherMode.CBC;
    //Create the key and set it to the Key property of the TripleDESCryptoServiceProvider object.
    //oTDES.Key = oPasswordDeriveBytes.CryptDeriveKey("TripleDES", "SHA1", 192, oPasswordDeriveBytes.Salt);
    oTDES.Key = oPasswordDeriveBytes.GetBytes(24);
    oTDES.IV = oPasswordDeriveBytes.GetBytes(8);

    byte[] data;
    byte[] result;
    if (toEncrypt)
    {
      data = Encoding.UTF8.GetBytes(rawString);
      result = oTDES.CreateEncryptor().TransformFinalBlock(data, 0, data.Length);
      oTDES.Clear();
      return Convert.ToBase64String(result);
    }
    else
    {
      data = Convert.FromBase64String(rawString);
      result = oTDES.CreateDecryptor().TransformFinalBlock(data, 0, data.Length);
      oTDES.Clear();
      return Encoding.UTF8.GetString(result);
    }
  }
  catch (CryptographicException cex)
  {
    return cex.Message;
  }
}
The TripleDES class will throw an Exception if you assign it with the weak key. The easy way to prevent this situation is to use the key that generated by the TripleDES itself.
public List<byte[]> TripleDESKeyGenerator()
{
  List<byte[]> lstResult = new List<byte[]>();
  TripleDES oTDES = TripleDESCryptoServiceProvider.Create();
  oTDES.GenerateKey();
  oTDES.GenerateIV();
  lstResult.Add(oTDES.Key);
  lstResult.Add(oTDES.IV);
  oTDES.Clear();
  return lstResult;
}


2/5/2010 updated:
Put on the FormatStringLength() method.
public static string FormatStringLength(string input, int requiredLength, char padding)
{
  if (input.Length < requiredLength)
    input = input.PadRight(requiredLength, padding);
  else if (input.Length > requiredLength)
    input = input.Substring(0, requiredLength);

  return input;
}

6/12/2011 updated:
Replaced the following line
oTDES.Key = oPasswordDeriveBytes.CryptDeriveKey("TripleDES", "SHA1", 192, oPasswordDeriveBytes.Salt);
with
oTDES.Key = oPasswordDeriveBytes.GetBytes(24);

2 comments:

  1. Nice articles on encryption. One thing I noticed was the use of FormatStringLength, I am not aware of this being in the .NET framework. Is this a function you wrote?

    ReplyDelete
  2. Hi Micheal,

    Thanks for reminding me about this mistake. I have put the missing method on the end of this article.

    You can remove the method without causing any error since the only purpose of it is to format the user input string (IV) so it can meet the length requirement.

    ReplyDelete