C# Basics: Symmetric Encryption with Rijndael

I often need to encrypt a string and then decrypt it. Sometimes its to move some value from one server to another without the benefit of SSL. So for the fifth installment of C# Basics, I’ll share the a generic version of a little encryption utility I’ve used many times and in many places.

Most Important: If you decide to use this code, be sure to change the key and vector text to something only you know. You might even want to use a hardware security module.

I like AES (formerly known as Rijndael, pronounced “rain-doll”) but you can pick your own algorithm. The code below will work with most of the .NET symmetric encryption algorithms.

using System;
using System.Security.Cryptography;
using System.Text;

namespace MyCrypt
{
  public static class Tokenizer
  {
    //create your own unique key and vector strings
    //maybe even lock them up and require a cert to get them out
    private const string keyText = @"The quick brown fox jumps";
    private const string vectorText = @"over the lazy dog.";
    private static byte[] key = null;
    private static byte[] vector = null;

    static Tokenizer()
    {
      key = GetMD5Hash(keyText);
      vector = GetMD5Hash(vectorText);
    }

    public static string Encrypt(string val)
    {
      if (string.IsNullOrWhiteSpace(val)) return null;
      RijndaelManaged rjm = new RijndaelManaged();
      rjm.KeySize = 128;
      rjm.BlockSize = 128;
      rjm.Key = key;
      rjm.IV = vector;
      byte[] input = Encoding.UTF8.GetBytes(val);
      byte[] output = rjm.CreateEncryptor()
        .TransformFinalBlock(input, 0, input.Length);
      string data = Convert.ToBase64String(output);
      return data;
    }

    public static string Decrypt(string val)
    {
      if (string.IsNullOrWhiteSpace(val)) return null;
      try
      {
        RijndaelManaged rjm = new RijndaelManaged();
        rjm.KeySize = 128;
        rjm.BlockSize = 128;
        rjm.Key = key;
        rjm.IV = vector;
        byte[] input = Convert.FromBase64String(val);
        byte[] output = rjm.CreateDecryptor()
          .TransformFinalBlock(input, 0, input.Length);
        string data = Encoding.UTF8.GetString(output);
        return data;
      }
      catch
      {
        return null;
      }
    }

    static byte[] GetMD5Hash(string data)
    {
      MD5 md5 = MD5CryptoServiceProvider.Create();
      return md5.ComputeHash(Encoding.UTF8.GetBytes(data));
    }
  }
}