AES Encryption in Java

AES (Advanced Encryption Standard) is a widely used symmetric encryption algorithm. Here's a step-by-step guide to implementing AES encryption in Java using the javax.crypto package:

AES Encryption and Decryption

Import necessary classes:

import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.IvParameterSpec; import java.util.Base64; import java.security.SecureRandom;

Generate a secret key

byte[] key = new byte[16]; // 128-bit key SecureRandom random = new SecureRandom(); random.nextBytes(key);
// Alternatively, you can derive a key from a password using PBKDF2: // byte[] password = "yourpassword".getBytes(); // byte[] salt = new byte[16]; // random.nextBytes(salt); // SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); // KeySpec spec = new PBEKeySpec(password, salt, 65536, 128); // SecretKey tmp = factory.generateSecret(spec); // SecretKeySpec key = new SecretKeySpec(tmp.getEncoded(), "AES");

Generate an initialization vector (IV)

byte[] iv = new byte[16]; // 128-bit IV random.nextBytes(iv);

Create a Cipher instance

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // Choose a suitable mode and padding

Initialize the Cipher for encryption

cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), new IvParameterSpec(iv));

Encrypt the data

String plainText = "This is the text to encrypt"; byte[] cipherText = cipher.doFinal(plainText.getBytes());

Encode the ciphertext and IV (optional)

String encodedCipherText = Base64.getEncoder().encodeToString(cipherText); String encodedIV = Base64.getEncoder().encodeToString(iv);

Decrypt the data

// Retrieve the encoded ciphertext and IV byte[] decodedCipherText = Base64.getDecoder().decode(encodedCipherText); byte[] decodedIV = Base64.getDecoder().decode(encodedIV); // Initialize the Cipher for decryption cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"), new IvParameterSpec(decodedIV)); // Decrypt the ciphertext byte[] decryptedText = cipher.doFinal(decodedCipherText); String plainText = new String(decryptedText);
Points to Remember:
  1. Key management: Securely store and manage keys.
  2. Mode of operation and padding: Choose appropriate modes (e.g., CBC, GCM) and padding (e.g., PKCS#5, PKCS#7) based on security requirements.
  3. Error handling: Implement proper error handling for exceptions.
  4. Base64 encoding: Optional for storing or transmitting ciphertext and IV as text.
  5. Best practices: Adhere to security best practices, such as using strong keys and keeping dependencies up-to-date.
Full Source | Java
import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.IvParameterSpec; import java.util.Base64; import java.security.SecureRandom; public class AESEncryptionExample { public static void main(String[] args) throws Exception { String plainText = "This is the text to encrypt"; // Generate a random key and IV byte[] key = generateRandomKey(); byte[] iv = generateRandomIV(); // Encrypt the plain text byte[] cipherText = encrypt(plainText, key, iv); // Encode the ciphertext and IV for storage or transmission String encodedCipherText = Base64.getEncoder().encodeToString(cipherText); String encodedIV = Base64.getEncoder().encodeToString(iv); System.out.println("Encrypted text (base64): " + encodedCipherText); System.out.println("IV (base64): " + encodedIV); // Decrypt the ciphertext String decryptedText = decrypt(encodedCipherText, encodedIV, key); System.out.println("Decrypted text: " + decryptedText); } private static byte[] generateRandomKey() { SecureRandom random = new SecureRandom(); byte[] key = new byte[16]; random.nextBytes(key); return key; } private static byte[] generateRandomIV() { SecureRandom random = new SecureRandom(); byte[] iv = new byte[16]; random.nextBytes(iv); return iv; } private static byte[] encrypt(String plainText, byte[] key, byte[] iv) throws Exception { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), new IvParameterSpec(iv)); return cipher.doFinal(plainText.getBytes()); } private static String decrypt(String encodedCipherText, String encodedIV, byte[] key) throws Exception { byte[] cipherText = Base64.getDecoder().decode(encodedCipherText); byte[] iv = Base64.getDecoder().decode(encodedIV); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"), new IvParameterSpec(iv)); byte[] decryptedText = cipher.doFinal(cipherText); return new String(decryptedText); } }
Output:
Encrypted text (base64): akXMyFjIQ6awFf4O8B/voTEthqWGRTnMo0NVYHekjdw= IV (base64): wFePzLDkbUfaefpMibZcJQ== Decrypted text: This is the text to encrypt

Conclusion

To implement AES encryption in Java, start by importing necessary packages such as javax.crypto and generate a secret key using the SecretKeySpec class. Then, create methods for encryption and decryption using the Cipher class, and finally, test the implementation by encrypting and decrypting a sample message in the main method. Ensure proper exception handling and consider using a secure method for key generation in a real-world scenario.