Encryption and Decryption for Dummies in .NET

June 27th, 2007 by Sameer | Filed under .NET articles, Deconstructing Subtext.

I was trying to figure out the easiest way that I could encrypt some text for the application I was working on. I struggled for a bit to figure out what was the best way to perform encryption in .NET.  Having a piece of open source software that you can look at is very helpful, and I highly recommend it.  You will frequently run into problems that have been solved by others time and time again, and instead of trying to re-invent the wheel, it would be in your best interests to have this toolbelt of code that you are familiar with, and that you can look up.

The software that this site runs on is called Subtext.  You can download the source code or the compiled version and take a look inside at the source code to get some ideas and learn from the experience of those more experienced than you and I.

Encryption is a massive topic and I am not even going to scratch the surface of it, but the code that follows is a simple example of how you can use it.

This code demonstrates a very easy way to Encrypt and Decrypt using Rinjdael’s (AES) algorithm.

It first creates an instance of the algorithm, followed by a method that uses our instance to Encrypt, and another that uses our instance to Decrypt. 

        static SymmetricAlgorithm encryptionAlgorithm = InitializeEncryptionAlgorithm();

        static SymmetricAlgorithm InitializeEncryptionAlgorithm()
        {
            SymmetricAlgorithm rijaendel = RijndaelManaged.Create();
            rijaendel.GenerateKey();
            rijaendel.GenerateIV();
            return rijaendel;
        }

        /// <summary>
        /// Encrypts the string and returns a base64 encoded encrypted string.
        /// </summary>
        /// <param name="clearText">The clear text.</param>
        /// <returns></returns>
        public static string EncryptString(string clearText)
        {
            byte[] clearTextBytes = Encoding.UTF8.GetBytes(clearText);
            byte[] encrypted = encryptionAlgorithm.CreateEncryptor().TransformFinalBlock(clearTextBytes, 0, clearTextBytes.Length);
            return Convert.ToBase64String(encrypted);
        }

        /// <summary>
        /// Decrypts the base64 encrypted string and returns the cleartext.
        /// </summary>
        /// <param name="encryptedEncodedText">The clear text.</param>
        /// <exception type="System.Security.Cryptography.CryptographicException">Thrown the string to be decrypted
        /// was encrypted using a different encryptor (for example, if we recompile and
        /// receive an old string).</exception>
        /// <returns></returns>
        public static string DecryptString(string encryptedEncodedText)
        {
            try
            {
                byte[] encryptedBytes = Convert.FromBase64String(encryptedEncodedText);
                byte[] decryptedBytes = encryptionAlgorithm.CreateDecryptor().TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length);
                return Encoding.UTF8.GetString(decryptedBytes);
            }
            catch (FormatException fe)
            {
                //throw new CaptchaExpiredException("Encrypted encoded text '" + encryptedEncodedText + "' was not valid.", fe);
            }
            catch (CryptographicException e)
            {
                //throw new CaptchaExpiredException("Captcha image expired, probably due to recompile making the key out of synch.", e);
            }
        }

As you can see, all you need is a few methods like this, and you have .NET encryption.  To encrypt data, simply call EncryptString("your string"), and to decrypt data, simply call DecryptString(encryptedString).  I commented out the exceptions, you will need to re-implement them as you like.  Or you can just leave it crashing ;)

Source from SubText-1.9.5-source\Subtext.Web.Controls\Captcha\CaptchaBase.cs

This code is licensed with the new BSD template - Open Source baby!

Update (July 10, 2007)
This method will create a random key every time the application restarts, which may not be what you want.  If this is the case, you can hardcode the key and IV values so that it will always be the same:

        rijaendel.Key = Convert.FromBase64String("HUfIj72qL4OnPu1OlMBKqoufdLSw/nOsIrJiSr+lRgg=");
        rijaendel.IV = Convert.FromBase64String("p1D5hkd4xa5kyX6O7ZXR2A==");

How did I get these values?  You don’t want to use these, but you can generate these values using the built in method above (InitializeEncryptionAlgorithm), and then store it as a string by running Convert.ToBase64String(keyValue)

Read "Better Captcha Through Encryption" for more details on how this code was implemented.

Another option is to set your machineKey value in your web.config

Update: Here is another slightly more optimized way to hardcore your Key and IV. Keep in mind this is not the most secure way, anyone can easily use Reflector on your DLL and get the Key and IV.

            rijaendel.IV = new Byte[] { 56, 151, 249, 160, 183, 47, 5, 42, 90, 5, 207, 241, 11, 166, 166, 173 };
            rijaendel.Key = new Byte[] { 214, 145, 104, 41, 148, 129, 139, 16, 224, 38, 40, 15, 5, 254, 217, 193, 146, 43, 187, 174, 132, 181, 220, 211, 228, 181, 153, 173, 239, 194, 45, 253 };

You shouldn’t use those exact values, but run the debugger and grab new values from GenerateKey() and GenerateIV(). This is more optimized because the values don’t have to be converted back into bytes.

Other Interesting Posts

2 Responses to “Encryption and Decryption for Dummies in .NET”

  1. Waleed Eissa says:

    Thanks a lot for the great post, I’ve been searching for a simple way to encrypt/decrypt strings and I think the code here will help me a lot …

  2. Sameer says:

    You are welcome. Keep in mind the limits of using this method (hardcoded values)…

Leave a Reply