Last Updated on February 11, 2024


Nowadays, AES encryption is widely used around the world to protect private and confidential data.  Encryption is a cryptographic mechanism or process having for goal to encode information in a format that cannot be interpreted by humans or computers. In other words, encryption consists of transforming plain text data to ciphertext by using an encryption algorithm. AES is one of the most popular encryption algorithms on the internet.

As a C# developer, if you search about AES encryption on docs.microsoft.com, you will notice that there are many classes available in .NET for that purpose. In this article, we will talk about the Aes.Create method, which is the recommended way to create a cryptographic object that implements the AES algorithm.

What is AES encryption?

AES encryption is a symmetric encryption process announced in 2001 by the National Institute of Standards and Technology (NIST) as US FIPS 197.

Usually, an encryption process uses an encryption key to perform the data transformation and that key can either be symmetric or asymmetric. Basically, a symmetric encryption process uses a single key to encrypt and decrypt data, while an asymmetric encryption process uses a key pair (public and private keys). In essence, AES encryption uses a symmetric key to encrypt or decrypt data. Consequently, in order to decrypt a ciphertext, you need to have the same key that was used to encrypt the original data. That’s why the encryption key is considered a secret and needs to be stored in a safe place, like a key management system or service (i.e. KMS).

The following diagram gives an overview of the AES encryption process:

AES Encryption: Encryption process

In summary, the AES encryption algorithm uses a key and an initialization vector to encrypt the plain text data. The encryption mechanism will then perform the data transformation based on the selected cipher and padding mode. Then, at the end of this transformation, the algorithm will output a ciphertext that represents the encrypted data.

AES Encryption: Decryption process

Similarly, the decryption process takes the ciphertext in input and the same key and initialization vector used previously during the encryption process. By using the same configuration, the decryption process will be able to output the original plain text data.





AES Encryption Block Size

The AES encryption algorithm chunks the data by blocks and then performs the encryption block by block in an iteration. Fundamentally, it uses a fixed block size of 128-bit. If you are familiar with the Rijndael encryption algorithm, it’s important to know that AES is the equivalent of Rijndael with a fixed block size of 128-bit.  

AES Encryption Key

In the AES algorithm, the key size is important because there is a direct correlation between the key size and the strength of the algorithm. Basically, AES supports 3 different key sizes: 128-bit key, 192-bit key, and 256-bit key.

While reading AES documentation on the internet, you will sometimes notice that the key size is in the full name of the algorithm:

  • AES-128: refers to AES encryption with a 128-bit key size.
  • AES-192: refers to AES encryption with a 192-bit key size.
  • AES-256: refers to AES encryption with a 256-bit key size.

Today, it’s better to use either a 192-bit or a 256-bit key to get maximum protection of the data.

The initialization vector (IV)

As explained previously, the encryption process is done iteratively block by block, by using the encryption key. Therefore, it’s evident that without any other variable, the encryption of the first block will always give the same output if you are using the same plain text input and encryption key. In other words, there is a minor degree of predictability. That’s where the initialization vector (IV) comes into play. Since the output of a block transformation has an impact on the encryption of the next block, the initialization vector will be used to encrypt the first block.

To be effective, the initialization vector must be a random byte array as well. Therefore, it’s not a good idea to re-use the same initialization vector when encrypting data with the same key.  That adds a layer of randomization to the encryption process, which is great for security purposes. It ensures that every encryption of the same input gives a different ciphertext.

Furthermore, the initialization vector is required during decryption as well. So, both the AES encryption and decryption process need the key and the IV.

For most cipher modes, the initialization vector size must be the same as the block size. Therefore, the size of the IV is usually 128-bit like the block size.

NB: Some documentations use the terms IV and nonce interchangeably. The nonce term is usually preferred for CTR-related modes and authenticated encryption modes. We will not go into details about the difference between the 2 terms in this article.

What is a cipher mode of operation?

The cipher mode of operation determines the cryptographic algorithm that will perform the blocks’ transformation. Here are some of the cipher modes of operation that you can use with AES:

  • Electronic Codebook (ECB)
  • Cipher Block Chaining (CBC)
  • Output Feedback (OFB)
  • Cipher Text Stealing (CTS)
  • Counter Mode (CTR)
  • Cipher Feedback (CFB)
  • Galois/Counter Mode (GCM)
  • Counter with Cipher Block Chaining Message Authentication Code (CCM)

This is not the complete list of cipher modes available for AES. You can have more information or details about these modes of operation by doing a google search. There are many articles that explain the difference between these modes.

The most popular mode until now is the CBC mode and at the time of writing this article, it’s the selected mode by default in most programming libraries.

The most recent modes (GCM and CCM) are classified as authenticated encryption with associated data (AEAD). We will talk about these modes in another article because there is a significant difference between AES AEAD and a regular AES encryption mechanism.





AES Encryption in .NET

Microsoft recommends using the Aes.Create method to perform AES encryption with one of the traditional cipher modes (i.e. non-AEAD). The Aes.Create method is available since .NET Framework 3.5 and .NET core 2.0. It’s very simple and easy to use, and the CipherMode enum contains the list of available cipher modes. The default cipher mode is CBC.

NB: As you noticed, this enumeration does not contain the AEAD cipher modes (GCM, CCM). For AES encryption with an AEAD cipher mode, you need to use one of the specialized classes: AesCcm and AesGcm.

Encrypting Data with Aes.Create

The Aes class itself is an abstract class, so you cannot create a new instance by just calling the constructor. In fact, there are many implementations of the Aes class, so it’s better to let the Aes.Create method return the most adequate implementation of the AES algorithm depending on some variables, like the .NET version or the OS that you are targeting.

The following code sample uses the Aes.Create method to create an instance of the Aes class.

And executing this code gives the following output:

AES encrypt code sample output

Here is the text version of the output:

Welcome to the Aes Encryption Test tool
Please enter the text that you want to encrypt:
This is the aes test we did on siakabaro.com website.
Aes Cipher Mode : CBC
Aes Padding Mode: PKCS7
Aes Key Size : 256
Aes Block Size : 128
--------------------------------------------------------------
Here is the cipher text:
QAOjlcfnHZD1FVpvrSfmtab9zww/eeUGi0raqdKchdrJkZWIEblyc6eTBtC3IUsBMKCZx8E4q3G/nPWKvOMTyQ==
--------------------------------------------------------------
Here is the Aes key in Base64:
yJ4L5ouh5D1n9Yj53S+GkEt/+OW/bn10MfC/opJjZ5g=
--------------------------------------------------------------
Here is the Aes IV in Base64:
4ZttzHusKGsjzmdQA5+Viw==

As you noticed, the default key size is 256 and the default cipher mode is CBC.

In this example, we are displaying the key and the IV for educational purposes. In a real application used by customers, you should keep the key secret. Even though the vector is not a secret, it’s not wise to disclose it publicly either, like an RSA public key for example. In other words, you don’t need to store the IV in a key vault, but on the other extreme, you should not disclose it on a public website either. You can simply store the IV with the encrypted data directly or share it following the least privilege principle. Basically, only components that need to decrypt the data should have access to the vector and the key.

Also, remember that you should not re-use the same IV with the same key when encrypting data. Consequently, if you encrypt 2 files with the same AES key, you need to use 2 different initialization vectors.

Decrypting Data with Aes.Create

In order to decrypt the ciphertext, you need to be in possession of the key and IV. For that reason, after creating an instance of the Aes class with Aes.Create, we need to feed these 2 values to the object in order to perform the decryption with the right parameters.  

By using the same key and IV from the previous example, we can decrypt the ciphertext as shown in this screenshot:

AES decrypt code sample output





Conclusion

In conclusion, if you need to use AES encryption in .NET with one of the basic cipher modes (i.e. non-AEAD cipher modes), you can use the Aes.Create method. By doing so, you will let the system select the most adequate implementation of the Aes class depending on the platform and the .NET version that you are targeting.