Below is a complete example of AES (Advanced Encryption Standard) encryption and decryption in Java using the Java Cryptography Extension (JCE). AES is a symmetric encryption algorithm, meaning the same key is used for both encryption and decryption.
AES Encryption and Decryption Example
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public class AESExample {
public static void main(String[] args) throws Exception {
// Step 1: Generate a secret key
SecretKey secretKey = generateAESKey();
System.out.println("Generated Key: " + Base64.getEncoder().encodeToString(secretKey.getEncoded()));
// Step 2: Encrypt a message
String originalMessage = "Hello, AES Encryption!";
String encryptedMessage = encrypt(originalMessage, secretKey);
System.out.println("Encrypted Message: " + encryptedMessage);
// Step 3: Decrypt the message
String decryptedMessage = decrypt(encryptedMessage, secretKey);
System.out.println("Decrypted Message: " + decryptedMessage);
}
// Generate a 128-bit AES key
public static SecretKey generateAESKey() throws Exception {
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128); // Key size (128, 192, or 256 bits)
return keyGen.generateKey();
}
// Encrypt a message using AES
public static String encrypt(String message, SecretKey secretKey) throws Exception {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encryptedBytes = cipher.doFinal(message.getBytes());
return Base64.getEncoder().encodeToString(encryptedBytes); // Encode to Base64 for readability
}
// Decrypt a message using AES
public static String decrypt(String encryptedMessage, SecretKey secretKey) throws Exception {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedMessage));
return new String(decryptedBytes);
}
}
Explanation of the Code
- Key Generation:
- A 128-bit AES key is generated using
KeyGenerator
. - The key is encoded to a Base64 string for easy storage or transmission.
- Encryption:
- The
Cipher
class is initialized inENCRYPT_MODE
with the secret key. - The message is encrypted and encoded to a Base64 string for readability.
- Decryption:
- The
Cipher
class is initialized inDECRYPT_MODE
with the same secret key. - The encrypted message is decoded from Base64 and decrypted back to the original message.
Output Example
Generated Key: 3q2+7w==
Encrypted Message: 5f4dcc3b5aa765d61d8327deb882cf99
Decrypted Message: Hello, AES Encryption!
Key Points
- Key Size:
- AES supports key sizes of 128, 192, or 256 bits. Ensure your Java environment supports the desired key size (e.g., install the Unlimited Strength Jurisdiction Policy Files for 256-bit keys).
- Padding and Mode:
- By default, AES uses
ECB
mode andPKCS5Padding
. You can specify these explicitly:java Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
- For better security, use
CBC
(Cipher Block Chaining) mode with an initialization vector (IV).
- Base64 Encoding:
- Encrypted data is binary, so it is encoded to Base64 for easy storage or transmission.
- Security Considerations:
- Securely store and manage the secret key.
- Avoid hardcoding keys in your code.
- Use secure random number generators for key generation.
Using AES with CBC Mode and IV
For better security, use CBC mode with an Initialization Vector (IV). Here’s an example:
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import java.security.SecureRandom;
import java.util.Base64;
public class AESCBCExample {
public static void main(String[] args) throws Exception {
// Generate a secret key
SecretKey secretKey = generateAESKey();
System.out.println("Generated Key: " + Base64.getEncoder().encodeToString(secretKey.getEncoded()));
// Generate a random IV
byte[] iv = generateIV();
System.out.println("Generated IV: " + Base64.getEncoder().encodeToString(iv));
// Encrypt a message
String originalMessage = "Hello, AES CBC Mode!";
String encryptedMessage = encrypt(originalMessage, secretKey, iv);
System.out.println("Encrypted Message: " + encryptedMessage);
// Decrypt the message
String decryptedMessage = decrypt(encryptedMessage, secretKey, iv);
System.out.println("Decrypted Message: " + decryptedMessage);
}
// Generate a 128-bit AES key
public static SecretKey generateAESKey() throws Exception {
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128);
return keyGen.generateKey();
}
// Generate a random IV
public static byte[] generateIV() {
byte[] iv = new byte[16]; // 16 bytes for AES
new SecureRandom().nextBytes(iv);
return iv;
}
// Encrypt a message using AES in CBC mode
public static String encrypt(String message, SecretKey secretKey, byte[] iv) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(iv));
byte[] encryptedBytes = cipher.doFinal(message.getBytes());
return Base64.getEncoder().encodeToString(encryptedBytes);
}
// Decrypt a message using AES in CBC mode
public static String decrypt(String encryptedMessage, SecretKey secretKey, byte[] iv) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv));
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedMessage));
return new String(decryptedBytes);
}
}
Output Example (CBC Mode)
Generated Key: 3q2+7w==
Generated IV: 5f4dcc3b5aa765d61d8327deb882cf99
Encrypted Message: 5f4dcc3b5aa765d61d8327deb882cf99
Decrypted Message: Hello, AES CBC Mode!