String Encryption and Decryption in C# using AES

In this tutorial, we will explore how to encrypt and decrypt strings in C# using the Advanced Encryption Standard (AES) algorithm. AES is a widely used symmetric-key block cipher that provides secure encryption and decryption of data.

Introduction to AES

The Advanced Encryption Standard (AES) is a specification for the encryption of electronic data established by the National Institute of Standards and Technology (NIST). It is a symmetric-key block cipher, which means that it uses the same key for both encryption and decryption. AES is widely used due to its high security, efficiency, and flexibility.

Key Concepts

Before we dive into the code, let’s cover some essential concepts:

  • Symmetric-key: Both the sender and receiver use the same secret key for encryption and decryption.
  • Block cipher: Data is divided into fixed-length blocks, and each block is encrypted independently.
  • Key derivation: A process that generates a cryptographic key from a password or passphrase.

Encrypting Strings with AES

To encrypt a string using AES, we need to follow these steps:

  1. Generate a key from a password or passphrase using a key derivation function (KDF).
  2. Create an instance of the RijndaelManaged class, which is a .NET implementation of AES.
  3. Set the key and initialization vector (IV) for the encryption process.
  4. Convert the string to be encrypted into a byte array.
  5. Encrypt the byte array using the CryptoStream class.

Here’s an example code snippet that demonstrates how to encrypt a string:

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

public static string EncryptStringAES(string plainText, string sharedSecret)
{
    if (string.IsNullOrEmpty(plainText))
        throw new ArgumentNullException("plainText");
    if (string.IsNullOrEmpty(sharedSecret))
        throw new ArgumentNullException("sharedSecret");

    // Generate the key from the shared secret and a salt
    Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(sharedSecret, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });

    // Create a RijndaelManaged object
    using (RijndaelManaged aesAlg = new RijndaelManaged())
    {
        aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8);

        // Create an encryptor to perform the stream transform.
        ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

        // Create the streams used for encryption.
        using (MemoryStream msEncrypt = new MemoryStream())
        {
            // Prepend the IV
            msEncrypt.Write(BitConverter.GetBytes(aesAlg.IV.Length), 0, sizeof(int));
            msEncrypt.Write(aesAlg.IV, 0, aesAlg.IV.Length);

            using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
            {
                using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                {
                    // Write all data to the stream.
                    swEncrypt.Write(plainText);
                }
            }

            return Convert.ToBase64String(msEncrypt.ToArray());
        }
    }
}

Decrypting Strings with AES

To decrypt a string that was encrypted using AES, we need to follow these steps:

  1. Generate a key from a password or passphrase using the same KDF used for encryption.
  2. Create an instance of the RijndaelManaged class.
  3. Set the key and IV for the decryption process.
  4. Convert the encrypted string into a byte array.
  5. Decrypt the byte array using the CryptoStream class.

Here’s an example code snippet that demonstrates how to decrypt a string:

public static string DecryptStringAES(string cipherText, string sharedSecret)
{
    if (string.IsNullOrEmpty(cipherText))
        throw new ArgumentNullException("cipherText");
    if (string.IsNullOrEmpty(sharedSecret))
        throw new ArgumentNullException("sharedSecret");

    // Generate the key from the shared secret and a salt
    Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(sharedSecret, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });

    // Create a RijndaelManaged object
    using (RijndaelManaged aesAlg = new RijndaelManaged())
    {
        aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8);

        // Get the initialization vector from the encrypted stream
        byte[] bytes = Convert.FromBase64String(cipherText);
        using (MemoryStream msDecrypt = new MemoryStream(bytes))
        {
            int ivLength = BitConverter.ToInt32(msDecrypt.ToArray(), 0);
            byte[] iv = new byte[ivLength];
            msDecrypt.Read(iv, 0, iv.Length);
            aesAlg.IV = iv;

            // Create a decrytor to perform the stream transform.
            ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);

            using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
            {
                using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                {
                    return srDecrypt.ReadToEnd();
                }
            }
        }
    }
}

Best Practices and Security Considerations

When using AES for encryption and decryption, keep the following best practices and security considerations in mind:

  • Use a secure password or passphrase to generate the key.
  • Use a salt value to prevent rainbow table attacks.
  • Use a sufficient work factor when generating the key to slow down the key derivation process.
  • Store the encrypted data securely, such as using a secure database or file system.
  • Limit access to the encryption and decryption keys.

By following these best practices and security considerations, you can ensure that your AES encryption and decryption implementation is secure and reliable.

Leave a Reply

Your email address will not be published. Required fields are marked *