AES (Advanced Encryption Standard) is a strong encryption and decryption algorithm and more secure than its predecessors DES (Data Encryption Standard) and 3DES (Triple-DES). Since AES Encryption is an Symmetric algorithm we will be using the same Secret Key for both Encryption as well as Decryption.
In this article, we will be discussing about AES (Advanced Encryption Standard) Symmetric Encryption algorithm in Java with CBC mode (Cipher Block Chaining).
What is AES Encryption?
Advanced Encryption Standard (AES), also known by its original name Rijndael is a specification for the encryption of electronic data established by the U.S. National Institute of Standards and Technology (NIST) in 2001 according to Wikipedia.
AES supports key lengths of 128, 192 and 256 bit. AES comprises of 3 block ciphers AES-128, AES-192 and AES-256, each cipher encrypts and decrypts the data in the block of 128 bits using the secret key of 128, 192 and 256 bits respectively.
Java AES Encryption Example
package com.javainterviewpoint; import java.security.SecureRandom; import java.util.Base64; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public class AES_Encryption { static String plainText = "This is a plain text which need to be encrypted by AES Algorithm with CBC Mode"; public static void main(String[] args) throws Exception { KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); keyGenerator.init(128); // Generate Key SecretKey key = keyGenerator.generateKey(); // Generating IV. byte[] IV = new byte[16]; SecureRandom random = new SecureRandom(); random.nextBytes(IV); System.out.println("Original Text : "+plainText); byte[] cipherText = encrypt(plainText.getBytes(),key, IV); System.out.println("Encrypted Text : "+Base64.getEncoder().encodeToString(cipherText) ); String decryptedText = decrypt(cipherText,key, IV); System.out.println("DeCrypted Text : "+decryptedText); } public static byte[] encrypt (byte[] plaintext,SecretKey key,byte[] IV ) throws Exception { //Get Cipher Instance Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); //Create SecretKeySpec SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "AES"); //Create IvParameterSpec IvParameterSpec ivSpec = new IvParameterSpec(IV); //Initialize Cipher for ENCRYPT_MODE cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); //Perform Encryption byte[] cipherText = cipher.doFinal(plaintext); return cipherText; } public static String decrypt (byte[] cipherText, SecretKey key,byte[] IV) throws Exception { //Get Cipher Instance Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); //Create SecretKeySpec SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "AES"); //Create IvParameterSpec IvParameterSpec ivSpec = new IvParameterSpec(IV); //Initialize Cipher for DECRYPT_MODE cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); //Perform Decryption byte[] decryptedText = cipher.doFinal(cipherText); return new String(decryptedText); } }
- We are using KeyGenerator Class to generate symmetric encryption keys, we get the KeyGenerator instance by calling the getInstance() method passing the name of the algorithm as a parameter, in our case it is AES
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
- After creating the KeyGenerator instance, we need to initialize it by calling its init() method, we need to pass the bit size of the keys to generate.
keyGenerator.init(128);
- Once the KeyGenerator is initialized, we can generate the symmetric SecretKey by calling the generateKey() method on top of the KeyGenerator instance.
SecretKey key = keyGenerator.generateKey();
- The IV stands for Initialization Vector, it is an arbitrary number which will be used along with SecretKey during encryption. The IV adds randomness to the start of the encryption process, it is also called as nonce as it will be used only once.
byte[] IV = new byte[16]; SecureRandom random = new SecureRandom(); random.nextBytes(IV);
- Cipher class is the one that handles the actual encryption and decryption. Cipher class instance is created by calling the getInstance() method passing the Cipher name as the parameter, in our case it is AES/CBC/PKCS5Padding
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
- Cipher name is composed of 3 parts
- The first part is the name of the algorithm – AES
- The second part is the mode in which the algorithm should be used – CBC
- The third part is the padding scheme which is going to be used – PKCS5Padding
- The SecretKeySpec provides the mechanism of converting byte data into a secret key suitable to be passed to init() method of the Cipher class.
SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "AES");
- IvParameterSpec is a wrapper for an initialization vector, IV gets its randomness from the way IvParameterSpec is configured.
IvParameterSpec ivSpec = new IvParameterSpec(IV);
- Once the Cipher instance is created we need to initilazie the cipher instance by calling the init() method. We need to pass the 3 parameters to the init() method.
- Cipher Mode – Cipher.ENCRYPT_MODE (or) Cipher.DECRYPT_MODE
- SecretKeySpec
- IvParameterSpec
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
- In order to encrypt we will be calling the doFinal() method on top of the Cipher instance passing the plainText as the parameter
byte[] cipherText = cipher.doFinal(plaintext);
- We will be encoding the ciperText with Base64 to ensure it to be intact without modification when it is transferred.
Base64.getEncoder().encodeToString(cipherText)
- To decrypt we need to pass the cipherText to the doFinal() method of the Cipher instance
byte[] decryptedText = cipher.doFinal(cipherText);
Output:
Original Text : This is a plain text which need to be encrypted by AES Algorithm with CBC Mode Encrypted Text : 91Lk10E35mvZgXmXOXezG8eXtlFM8W1Q1BeaU5L3isOvlp0a/ApY4KqXefovFMGuspaPDpgKuM6qf5rEsKN1y69vZeQQfGVCPtWTp+M0TbM= DeCrypted Text : This is a plain text which need to be encrypted by AES Algorithm with CBC Mode
Leave a Reply