Ebay - Advertisement

Tuesday, July 27, 2010

AES 256 Encryption & Decryption using C# - The short way

More organizations today understand that sensitive information should be stored encrypted in their repositories (Examples: user passwords, credit cards, SSN etc). Also there are regulations and security standards such as the PCI:DSS which requires the encryption of credit card numbers.
Thus, developers in such organizations encounter the issues of encryption frequently and are required to find appropriate solutions. There are a lot of ways to encrypt/decrypt information by using buld-in .NET libraries for encryption.
I decided to present you here the shortest way that i found for doing that.

The following code is an example of the short way to encrypt/decrypt data using AES algorithm.
Please notice that in this example i stored the encryption key in the code, but of course in the real life the key should be stored in a secure repository with appropriate ACL privileges.

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Security.Cryptography;

namespace aes3
{
    class aes3
    {
        static void Main(string[] args)
        {

           RijndaelManaged  AesEncryption = new RijndaelManaged();
           string plainStr = "AES me"; // The text that would be encrypted
           AesEncryption.KeySize = 256; // 192, 256
           AesEncryption.BlockSize = 128;
           AesEncryption.Mode = CipherMode.CBC;
           AesEncryption.Padding = PaddingMode.PKCS7;

           // The key should be generated prior and also should be stored in secure repository
            // with appropriate ACL priviledges.
           string keyStr = "cGFzc3dvcmQAAAAAAAAAAA==";
           string ivStr = "cGFzc3dvcmQAAAAAAAAAAA==";
           byte[] ivArr = Convert.FromBase64String(keyStr);
           byte[] keyArr = Convert.FromBase64String(ivStr);
           AesEncryption.IV = ivArr;  
           AesEncryption.Key = keyArr;
    
           // This array will contain the plain text in bytes
           byte[] plainText = ASCIIEncoding.UTF8.GetBytes(plainStr);

           // Creates Symmetric encryption and decryption objects   
           ICryptoTransform crypto = AesEncryption.CreateEncryptor();
           ICryptoTransform decrypto = AesEncryption.CreateDecryptor();
           // The result of the encrypion and decryption
           byte[] cipherText = crypto.TransformFinalBlock(plainText, 0, plainText.Length);
           byte[] decryptedText =  decrypto.TransformFinalBlock(cipherText,0,cipherText.Length);

            Console.Write("The plain text\"{0}\" in the encrypted format is:{1} \n",plainStr,Convert.ToBase64String(cipherText));
            Console.Write("The encrypted text \"{0}\" is decrypted to: {1}",Convert.ToBase64String(cipherText), ASCIIEncoding.UTF8.GetString(decryptedText));
            Console.Read();
        }
    }
}

3 comments:

  1. Yossi, thanks for posting but I should let you know this isn't production-ready. I like that you use the TransformFinalBlock method to write the transformed data - other examples online add unnecessary MemoryStreams and/or Cryptostreams, but you need to use a password-based key derivation function to create the hash and salt (PBKDF) for your RijndaelManaged/AesManaged instance. For example:
    ```

    // ...

    Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(password, 32, 10000); //use some sufficiently long and random password stored elsewhere

    AesEncryption.Key = key.GetBytes(32);
    AesEncryption.IV = key.GetBytes(16);
    //...
    ```
    More on this subject here - https://www.owasp.org/index.php/Using_Rfc2898DeriveBytes_for_PBKDF2.

    Then store the unique salt somewhere with the encrypted data for decrypting later. Many times this is a Salt column in the same data row as the encrypted data.

    ReplyDelete