Unravel › Java concepts › Security
Symmetric encryption (AES-GCM) and key handling
Encryption makes data unreadable without a key.
Learn these first
At a glance
A lockbox with one key shared by both parties.
- 1Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); cipher.init(Cipher.ENCRYPT_MODE, key, new GCMParameterSpec(128, iv)); byte[] out = cipher.doFinal(plain); The IV (nonce) is 12 random bytes, stored in front of the ciphertext
- 2Decrypting reads the IV, initialises the cipher in decrypt mode and calls doFinal; an AEADBadTagException means the data or key is wrong or the data was modified
- 3Keys come from a key manager (AWS KMS, Azure Key Vault, HashiCorp Vault) or a KeyStore, never from a string literalEnvelope encryption: KMS creates a data key per object and you store the encrypted data key beside the data.
- 4Asymmetric keys (RSA, EC) are for key exchange and signatures: Signature.getInstance("SHA256withRSA") signs and verifies; do not encrypt bulk data with RSA
- Never reuse an IV with the same key in GCM
- AES alone means AES/ECB/PKCS5Padding, which encrypts identical blocks identically and shows patterns; it is the most common mistake in found code
- GCM runs AES in counter mode (turning the block cipher into a stream cipher keyed by the nonce and a counter) and computes a GHASH authentication tag over the ciphertext and associated data
byte[] iv = new byte[12];new SecureRandom().nextBytes(iv);Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");cipher.init(Cipher.ENCRYPT_MODE, key, new GCMParameterSpec(128, iv));byte[] encrypted = cipher.doFinal(plain);byte[] stored = ByteBuffer.allocate(iv.length + encrypted.length).put(iv).put(encrypted).array();- line 3 uses Cipher, the core of Symmetric encryption (AES-GCM) and key handling
- line 4 uses Cipher, the core of Symmetric encryption (AES-GCM) and key handling
Read the full explanation (about 2 min)
Encryption makes data unreadable without a key. AES in GCM mode is the modern default: it encrypts and detects tampering in one step, but only if each message gets a fresh random nonce and the key is kept outside the code.
A mental model
A lockbox with one key shared by both parties. Each message uses a new, unique seal (the nonce) on the box; if anyone opens and re-closes it, the tamper seal (authentication tag) shows it.
How it works
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); cipher.init(Cipher.ENCRYPT_MODE, key, new GCMParameterSpec(128, iv)); byte[] out = cipher.doFinal(plain); The IV (nonce) is 12 random bytes, stored in front of the ciphertext.
Decrypting reads the IV, initialises the cipher in decrypt mode and calls doFinal; an AEADBadTagException means the data or key is wrong or the data was modified.
Keys come from a key manager (AWS KMS, Azure Key Vault, HashiCorp Vault) or a KeyStore, never from a string literal. Envelope encryption: KMS creates a data key per object and you store the encrypted data key beside the data.
Asymmetric keys (RSA, EC) are for key exchange and signatures: Signature.getInstance("SHA256withRSA") signs and verifies; do not encrypt bulk data with RSA.
Going deeper
Never reuse an IV with the same key in GCM. A repeated nonce breaks both confidentiality and authentication. Use SecureRandom for each encryption.
AES alone means AES/ECB/PKCS5Padding, which encrypts identical blocks identically and shows patterns; it is the most common mistake in found code. Use AES/GCM/NoPadding. Also avoid DES and RSA with PKCS1 padding for new designs.
Rolling your own scheme is risky: use a high-level library (Tink, Spring Encryptors) when you can. Keep key rotation in mind by storing a key id with each ciphertext.
Under the hood
GCM runs AES in counter mode (turning the block cipher into a stream cipher keyed by the nonce and a counter) and computes a GHASH authentication tag over the ciphertext and associated data. Decrypt verifies the tag before returning plaintext, which is why modified data fails instead of decrypting to garbage.
Common mistakes
- ECB mode by default.
- Reusing or hard-coding the IV.
- Keys in source code or properties files.
- Ignoring authentication (CBC without a MAC).
How Unravel recognises it
When you paste code, Unravel looks for these signs of symmetric encryption (aes-gcm) and key handling. Spotting them yourself is a good habit when you read unfamiliar code:
- Types:
CipherSecretKeySpecGCMParameterSpecIvParameterSpecKeyGeneratorSecretKeyKeyPairGeneratorKeyFactoryKeyAgreementBadPaddingExceptionAEADBadTagExceptionIllegalBlockSizeExceptionTextEncryptorEncryptorsand 5 more - Method calls:
Cipher.getInstance() - Configuration keys:
AES/GCM/NoPaddingAES/CBC/PKCS5PaddingAES/ECB/PKCS5PaddingRSA/ECB/PKCS1PaddingRSA/ECB/OAEPWithSHA-256AndMGF1Padding
Part of a learning path
- Security for backend developers · previous: Hashes, HMAC and secure random · next: TLS, keystores and certificates
Related concepts
Frequently asked questions
What is Symmetric encryption (AES-GCM) and key handling?
Encryption makes data unreadable without a key. AES in GCM mode is the modern default: it encrypts and detects tampering in one step, but only if each message gets a fresh random nonce and the key is kept outside the code.
What are the most common mistakes with Symmetric encryption (AES-GCM) and key handling?
ECB mode by default. Reusing or hard-coding the IV. Keys in source code or properties files. Ignoring authentication (CBC without a MAC).
How can I see Symmetric encryption (AES-GCM) and key handling in real code?
Paste your own Java into Unravel and it will point out where symmetric encryption (aes-gcm) and key handling appears, explain how it works at the detail level you choose, and draw the flow of the code around it.