AES-128 Example in JAVA

The example given will accomplish below Tasks.

  • Generate symmetric key using AES-128.
  • Generate initialization vector used for CBC (Cipher Block Chaining).
  • Encrypt message using symmetric key and initialization vector.
  • Decrypt the encrypted message using symmetric key and initialization vector.

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class AESManager {

 public static String ALGORITHM = "AES";
 // public static String AES_CBC_NoPADDING = "AES/CBC/NoPadding";
 public static String AES_CBC_PADDING = "AES/CBC/PKCS5Padding";

 public static byte[] encrypt(final byte[] key, final byte[] IV, final byte[] message) throws Exception {
  return AESManager.encryptDecrypt(Cipher.ENCRYPT_MODE, key, IV, message);
 }

 public static byte[] decrypt(final byte[] key, final byte[] IV, final byte[] message) throws Exception {
  return AESManager.encryptDecrypt(Cipher.DECRYPT_MODE, key, IV, message);
 }

 private static byte[] encryptDecrypt(final int mode, final byte[] key, final byte[] IV, final byte[] message) throws Exception {
  final Cipher cipher = Cipher.getInstance(AES_CBC_PADDING);
  final SecretKeySpec keySpec = new SecretKeySpec(key, ALGORITHM);
  final IvParameterSpec ivSpec = new IvParameterSpec(IV);
  cipher.init(mode, keySpec, ivSpec);
  return cipher.doFinal(message);
 }

 public static String getHex(byte[] data, int length) {
  StringBuffer sb = new StringBuffer();
  for (int i = 0; i < length; i++) {
   String hexStr = Integer.toHexString(((int) data[i]) & 0xFF);
   if (hexStr.length() < 2) {
    sb.append("0").append(hexStr.toUpperCase());
   } else {
    sb.append(hexStr.toUpperCase());
   }
  }
  return sb.toString();
 }

}
AESClient.java: AESClient class will generate random input message and will invoke AESManager.java to encrypt & decrypt input message.
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.Base64;
import java.util.UUID;

import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;

public class AESClient {

 private static int AES_128 = 128;
 private static int AES_192 = 192;
 private static int AES_256 = 256;

 public static void main(String[] args) throws Exception {

  byte keyBytes[] = generateKey();

  String AES_KEY_HEX = AESManager.getHex(keyBytes, keyBytes.length);
  System.out.println("AES-KEY : " +AES_KEY_HEX);

  // Initialization vector
  byte IVBytes[] = generateKey();

  String randomString = UUID.randomUUID().toString().substring(0, 16);
  System.out.println("1. Original Message: " + randomString);

  byte[] cipherText = AESManager.encrypt(keyBytes, IVBytes, randomString.getBytes());
  System.out.println("2. Encrypted Text: " + Base64.getEncoder().encodeToString(cipherText));

  byte[] decryptedString = AESManager.decrypt(keyBytes, IVBytes, cipherText);
  System.out.println("3. Decrypted Message : " + new String(decryptedString));
 }

 public static byte[] generateKey() throws NoSuchAlgorithmException, InvalidKeySpecException {
  KeyGenerator keyGenerator = KeyGenerator.getInstance(AESManager.ALGORITHM);
  keyGenerator.init(AES_128);
  SecretKey key = keyGenerator.generateKey();
  return key.getEncoded();
 }
}
Sample outPut:
AES-KEY : 6239A5DBBA65D0D42E6520922621A8B8
1. Original Message: 5dbf850f-3938-48
2. Encrypted Text: smV12iTwLIHNTgFRSDzG2xmzYl5yRJQ6Jo2qnqK0iqc=
3. Decrypted Message : 5dbf850f-3938-48Generate symmetric key using AES-128.

Important Note:

AES uses block size of 16 bytes (128 bits), so if you are using "AES/CBC/NoPadding", then Smaller input must be padded with zeros to 16 bytes otherwise you will get below exception:

javax.crypto.IllegalBlockSizeException: Input length not multiple of 16 bytes


In order to avoid padding at your end, then you have to use "AES/CBC/PKCS5Padding" as shown in above example.