AES Symmetric Encryption
Encrypt and decrypt sensitive data with AES/CBC/PKCS5Padding using Java's javax.crypto API.
AES Symmetric Encryption is a free Java Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Java Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Symmetric vs Asymmetric Encryption
Symmetric encryption uses the same key for encrypt and decrypt (fast, suitable for bulk data). Asymmetric uses a public/private key pair (slower, used for key exchange and signatures). AES is the standard symmetric cipher.
AES Modes: CBC vs GCM
AES has several modes. AES/CBC/PKCS5Padding is common but lacks authentication. AES/GCM/NoPadding provides both encryption and authentication (AEAD) — strongly preferred for new code.
Generating an AES Key
Use KeyGenerator to generate a 256-bit AES key securely.
KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(256); // 256-bit key
SecretKey key = kg.generateKey();
// Persist the key:
String b64Key = Base64.getEncoder().encodeToString(key.getEncoded());
// Restore the key:
byte[] decoded = Base64.getDecoder().decode(b64Key);
SecretKey restored = new SecretKeySpec(decoded, "AES");AES/GCM Encryption
GCM mode requires a unique 12-byte Initialization Vector (IV) per encryption. Generate a new random IV for every encryption operation — never reuse an IV with the same key.
byte[] iv = new byte[12]; // 96-bit IV for GCM
new SecureRandom().nextBytes(iv);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec spec = new GCMParameterSpec(128, iv); // 128-bit auth tag
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
byte[] ciphertext = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));
// Transmit/store: IV + ciphertext (IV is not secret)AES/GCM Decryption
Extract the IV from the stored data, reconstruct the spec, and decrypt. GCM automatically verifies authenticity — tampered data throws AEADBadTagException.
// Assume stored = iv + ciphertext:
byte[] iv = Arrays.copyOfRange(stored, 0, 12);
byte[] ciphertext = Arrays.copyOfRange(stored, 12, stored.length);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, key, new GCMParameterSpec(128, iv));
byte[] plaintext = cipher.doFinal(ciphertext); // throws if tamperedStoring IV with Ciphertext
The IV is not secret — store it prepended to or alongside the ciphertext. The recipient needs the IV to decrypt. The key must be kept secret.
byte[] encryptedData = new byte[iv.length + ciphertext.length];
System.arraycopy(iv, 0, encryptedData, 0, iv.length);
System.arraycopy(ciphertext, 0, encryptedData, iv.length, ciphertext.length);
String b64 = Base64.getEncoder().encodeToString(encryptedData);Key Derivation from Password (PBKDF2)
Never use a password directly as an AES key — its entropy is too low. Derive a key with PBKDF2 using a random salt and a high iteration count.
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 310_000, 256);
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
byte[] keyBytes = skf.generateSecret(spec).getEncoded();
SecretKey key = new SecretKeySpec(keyBytes, "AES");Using Java Security Provider
The JDK's default provider handles AES. For additional algorithms or FIPS compliance, use the Bouncy Castle provider.
// With Bouncy Castle:
Security.addProvider(new BouncyCastleProvider());
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "BC");Envelope Encryption Pattern
Encrypt data with a randomly generated Data Encryption Key (DEK). Encrypt the DEK with a Key Encryption Key (KEK) stored in a KMS (AWS KMS, HashiCorp Vault). This limits key exposure.
AES in Spring Apps
Spring Security's TextEncryptor or Spring Security Crypto module provide high-level AES encryption without managing Cipher/IV manually.
TextEncryptor encryptor = Encryptors.text(password, salt);
String encrypted = encryptor.encrypt("sensitive data");
String decrypted = encryptor.decrypt(encrypted);Common Pitfalls
Never: reuse IV with the same key, use ECB mode (patterns preserved), use a password as key directly, or ignore the authentication tag. Always use GCM for new code.
Quick Check
What does AES/GCM provide that AES/CBC does not?
Recap
Use AES/GCM/NoPadding for authenticated encryption. Generate a new random 12-byte IV per encryption. Prepend IV to ciphertext. Derive keys from passwords with PBKDF2. Never reuse an IV with the same key.
Frequently asked questions
Is the “AES Symmetric Encryption” lesson free?
Yes — the full text of “AES Symmetric Encryption” is free to read here on the web, and the Java Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Java Academy course, upgrade to CoddyKit PRO.
What will I learn in “AES Symmetric Encryption”?
Encrypt and decrypt sensitive data with AES/CBC/PKCS5Padding using Java's javax.crypto API. You practise Java Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Java Academy?
No prior experience is required. Java Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “AES Symmetric Encryption” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Java Academy lesson?
Yes. Every Java Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.