AES-GCM Encrypt & Decrypt in Python
Implement authenticated encryption with proper nonce management.
AES-GCM Encrypt & Decrypt in Python is a free Cryptology 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 Cryptology Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Why AES-GCM?
AES-GCM is an Authenticated Encryption with Associated Data (AEAD) scheme. It provides confidentiality (AES-CTR) and integrity/authenticity (GHASH MAC) in a single pass — the standard for modern encryption.
GCM Components: CTR + GHASH
AES-GCM = AES in Counter mode (encryption) + GHASH polynomial MAC (authentication). The 128-bit authentication tag covers both ciphertext and optional Additional Authenticated Data (AAD).
Nonce Requirements
The 96-bit nonce must never be reused with the same key. Nonce reuse completely breaks GCM — an attacker recovers the authentication key and can forge ciphertexts. Use random nonces or a counter with key rotation.
Encrypting with AES-GCM in Python
Using the hazmat layer:
import os
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
# Generate a 256-bit key
key = AESGCM.generate_key(bit_length=256)
aesgcm = AESGCM(key)
# Fresh 96-bit nonce per encryption
nonce = os.urandom(12)
plaintext = b"sensitive payload"
aad = b"user_id=42" # authenticated but not encrypted
ciphertext = aesgcm.encrypt(nonce, plaintext, aad)
print("Nonce:", nonce.hex())
print("Ciphertext+tag:", ciphertext.hex())Decrypting with AES-GCM in Python
Decryption verifies the tag automatically; raises InvalidTag on failure:
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from cryptography.exceptions import InvalidTag
# key, nonce, ciphertext, aad from previous step
try:
recovered = aesgcm.decrypt(nonce, ciphertext, aad)
print("Decrypted:", recovered)
except InvalidTag:
print("Authentication failed — ciphertext tampered!")Storing Nonce + Ciphertext
Prepend the nonce to the ciphertext before storage. On decryption, split at byte 12:
def encrypt_blob(key: bytes, data: bytes, aad: bytes = b"") -> bytes:
aesgcm = AESGCM(key)
nonce = os.urandom(12)
ct = aesgcm.encrypt(nonce, data, aad or None)
return nonce + ct # prepend nonce
def decrypt_blob(key: bytes, blob: bytes, aad: bytes = b"") -> bytes:
aesgcm = AESGCM(key)
nonce, ct = blob[:12], blob[12:]
return aesgcm.decrypt(nonce, ct, aad or None)Additional Authenticated Data (AAD)
AAD is authenticated but not encrypted. Use it to bind ciphertext to context: user ID, record ID, API version. Prevents an attacker from moving a valid ciphertext to a different context.
Using the Low-Level Cipher API
For streaming or in-place encryption use the Cipher API with GCM mode directly:
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
key = os.urandom(32)
nonce = os.urandom(12)
cipher = Cipher(algorithms.AES(key), modes.GCM(nonce))
encryptor = cipher.encryptor()
encryptor.authenticate_additional_data(b"aad-value")
ct = encryptor.update(b"hello world") + encryptor.finalize()
tag = encryptor.tag
print("Tag:", tag.hex())Nonce Misuse Resistance: AES-GCM-SIV
AES-GCM-SIV (RFC 8452) is nonce-misuse resistant: nonce reuse leaks that two plaintexts are identical but does NOT break authenticity. Prefer it when nonce uniqueness is hard to guarantee.
Key Derivation Before Encryption
Never use a raw password as an AES key. Derive a key with Argon2 or HKDF:
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
from cryptography.hazmat.primitives import hashes
import os
master_secret = b"shared_secret_from_ECDH"
salt = os.urandom(16)
kdf = HKDF(algorithm=hashes.SHA256(), length=32, salt=salt, info=b"aes-gcm-key")
aes_key = kdf.derive(master_secret)
print("Derived AES key:", aes_key.hex())Performance Considerations
AES-NI hardware acceleration makes AES-GCM extremely fast (~1-4 GB/s on modern CPUs). Python cryptography uses OpenSSL which exploits AES-NI. For files >100 MB, use chunked streaming with the low-level Cipher API.
Knowledge Check
What happens if the same nonce is used twice with AES-GCM under the same key?
Lesson Recap
AES-GCM provides authenticated encryption in one pass. Use a fresh 96-bit random nonce per encryption. Prepend nonce to ciphertext for storage. AAD binds ciphertext to context. AES-GCM-SIV resists nonce misuse. Derive keys with HKDF, never use raw passwords.
Frequently asked questions
Is the “AES-GCM Encrypt & Decrypt in Python” lesson free?
Yes — the full text of “AES-GCM Encrypt & Decrypt in Python” is free to read here on the web, and the Cryptology 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 Cryptology Academy course, upgrade to CoddyKit PRO.
What will I learn in “AES-GCM Encrypt & Decrypt in Python”?
Implement authenticated encryption with proper nonce management. You practise Cryptology 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 Cryptology Academy?
No prior experience is required. Cryptology 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-GCM Encrypt & Decrypt in Python” 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 Cryptology Academy lesson?
Yes. Every Cryptology 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.
All lessons in this course
- Python cryptography Library Overview
- AES-GCM Encrypt & Decrypt in Python
- RSA & ECDSA Key Pairs in Python
- Common Python Crypto Pitfalls & Secure Patterns