Goal
Master symmetric encryption with AES: understand encryption modes (and why ECB is broken), use OpenSSL for file encryption, and learn how Key Derivation Functions transform weak passwords into strong keys.
Prerequisites: Week 2a (Hash Functions)
This is Part 2 of 3 - Covers symmetric encryption and key derivation.
1. Symmetric Encryption: Shared Secrets
What Is Symmetric Encryption?
Symmetric encryption uses the same key for both encryption and decryption.
Alice Bob
| |
| "Meet at midnight" + Key123 |
|---------> AES Encrypt --------------> |
| f8a3b2c1d4e5f6 (ciphertext) |
| |
| <-------- AES Decrypt <-------------- |
| f8a3b2c1d4e5f6 + Key123 |
| "Meet at midnight" (plaintext) |
Key challenge: How do Alice and Bob agree on “Key123” without anyone else learning it? (Solved in Week 3 with asymmetric crypto)
AES: The Gold Standard
Advanced Encryption Standard (AES) is the most widely used symmetric cipher.
Key facts:
- Adopted by US government in 2001
- Replaced older DES (Data Encryption Standard)
- Block cipher: Encrypts data in 128-bit chunks
- Key sizes: 128-bit, 192-bit, or 256-bit (recommended)
- Unbroken after 20+ years of analysis
How secure is AES-256?
- 2^256 possible keys
- At 1 billion keys per second, brute force would take 3.67 × 10^51 years
- Universe is only 13.8 billion years old
- Conclusion: AES-256 is computationally unbreakable with current technology
Stream Ciphers vs Block Ciphers
Block Cipher (AES):
- Encrypts fixed-size blocks (128 bits)
- Requires padding for data not perfectly divisible by block size
- Needs “mode of operation”
Stream Cipher (ChaCha20):
- Encrypts data byte-by-byte
- No padding needed
- Often faster on devices without hardware AES acceleration
When to use each:
- AES: General purpose, hardware accelerated on modern CPUs
- ChaCha20: Mobile devices, embedded systems, Tor (faster without AES-NI)
2. Encryption Modes: How Block Ciphers Handle Data
AES encrypts 128-bit blocks, but files are arbitrary sizes. Modes of operation define how to encrypt multiple blocks.
ECB (Electronic Codebook) - NEVER USE
Block 1 → AES → Cipher 1
Block 2 → AES → Cipher 2 (Encrypted independently - BAD!)
Block 3 → AES → Cipher 3
Why it’s broken:
- Same plaintext block always produces same ciphertext block
- Patterns in data leak through encryption
- Famous example: ECB Penguin
CBC (Cipher Block Chaining) - Legacy
IV → XOR → AES → Cipher 1
↑ ↓
Block 1 XOR → AES → Cipher 2
↑ ↓
Block 2 Cipher 3...
Features:
- Each block depends on previous block (no patterns)
- Requires Initialization Vector (IV) - random starting value
- Vulnerable to padding oracle attacks if implemented incorrectly
- Still widely used but being phased out
GCM (Galois/Counter Mode) - RECOMMENDED
Counter → AES → XOR → Cipher 1
↑ ↑
Block 1 |
|
Authentication Tag (prevents tampering)
Features:
- Authenticated encryption - detects tampering automatically
- Parallel encryption (faster on multi-core CPUs)
- Industry standard for modern applications
- Used in TLS 1.3, SSH, disk encryption
Bottom line: Use AES-256-GCM unless you have a specific reason not to.
3. Hands-On: Encryption with OpenSSL
Basic File Encryption (CBC Mode)
# Encrypt a file with password
openssl enc -aes-256-cbc -salt -in secret.txt -out secret.enc
# You'll be prompted to enter a password
# Decrypt the file
openssl enc -d -aes-256-cbc -in secret.enc -out decrypted.txt
# Enter same password
# Verify decryption worked
diff secret.txt decrypted.txt # Should output nothing (files identical)
What’s happening:
enc- Encryption/decryption operation-aes-256-cbc- Algorithm and mode-salt- Adds randomness to prevent rainbow table attacks-in/-out- Input and output files-d- Decrypt flag
Encryption with Key File
# Generate 256-bit random key
openssl rand -out aes.key 32 # 32 bytes = 256 bits
# Encrypt using key file
openssl enc -aes-256-cbc -in secret.txt -out secret.enc -pass file:./aes.key
# Decrypt using key file
openssl enc -d -aes-256-cbc -in secret.enc -out decrypted.txt -pass file:./aes.key
# CRITICAL: Protect your key file!
chmod 600 aes.key # Only you can read/write
Modern Authenticated Encryption (GCM Mode)
# Encrypt with AES-256-GCM (authenticated)
openssl enc -aes-256-gcm -in secret.txt -out secret.enc -pass file:./aes.key
# If file is tampered with, decryption will FAIL automatically
echo "tamper" >> secret.enc
openssl enc -d -aes-256-gcm -in secret.enc -out decrypted.txt -pass file:./aes.key
# Error: bad decrypt (authentication tag verification failed)
ChaCha20: The Modern Alternative
ChaCha20-Poly1305 is a modern authenticated cipher (like AES-GCM).
Who uses it:
- Tor - All Tor traffic uses ChaCha20
- WireGuard - VPN protocol
- SSH - Available cipher for connections
- TLS 1.3 - Supported cipher suite
# Encrypt with ChaCha20-Poly1305
openssl enc -chacha20-poly1305 -in secret.txt -out secret.enc -pass file:./aes.key
# Decrypt
openssl enc -d -chacha20-poly1305 -in secret.enc -out decrypted.txt -pass file:./aes.key
4. Key Derivation Functions: From Passwords to Keys
The Problem with Password-Based Encryption
Passwords are weak. Most people choose:
- Dictionary words (“password123”)
- Short phrases (8-10 characters)
- Reused across sites
Raw passwords make terrible encryption keys:
# BAD: Using password directly
echo "MyPassword" → AES key
# Attacker tries 1 billion passwords/second → Cracked in minutes
How KDFs Work
A Key Derivation Function (KDF) transforms a weak password into a strong encryption key by making the process intentionally slow.
Process:
User Password + Salt → KDF (slow, expensive) → Strong 256-bit Key → AES Encryption
Steps:
- Add salt (random value) to prevent rainbow tables
- Apply hash function thousands/millions of times (CPU/memory intensive)
- Produce cryptographically strong key
Effect on attackers:
- Each password guess takes 0.1 seconds instead of 0.000001 seconds
- 1 billion guesses now takes 3 years instead of 1 second
Common KDFs
| Algorithm | Year | Strength | Notes |
|---|---|---|---|
| PBKDF2 | 2000 | Moderate | Widely supported, NIST standard |
| bcrypt | 1999 | Good | Memory-hard, resists GPUs |
| scrypt | 2009 | Better | Memory-hard + CPU-hard |
| Argon2 | 2015 | Best | Winner of Password Hashing Competition |
Recommendation: Use Argon2id for new applications, scrypt if Argon2 unavailable.
Hands-On: Key Derivation with OpenSSL
OpenSSL uses PBKDF2 by default when you provide a password.
# When you do this:
openssl enc -aes-256-cbc -salt -in secret.txt -out secret.enc
# OpenSSL internally:
# 1. Generates random salt
# 2. Applies PBKDF2 to your password + salt
# 3. Derives 256-bit AES key
# 4. Encrypts file
# You can specify iteration count (higher = slower = stronger)
openssl enc -aes-256-cbc -salt -pbkdf2 -iter 100000 -in secret.txt -out secret.enc
# 100,000 iterations makes password cracking 100,000x slower
Lab: Compare Weak vs Strong Passwords
# Encrypt same file with weak and strong passwords
echo "Sensitive data" > test.txt
# Weak password
openssl enc -aes-256-cbc -salt -in test.txt -out weak.enc -k "password"
# Strong password
openssl enc -aes-256-cbc -salt -in test.txt -out strong.enc -k "kR9$mP2#vL7@nQ4*wX6&jZ8"
# Both files are encrypted, but strong password makes brute force infeasible
# Weak password could be cracked in hours/days
# Strong password would take millennia
Lesson: KDFs help, but strong passwords are still essential.
Up Next
Week 2c covers entropy and randomness, binary encoding (Base64/hex), and putting it all together in an encrypted workflow.
Key Takeaways
- Symmetric encryption uses the same key for encrypt/decrypt
- AES-256 is computationally unbreakable (2^256 key space)
- ECB mode is broken - patterns leak through encryption
- GCM mode is recommended - provides authentication and confidentiality
- ChaCha20 is faster on devices without AES hardware acceleration
- Key Derivation Functions transform weak passwords into strong keys
- Salt + iterations make password cracking 100,000x+ slower