AES (Advanced Encryption Standard) is a widely adopted symmetric encryption algorithm designed to securely encrypt and decrypt data. This article provides an overview of AES, its applications, and a practical example of integrating AES encryption into a C# application.
The purpose of this article is to provide an example of application integration by explaining the basic knowledge and theory of AES.
AES (Advanced Encryption Standard) is a widely used symmetric encryption algorithm today. In 1997, the U.S. National Institute of Standards and Technology (NIST) organized a competition to replace the previous standard, Data Encryption Standard (DES). The Rijndael algorithm, which won the competition, was named AES and became an official standard in 2001. AES is used to securely encrypt and decrypt data, protecting against unauthorized access.
What is AES and Why is it Used?
AES (Advanced Encryption Standard) is a block cipher used for encrypting fixed-size data blocks (128 bits). It supports three different key sizes: 128, 192, and 256 bits. This allows users to choose different security levels according to their needs. One of the major advantages of AES over DES (Data Encryption Standard) is that it is much more difficult to break. This is a key reason why AES remains unbroken to this day.
Where is AES used?
AES is used in various fields, from financial transactions to the protection of state secrets. For example, online banking, mobile payments, wireless network security (WPA2), and many modern VPN technologies are based on AES encryption. Additionally, AES is preferred to securely store patient records wherever personal data needs to be protected, for example in the healthcare industry.
Is There Any Better and Why Should It Be Preferred?
The reliability and effectiveness of AES have been subjected to many tests and analyses over the years. Today, it is considered one of the most reliable encryption standards due to its practical lack of breakability. Other algorithms can replace AES (for example, Serpent or Twofish), and these algorithms also offer similar levels of security as AES. However, AES’s widespread acceptance, high performance, and ease of implementation across a variety of platforms make it the most preferred encryption standard.
The development of quantum computers may present new challenges for symmetric encryption algorithms in the future. However, based on current information, AES-256 is still considered secure against quantum attacks. Therefore, AES should be preferred as a strong and flexible encryption standard that meets modern security requirements.
AES Architecture
AES (Advanced Encryption Standard) is a symmetric block cipher algorithm that encrypts fixed-length blocks of data (128 bits). AES uses the same key to encrypt and decrypt data. Key sizes can be 128, 192, and 256 bits, leading to three different levels of security called AES-128, AES-192, and AES-256. AES’s architecture is based on block ciphering, key expansion, and a round-robin transaction structure.
Block Cipher
AES operates on 128-bit blocks of data. The input block is converted into a 4×4 matrix; This matrix is called the ‘case’ that the algorithm will handle. Each cell contains 8 bits (1 byte) of data, making 128 bits in total.
Key Expansion
AES expands the key material for use in multiple rounds during encryption. Depending on the key size (128, 192, or 256 bits), AES uses different numbers of rounds (10, 12, or 14 rounds respectively). During the key expansion process, the original key is expanded to produce a unique round key for each round. These types of keys are used during encryption and decryption operations.
Trading Rounds
Each round consists of four basic operations: SubBytes, ShiftRows, MixColumns, and AddRoundKey. The decryption process involves the inverse of these operations and is applied in reverse order.
SubBytes (Byte Substitution): Each byte is replaced by another byte using a substitution table (S-box). This process breaks the linearity of the algorithm and increases security.
ShiftRows: Each row of the state matrix is shifted to the left a certain number of positions. This process provides better mixing of the data within the block.
MixColumns: Each column is subjected to a mathematical transformation. This process helps further distribute the data within the block. The MixColumns operation is applied in every round except the last round.
AddRoundKey: The round key obtained from the expanded key is combined with the state matrix using the XOR operation. This process ensures that data is encrypted at each round.
Decoding
AES decryption is the reverse of encryption and uses reverse order operations: InvShiftRows, InvSubBytes, InvMixColumns, and AddRoundKey (AddRoundKey is the same in encryption and decryption). Each process is carefully designed to return encrypted data to its original state.
The strengths of AES come from the breaking of linearity in the S-box design, the integration of tour switches, and the complexity of transformations performed on the state matrix. These features make AES highly resistant to analytical attacks.
Why can’t AES encryption be cracked?
There are several reasons why AES (Advanced Encryption Standard) encryption is considered “unbreakable” today. However, no encryption method is theoretically unbreakable; The reasons why AES is so difficult to crack are based on the mathematical complexity of its design and the level of security in the key sizes used. We can list the main elements that make AES encryption strong as follows:
High Key Sizes: AES offers three different key sizes: 128, 192 and 256 bits. Each of these keys increases the number of combinations that need to be broken. For example, AES with a 256-bit key, 2²⁵⁶ (approximately 1.1×10⁷⁷) offers different key combinations. This is a number that is practically impossible to break with current and foreseeable future computer technology.
Complex Algorithm Structure: AES is based on the Rijndael algorithm and involves a series of complex mathematical operations. These operations include byte substitution (SubBytes), row shifting (ShiftRows), column shuffling (MixColumns), and adding a round key (AddRoundKey). Each of these processes makes it difficult to analyze encrypted data and guess the key.
Multiple Rounds of Encryption: AES encrypts data in 10, 12 or 14 rounds, depending on the key size. Each round performs a series of transformations on the data, and the security of each transformation is added to the previous one. These multiple rounds increase the security of AES and ensure its resistance to cryptanalytic attacks.
Extensive Testing and Analysis: AES was extensively tested and analyzed before being selected by NIST to replace DES. These tests by cryptographers have shown that AES is secure against many known types of attacks. These attacks include linear and differential cryptanalysis.
Quantum Resistance: For now, quantum computers theoretically have the potential to break some encryption methods. However, AES-256 is thought to have strong resistance even to quantum computers. Since quantum computing technology does not yet pose a practical threat, AES remains secure enough to meet modern security requirements.
Integration with C#
First of all, we define the environment variable below. Properties/launchSettings.json
{
"profiles": {
"data-encryption": {
"commandName": "Project",
"environmentVariables": {
"APP_ENCRYPTION_SECRET_KEY": "7ed64fb158a74476bef0e0c565c9be51"
}
}
}
}
We define the AesExample.cs class to perform operations
using System.Security.Cryptography;
using System.Text;
namespace data_encryption
{
public static class AesExample
{
private static string PrivateKey
{
get
{
var key = "3fb7fe5dbb0643caa984f53de6fffd0f";
const string envVarName = "APP_ENCRYPTION_SECRET_KEY";
var envKeyValue = Environment.GetEnvironmentVariable(envVarName);
if (envKeyValue != null)
{
key = envKeyValue;
}
return key;
}
}
public static string Decrypt(string cipherText, string publicKey)
{
if (cipherText is not { Length: > 0 })
throw new ArgumentNullException(nameof(cipherText));
if (PrivateKey is not { Length: > 0 })
throw new ArgumentNullException(nameof(PrivateKey));
if (publicKey is not { Length: > 0 })
throw new ArgumentNullException(nameof(publicKey));
using var aesAlg = Aes.Create();
aesAlg.Mode = CipherMode.CBC;
aesAlg.Key = CreateAesKey(PrivateKey);
aesAlg.IV = Convert.FromBase64String(publicKey);
var decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
using var msDecrypt = new MemoryStream(Convert.FromBase64String(cipherText));
using var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read);
using var srDecrypt = new StreamReader(csDecrypt);
var plaintext = srDecrypt.ReadToEnd();
return plaintext;
}
public static string Encrypt(string plainText, string publicKey)
{
if (plainText is not { Length: > 0 })
throw new ArgumentNullException(nameof(plainText));
if (PrivateKey is not { Length: > 0 })
throw new ArgumentNullException(nameof(PrivateKey));
if (publicKey is not { Length: > 0 })
throw new ArgumentNullException(nameof(publicKey));
byte[] encrypted;
using (var aesAlg = Aes.Create())
{
aesAlg.Mode = CipherMode.CBC;
aesAlg.Key = CreateAesKey(PrivateKey);
aesAlg.IV = Convert.FromBase64String(publicKey);
//aesAlg.GenerateKey();
//aesAlg.GenerateIV();
var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
using (var msEncrypt = new MemoryStream())
{
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (var swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
return Convert.ToBase64String(encrypted);
}
public static byte[] GenerateRandomPublicKey()
{
var iv = new byte[16]; // AES > IV > 128 bit
iv = RandomNumberGenerator.GetBytes(iv.Length);
return iv;
}
private static byte[] CreateAesKey(string inputString)
{
return Encoding.UTF8.GetByteCount(inputString) == 32 ? Encoding.UTF8.GetBytes(inputString) : SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(inputString));
}
}
}
and the last stage using on Program.cs
using data_encryption;
var original = "Here is some data to encrypt!";
var publicKey = Convert.ToBase64String(AesExample.GenerateRandomPublicKey());
var encrypted = AesExample.Encrypt(original, publicKey);
var roundtrip = AesExample.Decrypt(encrypted, publicKey);
Console.WriteLine("Original : {0}", original);
Console.WriteLine("Public Key : {0}", publicKey);
Console.WriteLine("Encrypted (b64) : {0}", encrypted);
Console.WriteLine("Decrypted : {0}", roundtrip);
Result
Original : Here is some data to encrypt!
Public Key : B+lFBxE3eqf/r6VS8EPApA==
Encrypted (b64) : dRGFNZldQKDVvBP9aMsSSWcT218XsX9YusiYM4kbulk=
Decrypted : Here is some data to encrypt!
If the article was useful to you and you liked it, you can clap and/or follow to understand that you liked my article. 🙂
If you want to access the GitHub Project, You can use the https://github.com/cemalcanakgul/data-encryption