Search

Suggested keywords:
  • Java
  • Docker
  • Git
  • React
  • NextJs
  • Spring boot
  • Laravel

Advanced Encryption Standard (AES) Encryption in Java

  • Share this:

post-title

Nowadays, securing sensitive data during transmission is of utmost importance. One of the most widely used encryption algorithms for this purpose is Advanced Encryption Standard (AES). In Java applications, AES encryption is straightforward to implement, making it easy to transmit secure data. In this article, we will explore how to encrypt and decrypt using AES algorithm using Java built in library.

What is AES Encryption?

An AES algorithm, also called Rijndael, is a symmetric encryption method. It encrypts and decrypts data using a symmetric key. Basically same key is used for both encryption and decryption. AES's strength lies in its key size, which can be 128, 192, or 256 bits. Generally, the larger the key size, the more secure the encryption.

AES is a block cipher algorithm. It splits the message into smaller blocks and encrypts those blocks to convert the plaintext message to encrypted message.

Implementation in Java

To demonstrate AES encryption in Java, let's look at a simple example. This section will demonstrate how to encrypt and decrypt strings using a secret key. Encrypted message will be in the form of binary, it has to be encoded in to Base64 to make it as a string.

We will use Java's built-in libraries to encrypt with AES. No external dependencies are required. Below example is simple and basic way of doing encryption.

 

AES Encryption

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;


public class AESEncryptionExample {

   private static final String AES_ALGORITHM = "AES";
   private static final String CHARSET = "UTF-8";

   public static String encrypt(String plaintext, String secretKey) throws Exception {
       SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(CHARSET), AES_ALGORITHM);
       Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
       cipher.init(Cipher.ENCRYPT_MODE, keySpec);
       byte[] encryptedBytes = cipher.doFinal(plaintext.getBytes(CHARSET));
       return Base64.getEncoder().encodeToString(encryptedBytes);
   }

   public static String decrypt(String encryptedText, String secretKey) throws Exception {
       SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(CHARSET), AES_ALGORITHM);
       Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
       cipher.init(Cipher.DECRYPT_MODE, keySpec);
       byte[] encryptedBytes = Base64.getDecoder().decode(encryptedText);
       byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
       return new String(decryptedBytes, CHARSET);
   }

   public static void main(String[] args) {
       try {
           String secretKey = "MySecretKey12345"; // 16, 24, or 32 bytes
           String originalText = "This is a secret message.";

           // Encrypting the text
           String encryptedText = encrypt(originalText, secretKey);
           System.out.println("Encrypted Text: " + encryptedText);

           // Decrypting the text
           String decryptedText = decrypt(encryptedText, secretKey);
           System.out.println("Decrypted Text: " + decryptedText);

       } catch (Exception e) {
           e.printStackTrace();
       }
   }
}

Explanation:

In the encrypt method, the plaintext and secret key are taken, the AES cipher is initialized with the secret key, and then the plaintext is encrypted. For ease of transmission, the result is encoded in Base64.

The decrypt method first decodes the Base64 encoded text, initializes the AES cipher, then decrypts the text.

 

AES Encryption using Transformation and Intialization Vectors

A transformation is of the form of algorithm/mode/padding, which describes the operation (or set of operations) to be performed on the given input, to produce some output. If we use transformation with padding then we need to use initialization vector. 

Initialization vector: An initialization vector (IV) is a random or pseudo random number used in combination with a secret key as a means to encrypt data. It should be used only once per session. If you encrypt same content again and again, you will get same encrypted text as output. This will help the hackers to guess the data. In order to avoid, we need to add IV to the key, to get unique encrypted text every time.

Using the same input text and same secret key with different IV, we will get different output. If IV is same then every time we will get same output. This will help hackers to decode the key. To avoid this, it is good to use IV.

Here we are using simple data structure to store encrypted text and IV.

public class EncryptedData {
	
	private String data;
	private String iv;
	
	public EncryptedData(String data, String iv) {
		super();
		this.data = data;
		this.iv = iv;
	}
	
	public String getData() {
		return data;
	}
	
	public String getIv() {
		return iv;
	}

}

 

Now let's encrypt and decrypt using transformation and IV.

public class AESAdvancedEncryptionExample {
	
	private static final String AES_ALGORITHM = "AES";
	private static final String CIPHER_MODE   = "AES/CBC/PKCS5Padding";
	private static final String CHARSET       = "UTF-8";
	
	public static EncryptedData encrypt(String plaintext, String secretKey) throws Exception {
		
		SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(), AES_ALGORITHM);
        Cipher cipher = Cipher.getInstance(CIPHER_MODE);
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, new SecureRandom());
        byte[] encryptedBytes = cipher.doFinal(plaintext.getBytes(CHARSET));
        
        String iv   = Base64.getEncoder().encodeToString(cipher.getIV());
        String data = Base64.getEncoder().encodeToString(encryptedBytes);
        
        return new EncryptedData(data, iv);
    }

	public static String decrypt(EncryptedData encryptedData, String secretKey) throws Exception {
		
		byte[] encryptedBytes = Base64.getDecoder().decode(encryptedData.getData());
	    byte[] iv = Base64.getDecoder().decode(encryptedData.getIv());
		
		SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(), AES_ALGORITHM);
	    Cipher cipher = Cipher.getInstance(CIPHER_MODE);
	    cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(iv));
	    byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
	    return new String(decryptedBytes, CHARSET);
	}

}

 

Let's test the code.

try {
	String secretKey = "MySecretKey12345"; // 16, 24, or 32 bytes
	String originalText = "This is a secret message.";
	
	// Encrypting the text
	EncryptedData encryptedData = AESAdvancedEncryptionExample.encrypt(originalText, secretKey);
	System.out.println("Encrypted Text: " + encryptedData.getData());
	System.out.println("IV String: " + encryptedData.getIv());
	
	// Decrypting the text
	String decryptedText = AESAdvancedEncryptionExample.decrypt(encryptedData, secretKey);
	System.out.println("Decrypted Text: " + decryptedText);
	
} catch (Exception e) {
	e.printStackTrace();
}

Explanation:

In the encrypt method, we use SecureRandom() to generate random value while doing encryption. Once the encryption is done we can get the encrypted value using cipher.doFinal() and we can get IV using cipher.getIV().

In the decrypt method, we will be using the secret key and the same IV to decrypt the data.

 

Source code available in Github

Conclusion

This article demonstrated how to encrypt data using the AES encryption algorithm using Java. The secret key is crucial to encrypting and decrypting data, so it must be kept secure. The AES algorithm provides a high level of security, making it ideal for protecting sensitive data. The example below illustrates how Java applications can implement secure data transmission.

 

Muthu Annamalai

About author
Technical Writer | Pre-Final Year Student | Code & Community | Developer who works everyday to improve himself.