Using Encryption in .NET

Conclusion

While we have left much about the field of cryptography unsaid, I hope that you've gained a good understanding of the basics of using the FCL classes for encryption. In summary, remember the following points:

  • Always use proven, public technology
  • Use Rijndael, if possible
  • Use 256-bit keys and blocks
  • Take care how you derive keys
  • Use PKCS7 padding in .NET 1.1, ISO10126 in .NET 2.0
  • Don't use ECB mode unless you have a good reason and know what you're doing
  • Always use a unique IV for each message
  • Take the time to be explicit in your code for important details, even when you're using defaults

Finally, here is the complete text of the CipherWrapper class we developed in this article. Keep in mind that this code is provided for demonstration purposes only. I designed the code for simplicity and illustration foremost and I typically write more complex crypto code to accomplish such goals as to make the classes thread safe and useable from multiple sessions. These details, in my view, do not contribute to the subject at hand, so they were omitted. That stated, this class puts to work all the principles covered by this article. Take some time to study the documentation for the SymmetricAlgorithm class, from which all the FCL ciphers derive, and the ICryptoTransform interface, particularly the overloads for the CreateEncryptor/Decryptor methods.

class CipherWrapper
{
  RijndaelManaged _cipher = null;
  public CipherWrapper()
  {
    _cipher = InitCipher();
  }
  public CipherWrapper(byte[] key)
  {
    _cipher = InitCipher(key);
  }
  public byte[] Key
  {
  get { return _cipher.Key;  }
  set { _cipher.Key = value; }
  }
  public byte[] EncryptMessage(byte[] plainText, out byte[] iv)
  {
    _cipher.GenerateIV();
    iv = _cipher.IV;
    ICryptoTransform transform = _cipher.CreateEncryptor();
    byte[] cipherText = transform.TransformFinalBlock(plainText, 0, plainText.Length);
    return cipherText;
  }
  public byte[] DecryptMessage(byte[] cipherText, byte[] iv)
  {
    _cipher.IV = iv;
    ICryptoTransform transform = _cipher.CreateDecryptor();
    byte[] plainText = transform.TransformFinalBlock(cipherText, 0, cipherText.Length);
    return plainText;
  }
  private RijndaelManaged InitCipher()
  {
    RijndaelManaged cipher = CreateCipher();
    cipher.GenerateKey();
    return cipher;
  }

  private RijndaelManaged InitCipher(byte[] key)
  {
    RijndaelManaged cipher = CreateCipher();
    cipher.Key = key;
    return cipher;
  }
  private RijndaelManaged CreateCipher()
  {
    RijndaelManaged cipher = new RijndaelManaged();
    cipher.KeySize  = 256;
    cipher.BlockSize = 256;
    cipher.Mode      = CipherMode.CBC;
    cipher.Padding  = PaddingMode.PKCS7;
    return cipher;
  }
}

Kudos

Many thanks to Keith Brown for his review of this article. Keith provided many helpful suggestions and corrections.

This article was originally published at DotNetDevs.com

You might also like...

Comments

About the author

Steve Johnson United States

Steve is a senior developer and consultant for 3t Systems, Inc. in Denver, CO, where he spends his days doing architecture, training, and "in-the-trenches" development. Steve began programming W...

Interested in writing for us? Find out more.

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“It works on my machine.” - Anonymous