Encryption Deep Dive: Symmetric, Asymmetric, Hashing & Real-World Security Architecture
A Complete Technical Guide for Production Systems
When you tap "Pay" on your banking app, cryptography protects your money through six different encryption operations in under 200 milliseconds. Understanding these operations—symmetric encryption, asymmetric key exchange, hashing, and digital signatures—is essential for building secure systems.
This guide examines cryptography at the implementation level: how algorithms work, when to use each type, and the mistakes that lead to breaches.
Chapter 1: Cryptography Fundamentals
The Four Pillars of Cryptographic Security
┌─────────────────────────────────────────────────────────────────┐ │ SECURITY PROPERTIES │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ CONFIDENTIALITY │ │ ──────────────── │ │ Only authorized parties can read the data. │ │ Achieved by: Encryption │ │ Example: Encrypted database, TLS │ │ │ │ INTEGRITY │ │ ───────── │ │ Data has not been modified in transit or storage. │ │ Achieved by: Hashing, MACs, Digital signatures │ │ Example: File checksums, HMAC in APIs │ │ │ │ AUTHENTICITY │ │ ──────────── │ │ Data comes from the claimed source. │ │ Achieved by: Digital signatures, MACs │ │ Example: Code signing, JWT signatures │ │ │ │ NON-REPUDIATION │ │ ────────────── │ │ Sender cannot deny having sent the message. │ │ Achieved by: Digital signatures (asymmetric only) │ │ Example: Legal contracts, audit logs │ │ │ └─────────────────────────────────────────────────────────────────┘
Encryption vs Hashing vs Encoding
CRITICAL DISTINCTIONS: ───────────────────────────────────────────────────────────────── ENCODING (NOT security): ┌─────────────────────────────────────────────────────────────────┐ │ Purpose: Data format transformation │ │ Reversible: Yes, by anyone │ │ Key required: No │ │ │ │ Examples: │ │ • Base64: SGVsbG8gV29ybGQ= → "Hello World" │ │ • URL encoding: Hello%20World → "Hello World" │ │ • UTF-8, ASCII │ │ │ │ WARNING: Encoding provides ZERO security! │ │ Base64 is not encryption! │ └─────────────────────────────────────────────────────────────────┘ ENCRYPTION (Confidentiality): ┌─────────────────────────────────────────────────────────────────┐ │ Purpose: Hide data from unauthorized parties │ │ Reversible: Yes, but only with correct key │ │ Key required: Yes │ │ │ │ Plaintext ──[Key]──► Ciphertext ──[Key]──► Plaintext │ │ │ │ Examples: │ │ • AES encryption │ │ • RSA encryption │ │ • ChaCha20 │ └─────────────────────────────────────────────────────────────────┘ HASHING (Integrity): ┌─────────────────────────────────────────────────────────────────┐ │ Purpose: Create fixed-size fingerprint of data │ │ Reversible: NO (one-way function) │ │ Key required: No (or yes for HMAC) │ │ │ │ Data ──────► Hash │ │ (any size) (fixed size, e.g., 256 bits) │ │ │ │ Cannot recover original data from hash! │ │ │ │ Examples: │ │ • SHA-256 │ │ • bcrypt (for passwords) │ │ • BLAKE3 │ └─────────────────────────────────────────────────────────────────┘ Comparison: ───────────────────────────────────────────────────────────────── ┌──────────────┬────────────┬──────────────┬──────────────────────┐ │ │ Reversible │ Key Needed │ Use Case │ ├──────────────┼────────────┼──────────────┼──────────────────────┤ │ Encoding │ Yes │ No │ Data format │ │ Encryption │ Yes │ Yes │ Confidentiality │ │ Hashing │ No │ Optional │ Integrity, passwords │ └──────────────┴────────────┴──────────────┴──────────────────────┘
Chapter 2: Symmetric Encryption
How Symmetric Encryption Works
Symmetric encryption uses the same key for both encryption and decryption.
Symmetric Encryption Flow: ───────────────────────────────────────────────────────────────── Same Key Same Key │ │ ▼ ▼ ┌───────┐ ┌─────────┐ ┌─────────┐ ┌───────┐ │ Plain │───►│ Encrypt │─── Network ─►│ Decrypt │───►│ Plain │ │ Text │ └─────────┘ └─────────┘ │ Text │ └───────┘ │ │ └───────┘ ▼ ▼ ┌──────────┐ ┌──────────┐ │ Cipher │ │ Cipher │ │ Text │ │ Text │ └──────────┘ └──────────┘ Key insight: Anyone with the key can both encrypt AND decrypt. Challenge: How do you securely share the key?
AES (Advanced Encryption Standard)
AES is the gold standard for symmetric encryption. Used by governments, banks, and everywhere security matters.
AES Characteristics: ───────────────────────────────────────────────────────────────── Block cipher: Encrypts fixed-size blocks (128 bits = 16 bytes) Key sizes: 128, 192, or 256 bits Speed: ~1 GB/sec with hardware acceleration (AES-NI) AES-256 Security: • 2^256 possible keys • If you tried 1 billion keys per second... • It would take 3.6 × 10^51 years to try all keys • The universe is only 1.4 × 10^10 years old AES Block Encryption: ┌─────────────────────────────────────────────────────────────────┐ │ │ │ 16-byte block: [H][e][l][l][o][ ][W][o][r][l][d][!][.][.][.][.]│ │ │ │ AES operates on 4×4 byte matrix: │ │ ┌────┬────┬────┬────┐ │ │ │ H │ o │ r │ . │ │ │ ├────┼────┼────┼────┤ │ │ │ e │ │ l │ . │ │ │ ├────┼────┼────┼────┤ │ │ │ l │ W │ d │ . │ │ │ ├────┼────┼────┼────┤ │ │ │ l │ o │ ! │ . │ │ │ └────┴────┴────┴────┘ │ │ │ │ 10-14 rounds of: │ │ 1. SubBytes (substitute using S-box) │ │ 2. ShiftRows (rotate rows) │ │ 3. MixColumns (matrix multiplication) │ │ 4. AddRoundKey (XOR with round key) │ │ │ └─────────────────────────────────────────────────────────────────┘
Block Cipher Modes
Raw AES encrypts one block at a time. Modes define how to handle multiple blocks.
Block Cipher Modes Comparison: ───────────────────────────────────────────────────────────────── ECB (Electronic Codebook) - NEVER USE! ┌─────────────────────────────────────────────────────────────────┐ │ │ │ Block 1 ──► AES ──► Ciphertext 1 │ │ Block 2 ──► AES ──► Ciphertext 2 │ │ Block 3 ──► AES ──► Ciphertext 3 │ │ │ │ Problem: Same plaintext block = Same ciphertext block │ │ Leaks patterns! Famous example: ECB-encrypted penguin image │ │ │ │ Original: ████▓▓██░░██ (pattern visible) │ │ ECB: ████▓▓██░░██ (SAME pattern!) │ │ CBC/GCM: ░▓█░▓▓░█▓░▓█ (random-looking) │ │ │ └─────────────────────────────────────────────────────────────────┘ CBC (Cipher Block Chaining) - Good, but use GCM if possible ┌─────────────────────────────────────────────────────────────────┐ │ │ │ IV ─────────────────┐ │ │ ▼ │ │ Block 1 ──► XOR ──► AES ──► Ciphertext 1 ─┐ │ │ │ │ │ ┌──────────────────────┘ │ │ ▼ │ │ Block 2 ──► XOR ──► AES ──► Ciphertext 2 ─┐ │ │ │ │ │ ┌──────────────────────┘ │ │ ▼ │ │ Block 3 ──► XOR ──► AES ──► Ciphertext 3 │ │ │ │ • Each block XORed with previous ciphertext │ │ • IV (Initialization Vector) used for first block │ │ • IV must be random and unique per encryption │ │ • Provides confidentiality but NOT integrity │ │ │ └─────────────────────────────────────────────────────────────────┘ GCM (Galois/Counter Mode) - RECOMMENDED ┌─────────────────────────────────────────────────────────────────┐ │ │ │ Combines CTR mode encryption with GMAC authentication │ │ │ │ IV/Nonce │ │ │ │ │ ▼ │ │ ┌───────┐ ┌───────┐ │ │ │Counter│───►│ AES │───► Keystream │ │ └───────┘ └───────┘ │ │ │ ▼ │ │ Plaintext ─────────────────► XOR ──► Ciphertext │ │ │ │ │ ▼ │ │ ┌────────────────────┐ │ │ │ GMAC (Auth Tag) │ │ │ │ 128-bit integrity │ │ │ └────────────────────┘ │ │ │ │ Benefits: │ │ • Authenticated encryption (confidentiality + integrity) │ │ • Parallelizable (fast) │ │ • Detects tampering │ │ • Industry standard for TLS 1.3 │ │ │ │ CRITICAL: Never reuse IV with same key! │ │ • Reusing IV = complete security failure │ │ • Use random 96-bit IV for each encryption │ │ │ └─────────────────────────────────────────────────────────────────┘
IV (Initialization Vector)
IV Requirements: ───────────────────────────────────────────────────────────────── Purpose: Ensure same plaintext + same key = different ciphertext ┌─────────────────────────────────────────────────────────────────┐ │ Without IV (or reused IV): │ │ │ │ Encrypt("Hello", key) = "x9f2k" │ │ Encrypt("Hello", key) = "x9f2k" ← SAME! Bad. │ │ │ │ Attacker learns: These messages are identical │ └─────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────────┐ │ With random IV: │ │ │ │ Encrypt("Hello", key, IV1) = "x9f2k" │ │ Encrypt("Hello", key, IV2) = "m3p8q" ← Different. Good. │ │ │ │ Attacker cannot tell messages are identical │ └─────────────────────────────────────────────────────────────────┘ IV Rules: • GCM: 96-bit (12 bytes), must be unique (never repeat) • CBC: 128-bit (16 bytes), must be random and unpredictable • IV is NOT secret - transmitted with ciphertext • IV reuse with GCM = catastrophic failure (key recovery possible)
AES Implementation Example
goimport ( "crypto/aes" "crypto/cipher" "crypto/rand" "io" ) // AES-256-GCM Encryption (Recommended) func EncryptAESGCM(plaintext, key []byte) ([]byte, error) { // Key must be 32 bytes for AES-256 if len(key) != 32 { return nil, errors.New("key must be 32 bytes") } block, err := aes.NewCipher(key) if err != nil { return nil, err } gcm, err := cipher.NewGCM(block) if err != nil { return nil, err } // Generate random 12-byte nonce nonce := make([]byte, gcm.NonceSize()) // 12 bytes if _, err := io.ReadFull(rand.Reader, nonce); err != nil { return nil, err } // Encrypt and authenticate // Output: nonce + ciphertext + auth_tag ciphertext := gcm.Seal(nonce, nonce, plaintext, nil) return ciphertext, nil } func DecryptAESGCM(ciphertext, key []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err } gcm, err := cipher.NewGCM(block) if err != nil { return nil, err } nonceSize := gcm.NonceSize() if len(ciphertext) < nonceSize { return nil, errors.New("ciphertext too short") } // Extract nonce and actual ciphertext nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:] // Decrypt and verify authentication tag plaintext, err := gcm.Open(nil, nonce, ciphertext, nil) if err != nil { // Authentication failed - tampered or wrong key return nil, err } return plaintext, nil }
Chapter 3: Asymmetric Encryption
How Asymmetric Encryption Works
Asymmetric encryption uses a key pair: public key (shared) and private key (secret).
Asymmetric Encryption Flow: ───────────────────────────────────────────────────────────────── Key Generation: ┌─────────────────────────────────────────────────────────────────┐ │ Generate mathematically linked key pair: │ │ │ │ Private Key: Keep SECRET (only owner has it) │ │ Public Key: Share FREELY (anyone can have it) │ │ │ │ Mathematical relationship: │ │ • Data encrypted with Public can ONLY be decrypted with Private│ │ • Data signed with Private can be verified with Public │ │ • Cannot derive Private from Public (computationally infeasible)│ └─────────────────────────────────────────────────────────────────┘ Encryption (Confidentiality): ┌─────────────────────────────────────────────────────────────────┐ │ │ │ Alice wants to send secret message to Bob │ │ │ │ Alice Bob │ │ │ │ │ │ │◄───────── Bob's Public Key ─────────────────│ │ │ │ (Bob shares freely) │ │ │ │ │ │ │ │ Encrypt with Bob's Public Key │ │ │ │ ┌─────────────────────────────┐ │ │ │ │ │ "Secret" + PubKey = "x8f2j" │ │ │ │ │ └─────────────────────────────┘ │ │ │ │ │ │ │ │────────── Ciphertext "x8f2j" ──────────────►│ │ │ │ │ │ │ │ Decrypt with Private Key │ │ │ ┌─────────────────────────────┐ │ │ │ │ "x8f2j" + PrivKey = "Secret"│ │ │ │ └─────────────────────────────┘ │ │ │ │ Only Bob can decrypt (only Bob has private key) │ │ │ └─────────────────────────────────────────────────────────────────┘
RSA Algorithm
RSA is the most widely used asymmetric algorithm, based on the difficulty of factoring large primes.
RSA Overview: ───────────────────────────────────────────────────────────────── Key Generation: 1. Choose two large primes: p, q (each ~1024 bits for RSA-2048) 2. Compute n = p × q (this is the modulus) 3. Compute φ(n) = (p-1)(q-1) 4. Choose public exponent e (commonly 65537) 5. Compute private exponent d where e × d ≡ 1 (mod φ(n)) Public Key: (n, e) Private Key: (n, d) Encryption: ciphertext = message^e mod n Decryption: message = ciphertext^d mod n Security: • Based on difficulty of factoring n back to p and q • RSA-2048: n is 2048 bits (~617 decimal digits) • No known algorithm can factor this in reasonable time • Quantum computers could break it (Shor's algorithm) Performance: • SLOW compared to symmetric encryption • RSA-2048 encryption: ~1,000 operations/second • AES-256: ~1,000,000,000 operations/second • 1,000,000x slower! That's why RSA is used for key exchange, not bulk encryption.
ECC (Elliptic Curve Cryptography)
ECC provides equivalent security to RSA with smaller keys.
ECC vs RSA Key Size Comparison: ───────────────────────────────────────────────────────────────── ┌────────────────┬────────────────┬────────────────────────────┐ │ Security Level │ RSA Key Size │ ECC Key Size │ ├────────────────┼────────────────┼────────────────────────────┤ │ 80 bits │ 1024 bits │ 160 bits │ │ 112 bits │ 2048 bits │ 224 bits │ │ 128 bits │ 3072 bits │ 256 bits (P-256) │ │ 192 bits │ 7680 bits │ 384 bits (P-384) │ │ 256 bits │ 15360 bits │ 512 bits (P-521) │ └────────────────┴────────────────┴────────────────────────────┘ ECC Benefits: • Smaller keys = faster operations • Less bandwidth for key exchange • Less storage for certificates • Better for mobile/IoT devices Common Curves: • P-256 (secp256r1): NIST standard, widely supported • P-384: Higher security • Curve25519: Modern, fast, designed by Daniel Bernstein • secp256k1: Used by Bitcoin ECC for Key Exchange (ECDH): ┌─────────────────────────────────────────────────────────────────┐ │ Alice Bob │ │ │ │ │ │ │ Generate: Generate: │ │ │ │ a (private) b (private) │ │ │ │ A = a × G (public) B = b × G │ │ │ │ │ │ │ │──────────────── A ─────────────────────────►│ │ │ │◄───────────────── B ────────────────────────│ │ │ │ │ │ │ │ Shared secret: Shared secret:│ │ │ │ S = a × B S = b × A │ │ │ │ = a × (b × G) = b × (a × G)│ │ │ │ = ab × G = ab × G │ │ │ │ │ │ │ Both compute same S without revealing a or b! │ └─────────────────────────────────────────────────────────────────┘
Chapter 4: Hybrid Encryption
Why Hybrid?
Neither symmetric nor asymmetric alone is ideal for all scenarios.
The Problem: ───────────────────────────────────────────────────────────────── SYMMETRIC (AES): ✓ Very fast ✗ Key distribution problem (how to share key securely?) ASYMMETRIC (RSA/ECC): ✓ Solves key distribution (public key can be shared openly) ✗ Very slow (1000x slower than symmetric) ✗ Size limitations (RSA-2048 can only encrypt ~245 bytes) SOLUTION: Hybrid Encryption ───────────────────────────────────────────────────────────────── Use asymmetric to exchange a symmetric key. Use symmetric to encrypt actual data. Best of both worlds!
Hybrid Encryption Flow
Hybrid Encryption in Practice: ───────────────────────────────────────────────────────────────── ┌─────────────────────────────────────────────────────────────────┐ │ SENDER (Alice) │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 1. Generate random AES key (256 bits) │ │ session_key = random(32 bytes) │ │ │ │ 2. Encrypt message with AES (fast) │ │ encrypted_message = AES_GCM(message, session_key) │ │ │ │ 3. Encrypt session key with recipient's RSA public key │ │ encrypted_key = RSA_Encrypt(session_key, bob_public_key) │ │ │ │ 4. Send both: │ │ { encrypted_key, encrypted_message } │ │ │ └─────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ RECIPIENT (Bob) │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 1. Decrypt session key with RSA private key │ │ session_key = RSA_Decrypt(encrypted_key, bob_private_key) │ │ │ │ 2. Decrypt message with AES (fast) │ │ message = AES_GCM_Decrypt(encrypted_message, session_key) │ │ │ └─────────────────────────────────────────────────────────────────┘ Result: • RSA only encrypts 32 bytes (the AES key) - fast enough • AES encrypts gigabytes of data - very fast • Key is securely transmitted without pre-shared secret
TLS Handshake (Real-World Hybrid)
TLS 1.3 Handshake: ───────────────────────────────────────────────────────────────── ┌─────────────────────────────────────────────────────────────────┐ │ CLIENT SERVER │ │ │ │ │ │ │ ClientHello │ │ │ │ • Supported cipher suites │ │ │ │ • Client random │ │ │ │ • Key share (ECDH public key) │ │ │ │─────────────────────────────────────────────►│ │ │ │ │ │ │ │ ServerHello │ │ │ │ • Chosen cipher suite │ │ │ │ • Server random │ │ │ │ • Key share (ECDH public key) │ │ │ │ Certificate │ │ │ │ • Server's X.509 certificate │ │ │ │ CertificateVerify │ │ │ │ • Signature proving key ownership │ │ │ │ Finished │ │ │ │ • MAC of handshake │ │ │ │◄─────────────────────────────────────────────│ │ │ │ │ │ │ │ Both compute shared secret: │ │ │ │ shared_secret = ECDH(client_priv, server_pub) │ │ │ = ECDH(server_priv, client_pub) │ │ │ │ │ │ │ Derive session keys: │ │ │ │ client_write_key, server_write_key │ │ │ │ client_write_iv, server_write_iv │ │ │ │ │ │ │ │ Finished │ │ │ │ • MAC of handshake │ │ │ │─────────────────────────────────────────────►│ │ │ │ │ │ │ │══════════ ENCRYPTED APPLICATION DATA ═══════│ │ │ │ (AES-256-GCM or ChaCha20-Poly1305) │ │ │ │◄════════════════════════════════════════════►│ │ │ │ └─────────────────────────────────────────────────────────────────┘ TLS 1.3 Improvements over TLS 1.2: • 1-RTT handshake (faster) • Removed insecure algorithms (RSA key exchange, CBC) • Perfect Forward Secrecy required (ephemeral ECDH) • Encrypted certificates (privacy)
Chapter 5: Hashing (One-Way Functions)
Hash Function Properties
Cryptographic Hash Requirements: ───────────────────────────────────────────────────────────────── 1. DETERMINISTIC Same input always produces same output SHA256("hello") = 2cf24dba... (always) 2. FIXED OUTPUT SIZE Any input size → same output size SHA256("a") = 32 bytes SHA256("entire book contents...") = 32 bytes 3. ONE-WAY (Pre-image Resistance) Given hash, cannot find input Given "2cf24dba...", cannot find "hello" 4. COLLISION RESISTANCE Cannot find two inputs with same hash Cannot find x,y where SHA256(x) = SHA256(y) 5. AVALANCHE EFFECT Small input change → completely different hash SHA256("hello") = 2cf24dba5fb0a30e26e83b2ac5b9e29e... SHA256("hellp") = 8457d2e2a9d7c3f1b4e5a6d8c9f0e2b4... ^^^^^^^^^ completely different Hash Function Visualization: ───────────────────────────────────────────────────────────────── Input (any size) Output (fixed size) ┌────────────────────┐ ┌──────────────────────┐ │ "Hello World" │ │ 64 hex characters │ │ (11 bytes) │ │ (32 bytes / 256 bits)│ └────────────────────┘ └──────────────────────┘ │ ▲ │ ┌──────────┐ │ └────────►│ SHA-256 │──────────┘ └──────────┘ ┌────────────────────┐ ┌──────────────────────┐ │ 1GB video file │ │ 64 hex characters │ │ (1,073,741,824 B) │ │ (same 32 bytes!) │ └────────────────────┘ └──────────────────────┘ │ ▲ │ ┌──────────┐ │ └────────►│ SHA-256 │──────────┘ └──────────┘
Hash Algorithms Comparison
┌────────────────┬────────────┬──────────────┬─────────────────────┐ │ Algorithm │ Output │ Security │ Use Case │ ├────────────────┼────────────┼──────────────┼─────────────────────┤ │ MD5 │ 128 bits │ BROKEN ✗ │ Never (checksums ok)│ │ SHA-1 │ 160 bits │ BROKEN ✗ │ Never │ │ SHA-256 │ 256 bits │ Secure ✓ │ General purpose │ │ SHA-384 │ 384 bits │ Secure ✓ │ Higher security │ │ SHA-512 │ 512 bits │ Secure ✓ │ Highest security │ │ SHA-3 (Keccak) │ Variable │ Secure ✓ │ Alternative to SHA-2│ │ BLAKE3 │ Variable │ Secure ✓ │ Speed-optimized │ │ bcrypt │ 184 bits │ Secure ✓ │ Passwords only │ │ Argon2 │ Variable │ Secure ✓ │ Passwords (best) │ └────────────────┴────────────┴──────────────┴─────────────────────┘ Speed Comparison (approximate): ───────────────────────────────────────────────────────────────── SHA-256: ~500 MB/s SHA-512: ~700 MB/s BLAKE3: ~2000 MB/s (fastest secure hash) bcrypt: ~4 hashes/sec (intentionally slow!) Argon2: ~10 hashes/sec (intentionally slow!) Why slow is good for passwords: • Attacker trying to crack password must compute hash • Fast hash = attacker can try billions per second • Slow hash = attacker limited to few per second
Password Hashing
Password Hashing Best Practices: ───────────────────────────────────────────────────────────────── WRONG: Plain hash SHA256("password123") = ef92b778bafe771e89245b89ecbc08a44a4e166c06659911881f383d4473e94f Problem: Rainbow tables (pre-computed hash → password lookup) WRONG: Hash with pepper SHA256("password123" + "secret_pepper") Problem: Same password = same hash (attacker can detect duplicates) CORRECT: Salted slow hash ┌─────────────────────────────────────────────────────────────────┐ │ │ │ Registration: │ │ 1. Generate random salt: salt = random(16 bytes) │ │ 2. Hash: hash = bcrypt(password + salt, cost=12) │ │ 3. Store: $2b$12$salt...hash... │ │ (bcrypt embeds salt in output) │ │ │ │ Login: │ │ 1. Retrieve stored hash │ │ 2. Extract salt from stored hash │ │ 3. Compute: computed = bcrypt(input + salt, cost) │ │ 4. Compare: stored_hash == computed │ │ │ └─────────────────────────────────────────────────────────────────┘ Argon2id (Current Recommendation): ───────────────────────────────────────────────────────────────── hash = argon2id( password, salt = random(16 bytes), time_cost = 1, // iterations memory_cost = 64MB, // RAM required parallelism = 4 // threads ) Why Argon2id? • Memory-hard: Requires lots of RAM to compute • GPU-resistant: GPUs have less memory per core • Side-channel resistant: Combines Argon2i and Argon2d • Winner of Password Hashing Competition (2015)
Rainbow Table Attack
Rainbow Table Attack Explained: ───────────────────────────────────────────────────────────────── Pre-computation (attacker does once): ┌─────────────────────────────────────────────────────────────────┐ │ password → hash │ │ "password" → "5e884898da28..." │ │ "password1" → "0b14d501a594..." │ │ "123456" → "8d969eef6eca..." │ │ "qwerty" → "d8578edf8458..." │ │ ... billions of entries ... │ │ │ │ Store in searchable table (by hash) │ └─────────────────────────────────────────────────────────────────┘ Attack: ┌─────────────────────────────────────────────────────────────────┐ │ 1. Steal database with hashed passwords │ │ user_id | password_hash │ │ 1 | 5e884898da28... │ │ │ │ 2. Look up hash in rainbow table │ │ 5e884898da28... → "password" │ │ │ │ 3. Now attacker knows: User 1's password is "password" │ └─────────────────────────────────────────────────────────────────┘ Why Salt Defeats This: ┌─────────────────────────────────────────────────────────────────┐ │ Without salt: │ │ All users with "password" → same hash → single lookup │ │ │ │ With unique salt per user: │ │ User 1: bcrypt("password" + "salt1") → hash1 │ │ User 2: bcrypt("password" + "salt2") → hash2 │ │ Different salts → different hashes → different lookups │ │ │ │ Attacker would need rainbow table for EVERY possible salt │ │ 16-byte salt = 2^128 possible salts = impossible │ └─────────────────────────────────────────────────────────────────┘
Chapter 6: Digital Signatures
How Digital Signatures Work
Digital Signature Flow: ───────────────────────────────────────────────────────────────── PURPOSE: Prove authenticity and integrity of data SIGNING (Private Key): ┌─────────────────────────────────────────────────────────────────┐ │ │ │ Document: "I agree to pay $100" │ │ │ │ │ ▼ │ │ ┌──────────────────┐ │ │ │ Hash (SHA-256) │ │ │ └────────┬─────────┘ │ │ │ │ │ ▼ │ │ Hash: "a3f2c9d1..." │ │ │ │ │ ▼ │ │ ┌──────────────────┐ │ │ │ Encrypt hash │ ← Private Key │ │ │ with Private Key │ │ │ └────────┬─────────┘ │ │ │ │ │ ▼ │ │ Signature: "x8f2k9m..." │ │ │ │ Output: Document + Signature │ │ │ └─────────────────────────────────────────────────────────────────┘ VERIFICATION (Public Key): ┌─────────────────────────────────────────────────────────────────┐ │ │ │ Received: Document + Signature │ │ │ │ Step 1: Decrypt signature with signer's public key │ │ ┌──────────────────┐ │ │ │ Signature │ │ │ │ "x8f2k9m..." │ │ │ └────────┬─────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────────┐ │ │ │ Decrypt with │ ← Public Key │ │ │ Public Key │ │ │ └────────┬─────────┘ │ │ │ │ │ ▼ │ │ Recovered hash: "a3f2c9d1..." │ │ │ │ Step 2: Hash the received document │ │ ┌──────────────────┐ │ │ │ Hash (SHA-256) │ │ │ └────────┬─────────┘ │ │ │ │ │ ▼ │ │ Computed hash: "a3f2c9d1..." │ │ │ │ Step 3: Compare │ │ Recovered hash == Computed hash ? │ │ │ │ YES → Valid signature ✓ │ │ • Document wasn't modified (integrity) │ │ • Signer has private key (authenticity) │ │ • Signer can't deny signing (non-repudiation) │ │ │ │ NO → Invalid signature ✗ │ │ • Document was modified, OR │ │ • Wrong public key, OR │ │ • Signature is fake │ │ │ └─────────────────────────────────────────────────────────────────┘
JWT Signature Example
JWT Signing (RS256): ───────────────────────────────────────────────────────────────── JWT Structure: header.payload.signature ┌─────────────────────────────────────────────────────────────────┐ │ SIGNING: │ │ │ │ 1. Encode header and payload │ │ header = base64url({"alg":"RS256","typ":"JWT"}) │ │ payload = base64url({"sub":"123","exp":1704067200}) │ │ │ │ 2. Create signing input │ │ signing_input = header + "." + payload │ │ │ │ 3. Sign with private key │ │ signature = base64url(RSA_Sign(SHA256(signing_input), priv))│ │ │ │ 4. Combine │ │ jwt = signing_input + "." + signature │ │ │ └─────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────────┐ │ VERIFICATION: │ │ │ │ 1. Split JWT into parts │ │ parts = jwt.split(".") │ │ header, payload, signature = parts[0], parts[1], parts[2] │ │ │ │ 2. Decode header, check algorithm │ │ alg = decode(header)["alg"] │ │ CRITICAL: Verify alg is what you expect (RS256) │ │ │ │ 3. Verify signature │ │ signing_input = header + "." + payload │ │ valid = RSA_Verify(SHA256(signing_input), signature, pub) │ │ │ │ 4. If valid, decode and use payload │ │ claims = decode(payload) │ │ │ └─────────────────────────────────────────────────────────────────┘
Chapter 7: Encryption At Rest vs In Transit
Encryption In Transit
Encryption In Transit (TLS): ───────────────────────────────────────────────────────────────── Protects data as it travels over the network. ┌─────────────────────────────────────────────────────────────────┐ │ │ │ Client Internet Server │ │ ┌──────┐ ┌─────────┐ ┌──────┐ │ │ │ │ TLS/HTTPS │ Can see │ TLS/HTTPS │ │ │ │ │ App │════════════▶│encrypted│═════════════▶│ API │ │ │ │ │ │ traffic │ │ │ │ │ └──────┘ │ only │ └──────┘ │ │ └─────────┘ │ │ (Attacker can't │ │ read content) │ │ │ └─────────────────────────────────────────────────────────────────┘ Best Practices: • TLS 1.3 only (disable TLS 1.0, 1.1, 1.2 if possible) • Strong cipher suites only (AES-256-GCM, ChaCha20-Poly1305) • HSTS (HTTP Strict Transport Security) • Certificate pinning for mobile apps • mTLS for service-to-service
Encryption At Rest
Encryption At Rest: ───────────────────────────────────────────────────────────────── Protects data stored on disk (databases, files, backups). FULL DISK ENCRYPTION (FDE): ┌─────────────────────────────────────────────────────────────────┐ │ │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ ENCRYPTED DISK │ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ │ │ OS Files │ │ App Data │ │ Database │ │ Logs │ │ │ │ │ │(encrypted)│ │(encrypted)│ │(encrypted)│ │(encrypted)│ │ │ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │ │ └──────────────────────────────────────────────────────────┘ │ │ │ │ Key stored in: TPM / HSM / Secure boot │ │ │ │ Protects against: │ │ • Physical theft of disk │ │ • Improper disk disposal │ │ │ │ Does NOT protect against: │ │ • Running system compromise (data decrypted in memory) │ │ • Application-level attacks │ │ │ └─────────────────────────────────────────────────────────────────┘ DATABASE-LEVEL ENCRYPTION: ┌─────────────────────────────────────────────────────────────────┐ │ │ │ TRANSPARENT DATA ENCRYPTION (TDE): │ │ • Encrypts entire database files │ │ • Transparent to application │ │ • Key managed by database │ │ │ │ COLUMN-LEVEL ENCRYPTION: │ │ • Encrypt specific sensitive columns │ │ • More granular control │ │ • Can use different keys per column │ │ │ │ Example: │ │ ┌────────────────────────────────────────────────────────────┐ │ │ │ id │ name │ email │ ssn_encrypted │ │ │ │ 1 │ John Doe │ john@example.com │ AES(123-45-6789) │ │ │ │ 2 │ Jane Doe │ jane@example.com │ AES(987-65-4321) │ │ │ └────────────────────────────────────────────────────────────┘ │ │ │ │ SSN encrypted, other columns not (for query performance) │ │ │ └─────────────────────────────────────────────────────────────────┘ APPLICATION-LEVEL ENCRYPTION: ┌─────────────────────────────────────────────────────────────────┐ │ │ │ Encrypt before storing, decrypt after reading │ │ │ │ Application Database │ │ ┌────────────┐ ┌────────────────┐ │ │ │ plaintext │ │ │ │ │ │ │ │ │ ciphertext │ │ │ │ ▼ │ INSERT │ (encrypted) │ │ │ │ encrypt ───│───────────────►│ │ │ │ │ │ │ │ │ │ │ plaintext │ SELECT │ │ │ │ │ ▲ │◄───────────────│ │ │ │ │ decrypt ◄──│ │ │ │ │ └────────────┘ └────────────────┘ │ │ │ │ Benefits: │ │ • Database admin can't read data │ │ • Different keys per tenant (multi-tenant) │ │ • Client-side encryption possible │ │ │ │ Challenges: │ │ • Can't search encrypted columns (without special techniques) │ │ • Key management complexity │ │ • Performance overhead │ │ │ └─────────────────────────────────────────────────────────────────┘
Chapter 8: Key Management
Key Management Architecture
Key Management System (KMS): ───────────────────────────────────────────────────────────────── ┌─────────────────────────────────────────────────────────────────┐ │ KEY MANAGEMENT ARCHITECTURE │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────┐ │ │ │ Master Key (KEK) │ │ │ │ Stored in HSM │ │ │ │ Never exported │ │ │ └─────────┬───────────┘ │ │ │ │ │ ┌─────────────────┼─────────────────┐ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │ │ │ Data Key 1 │ │ Data Key 2 │ │ Data Key 3 │ │ │ │ (encrypted │ │ (encrypted │ │ (encrypted │ │ │ │ with KEK) │ │ with KEK) │ │ with KEK) │ │ │ └───────┬───────┘ └───────┬───────┘ └───────┬───────┘ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │ │ │ Database │ │ Files │ │ Backup │ │ │ │ encrypted │ │ encrypted │ │ encrypted │ │ │ └───────────────┘ └───────────────┘ └───────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────┘ Envelope Encryption: ───────────────────────────────────────────────────────────────── 1. Master Key (KEK - Key Encryption Key) • Lives only in HSM • Never exported or seen • Used to encrypt/decrypt data keys 2. Data Key (DEK - Data Encryption Key) • Generated for each data set • Used to encrypt actual data • Encrypted with KEK when stored Encryption: ┌─────────────────────────────────────────────────────────────────┐ │ 1. Generate random DEK │ │ 2. Encrypt data with DEK │ │ 3. Encrypt DEK with KEK (call to KMS/HSM) │ │ 4. Store: encrypted_data + encrypted_dek │ └─────────────────────────────────────────────────────────────────┘ Decryption: ┌─────────────────────────────────────────────────────────────────┐ │ 1. Retrieve encrypted_dek │ │ 2. Decrypt DEK with KEK (call to KMS/HSM) │ │ 3. Decrypt data with DEK │ └─────────────────────────────────────────────────────────────────┘
Key Rotation
Key Rotation Strategy: ───────────────────────────────────────────────────────────────── Why Rotate? • Limit damage if key compromised • Compliance requirements (PCI-DSS: annual rotation) • Reduce cryptographic wear Rotation Process: ┌─────────────────────────────────────────────────────────────────┐ │ │ │ TIME 0: Key v1 active │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ Data encrypted with DEK-v1 │ │ │ │ DEK-v1 encrypted with KEK-v1 │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ TIME 1: Rotate KEK │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ 1. Generate KEK-v2 │ │ │ │ 2. Re-encrypt all DEKs with KEK-v2 │ │ │ │ 3. Delete KEK-v1 (after verification) │ │ │ │ │ │ │ │ Data stays encrypted with same DEKs │ │ │ │ Only DEK wrappers change │ │ │ │ (Much faster than re-encrypting all data) │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ TIME 2: Rotate DEK (for new data) │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ 1. Generate DEK-v2 │ │ │ │ 2. New data encrypted with DEK-v2 │ │ │ │ 3. Old data stays with DEK-v1 (or re-encrypt over time)│ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────┘ Multi-Version Key Support: ┌─────────────────────────────────────────────────────────────────┐ │ Key ID in metadata allows using multiple key versions │ │ │ │ Encrypted data: { │ │ "key_id": "dek-2024-01-v2", │ │ "algorithm": "AES-256-GCM", │ │ "ciphertext": "x8f2k9m...", │ │ "nonce": "abc123..." │ │ } │ │ │ │ Decryption: Lookup key by key_id, then decrypt │ │ │ └─────────────────────────────────────────────────────────────────┘
Cloud KMS Options
Cloud KMS Comparison: ───────────────────────────────────────────────────────────────── ┌────────────────┬─────────────────────────────────────────────────┐ │ Service │ Description │ ├────────────────┼─────────────────────────────────────────────────┤ │ AWS KMS │ • Integrated with AWS services │ │ │ • Automatic key rotation (annual) │ │ │ • CloudHSM option for dedicated hardware │ ├────────────────┼─────────────────────────────────────────────────┤ │ Google Cloud │ • Software or HSM-backed keys │ │ KMS │ • Automatic rotation configurable │ │ │ • IAM integration │ ├────────────────┼─────────────────────────────────────────────────┤ │ Azure Key │ • Vault for secrets, keys, certificates │ │ Vault │ • HSM-backed (Premium tier) │ │ │ • Managed HSM option │ ├────────────────┼─────────────────────────────────────────────────┤ │ HashiCorp │ • Self-hosted or cloud │ │ Vault │ • Dynamic secrets │ │ │ • Transit secrets engine (encryption as service)│ └────────────────┴─────────────────────────────────────────────────┘ AWS KMS Usage Example: ───────────────────────────────────────────────────────────────── // Generate data key aws kms generate-data-key \ --key-id alias/my-key \ --key-spec AES_256 // Response: { "Plaintext": "<base64-encoded-32-byte-key>", // Use for encryption "CiphertextBlob": "<base64-encrypted-key>", // Store with data "KeyId": "arn:aws:kms:..." } // Decrypt data key (when needed) aws kms decrypt \ --ciphertext-blob fileb://encrypted_key.bin // Response: { "Plaintext": "<base64-encoded-32-byte-key>", // Use for decryption "KeyId": "arn:aws:kms:..." }
Chapter 9: Real-World Fintech Example
Secure Payment System Architecture
Payment Processing Security Architecture: ───────────────────────────────────────────────────────────────── ┌─────────────────────────────────────────────────────────────────────────┐ │ SECURE PAYMENT FLOW │ ├─────────────────────────────────────────────────────────────────────────┤ │ │ │ Mobile App │ │ ┌────────────────────────────────────────────────────────────────┐ │ │ │ 1. User enters card: 4111-1111-1111-1111 │ │ │ │ │ │ │ │ 2. Client-side encryption (before leaving device) │ │ │ │ encrypted_card = RSA_Encrypt(card, server_public_key) │ │ │ │ │ │ │ │ 3. TLS 1.3 connection established │ │ │ │ Certificate pinning verified │ │ │ │ │ │ │ └────────────────────────────────────────────────────────────────┘ │ │ │ │ │ │ HTTPS (TLS 1.3) │ │ │ Encryption Layer 1: TLS │ │ │ Encryption Layer 2: RSA (card) │ │ ▼ │ │ API Gateway │ │ ┌────────────────────────────────────────────────────────────────┐ │ │ │ 4. TLS termination │ │ │ │ 5. JWT validation │ │ │ │ 6. Rate limiting │ │ │ │ 7. Forward to Payment Service │ │ │ └────────────────────────────────────────────────────────────────┘ │ │ │ │ │ │ mTLS (service mesh) │ │ ▼ │ │ Payment Service │ │ ┌────────────────────────────────────────────────────────────────┐ │ │ │ 8. Decrypt card with RSA private key (from HSM) │ │ │ │ plaintext_card = HSM.RSA_Decrypt(encrypted_card) │ │ │ │ │ │ │ │ 9. Validate card format, Luhn check │ │ │ │ │ │ │ │ 10. Create token (tokenization) │ │ │ │ token = random(16 bytes) │ │ │ │ Store: token → AES_Encrypt(card, data_key) │ │ │ │ │ │ │ │ 11. Send token to processor (never raw card) │ │ │ │ │ │ │ └────────────────────────────────────────────────────────────────┘ │ │ │ │ │ │ Encrypted connection │ │ ▼ │ │ Token Vault (PCI-compliant) │ │ ┌────────────────────────────────────────────────────────────────┐ │ │ │ 12. Store encrypted card data │ │ │ │ │ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ │ │ token │ encrypted_card (AES-256-GCM) │ key_id │ │ │ │ │ │ tok_abc123 │ x8f2k9m... │ dek_001 │ │ │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ │ │ │ │ Data encryption keys encrypted with KMS master key │ │ │ │ HSM stores master key (never exported) │ │ │ └────────────────────────────────────────────────────────────────┘ │ │ │ │ │ │ │ │ Audit Log (tamper-evident) │ │ ┌────────────────────────────────────────────────────────────────┐ │ │ │ 13. Log all access (encrypted, signed) │ │ │ │ │ │ │ │ { │ │ │ │ "timestamp": "2024-01-15T10:30:00Z", │ │ │ │ "action": "card_tokenized", │ │ │ │ "user_id": "user_123", │ │ │ │ "token_id": "tok_abc123", │ │ │ │ "ip": "203.0.113.42", │ │ │ │ "signature": "RSA_Sign(log_entry, audit_key)" │ │ │ │ } │ │ │ └────────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────┘ Security Layers: ───────────────────────────────────────────────────────────────── Layer 1: Transport (TLS 1.3) Layer 2: Application (RSA encryption of card) Layer 3: Storage (AES-256-GCM encryption at rest) Layer 4: Key Management (HSM, envelope encryption) Layer 5: Tokenization (card never leaves vault) Layer 6: Audit (signed, tamper-evident logs)
Chapter 10: Common Cryptographic Mistakes
CRITICAL MISTAKES TO AVOID: ───────────────────────────────────────────────────────────────── 1. HARDCODING KEYS ┌─────────────────────────────────────────────────────────────────┐ │ WRONG: │ │ const AES_KEY = "mySecretKey12345" // In source code │ │ │ │ RIGHT: │ │ key := os.Getenv("AES_KEY") // From environment │ │ // Or: key := kms.GetKey("key-id") // From KMS │ └─────────────────────────────────────────────────────────────────┘ 2. REUSING IV/NONCE ┌─────────────────────────────────────────────────────────────────┐ │ WRONG: │ │ var iv = []byte("0000000000000000") // Static IV! │ │ gcm.Seal(iv, iv, plaintext, nil) │ │ │ │ RIGHT: │ │ iv := make([]byte, 12) │ │ rand.Read(iv) // Random IV each time │ │ gcm.Seal(iv, iv, plaintext, nil) │ │ │ │ Impact of reuse with GCM: COMPLETE key recovery possible! │ └─────────────────────────────────────────────────────────────────┘ 3. WEAK RANDOM NUMBER GENERATOR ┌─────────────────────────────────────────────────────────────────┐ │ WRONG: │ │ import "math/rand" │ │ key := make([]byte, 32) │ │ rand.Read(key) // Predictable! │ │ │ │ RIGHT: │ │ import "crypto/rand" │ │ key := make([]byte, 32) │ │ rand.Read(key) // Cryptographically secure │ └─────────────────────────────────────────────────────────────────┘ 4. USING ECB MODE ┌─────────────────────────────────────────────────────────────────┐ │ WRONG: │ │ block.Encrypt(ciphertext, plaintext) // ECB, leaks patterns │ │ │ │ RIGHT: │ │ gcm.Seal(nonce, nonce, plaintext, nil) // GCM │ └─────────────────────────────────────────────────────────────────┘ 5. ENCRYPTION WITHOUT AUTHENTICATION ┌─────────────────────────────────────────────────────────────────┐ │ WRONG: │ │ CBC encryption without HMAC // Can be modified without detect │ │ │ │ RIGHT: │ │ AES-GCM (authenticated encryption) │ │ // Or: Encrypt-then-MAC (AES-CBC + HMAC) │ └─────────────────────────────────────────────────────────────────┘ 6. COMPARING HASHES INCORRECTLY ┌─────────────────────────────────────────────────────────────────┐ │ WRONG: │ │ if computedHash == storedHash { // Timing attack vulnerable │ │ │ │ RIGHT: │ │ import "crypto/subtle" │ │ if subtle.ConstantTimeCompare(computedHash, storedHash) == 1 { │ │ // Constant-time comparison │ │ } │ └─────────────────────────────────────────────────────────────────┘ 7. STORING PRIVATE KEYS UNPROTECTED ┌─────────────────────────────────────────────────────────────────┐ │ WRONG: │ │ privateKey saved in: /app/keys/private.pem (on disk, readable)│ │ │ │ RIGHT: │ │ • Store in HSM (never exported) │ │ • Or: Encrypt with passphrase │ │ • Or: Use KMS │ │ • Restrict file permissions (chmod 600) │ └─────────────────────────────────────────────────────────────────┘ 8. ROLLING YOUR OWN CRYPTO ┌─────────────────────────────────────────────────────────────────┐ │ WRONG: │ │ func myEncrypt(data []byte) []byte { │ │ for i := range data { │ │ data[i] ^= secret[i % len(secret)] // Custom XOR │ │ } │ │ return data │ │ } │ │ │ │ RIGHT: │ │ Use established libraries: crypto/aes, crypto/cipher │ │ "Don't roll your own crypto" - universal security wisdom │ └─────────────────────────────────────────────────────────────────┘
Chapter 11: Comparison Table
Cryptographic Primitives Comparison: ───────────────────────────────────────────────────────────────── ┌──────────────┬────────────┬───────────┬─────────────────────────┐ │ Type │ Reversible │ Speed │ Use Case │ ├──────────────┼────────────┼───────────┼─────────────────────────┤ │ AES-256-GCM │ Yes │ Very Fast │ Data encryption │ │ ChaCha20 │ Yes │ Very Fast │ TLS, mobile │ │ RSA-2048 │ Yes │ Slow │ Key exchange, signatures│ │ ECC P-256 │ Yes │ Fast │ Key exchange, TLS │ │ SHA-256 │ No │ Fast │ Integrity, fingerprints │ │ SHA-3 │ No │ Fast │ Integrity (alternative) │ │ BLAKE3 │ No │ Very Fast │ Checksums, integrity │ │ bcrypt │ No │ Slow* │ Password hashing │ │ Argon2id │ No │ Slow* │ Password hashing (best) │ │ HMAC-SHA256 │ No │ Fast │ Message authentication │ └──────────────┴────────────┴───────────┴─────────────────────────┘ * Intentionally slow for security
Chapter 12: Advanced Topics
Perfect Forward Secrecy (PFS)
Perfect Forward Secrecy: ───────────────────────────────────────────────────────────────── WITHOUT PFS: ┌─────────────────────────────────────────────────────────────────┐ │ • Server uses same RSA key pair for years │ │ • Attacker records encrypted traffic │ │ • Years later, attacker compromises server private key │ │ • Attacker decrypts ALL past recorded traffic! │ └─────────────────────────────────────────────────────────────────┘ WITH PFS (Ephemeral Keys): ┌─────────────────────────────────────────────────────────────────┐ │ • Each session uses fresh ECDHE key pair │ │ • Ephemeral keys deleted after session │ │ • Server long-term key only used for authentication │ │ • Even if long-term key compromised later: │ │ → Past sessions can't be decrypted │ │ → Ephemeral keys are gone │ │ │ │ TLS 1.3: PFS required (no non-PFS cipher suites) │ └─────────────────────────────────────────────────────────────────┘
Zero-Knowledge Proofs (Brief)
Zero-Knowledge Proof Concept: ───────────────────────────────────────────────────────────────── Prove you know something without revealing what you know. Example: Password authentication ┌─────────────────────────────────────────────────────────────────┐ │ TRADITIONAL: │ │ Client sends: password → Server checks hash │ │ Problem: Server sees password in transit (even briefly) │ │ │ │ ZERO-KNOWLEDGE: │ │ Client proves: "I know password" without sending password │ │ Server verifies: Proof is valid │ │ Server never learns: What the password is │ │ │ │ Applications: │ │ • SRP (Secure Remote Password) protocol │ │ • Blockchain privacy (zk-SNARKs) │ │ • Age verification without revealing birthdate │ └─────────────────────────────────────────────────────────────────┘
Quantum Threat Overview
Quantum Computing Threat: ───────────────────────────────────────────────────────────────── VULNERABLE (to quantum computers): ┌─────────────────────────────────────────────────────────────────┐ │ • RSA (Shor's algorithm breaks factoring) │ │ • ECC (Shor's algorithm breaks discrete log) │ │ • DH/ECDH (same reason) │ │ │ │ Timeline: Estimates vary, 10-20+ years │ │ Risk: "Harvest now, decrypt later" attacks │ │ (Record encrypted data today, decrypt when quantum ready)│ └─────────────────────────────────────────────────────────────────┘ QUANTUM-RESISTANT: ┌─────────────────────────────────────────────────────────────────┐ │ • AES-256 (Grover's algorithm weakens to 128-bit, still safe) │ │ • SHA-256 (similar, still safe) │ │ • Post-quantum algorithms (NIST standardizing): │ │ - CRYSTALS-Kyber (key exchange) │ │ - CRYSTALS-Dilithium (signatures) │ │ - SPHINCS+ (signatures) │ │ │ │ Action: Start planning hybrid schemes │ │ (classical + post-quantum for transition) │ └─────────────────────────────────────────────────────────────────┘
Conclusion
Cryptography is foundational to modern security. Key takeaways:
- Use established algorithms: AES-256-GCM, RSA-2048+, SHA-256, bcrypt/Argon2
- Never roll your own crypto: Use standard libraries
- Layer your defenses: TLS + application encryption + encryption at rest
- Manage keys properly: HSM/KMS, rotation, envelope encryption
- Protect against future threats: Consider PFS, plan for post-quantum
The difference between secure and insecure systems often comes down to implementation details: random IVs, constant-time comparisons, proper key storage. Get these right, and your cryptography will protect data for decades.
Quick Reference
When to use what: ───────────────────────────────────────────────────────────────── Encrypting data: AES-256-GCM (symmetric) Key exchange: ECDH (P-256 or X25519) Digital signatures: ECDSA (P-256) or Ed25519 Password storage: Argon2id File integrity: SHA-256 or BLAKE3 Message authentication: HMAC-SHA256 TLS configuration: TLS 1.3 with PFS cipher suites Secrets management: KMS (AWS/GCP/Azure) or HashiCorp Vault