Cryptography Quick Reference
Everything you need day‑to‑day – AES, RSA, key management, and encryption modes.
Cryptography Basics
Key Concepts
- Encryption – plaintext → ciphertext
- Decryption – ciphertext → plaintext
- Key – secret parameter for encryption/decryption
- Hash – one‑way function (integrity)
- Digital Signature – authenticity + non‑repudiation
- Certificate – binds identity to public key
Cryptography Categories
- Symmetric: Same key for encryption/decryption (AES, DES, 3DES, ChaCha20)
- Asymmetric: Public/private key pair (RSA, ECC, DSA)
- Hash: One‑way (SHA‑256, SHA‑3, MD5, BLAKE2)
- Key Exchange: Diffie‑Hellman, ECDH
Symmetric Encryption – AES
AES Overview
- AES – Advanced Encryption Standard
- NIST standard, symmetric block cipher
- Block size: 128 bits (16 bytes)
- Key sizes: 128, 192, 256 bits
- Rounds: 10 (128‑bit), 12 (192‑bit), 14 (256‑bit)
- Substitution‑permutation network
- Use cases: File encryption, database encryption, TLS, disk encryption
AES Key Sizes
| Key Size | Rounds | Security Level | Use Case |
|---|---|---|---|
| 128‑bit | 10 | Standard | General purpose |
| 192‑bit | 12 | High | Government (legacy) |
| 256‑bit | 14 | Very High | Top secret, future‑proof |
AES Modes of Operation
| Mode | Description | Parallelisable | Padding | Use Case |
|---|---|---|---|---|
| ECB | Each block encrypted separately | Yes | Required | Avoid – pattern leakage |
| CBC | XOR with previous ciphertext block + IV | No (decryption yes) | Required | Legacy, still used |
| CTR | Counter mode – turns block cipher into stream | Yes | No | High performance, parallel |
| GCM | Authenticated encryption (AEAD) | Yes | No | Recommended – encryption + authentication |
| CFB | Cipher feedback – stream mode | No | No | Streaming data |
| OFB | Output feedback – stream mode | No | No | Error‑resistant streaming |
IV (Initialization Vector)
- Random, unique for each encryption operation
- Must be unpredictable
- Does not need to be secret (sent with ciphertext)
- Reusing IV with same key compromises security
- Size: 16 bytes for AES (128 bits)
- Use
os.urandom()orSecureRandom
AES in Code (Python)
# AES‑GCM (recommended) from cryptography.hazmat.primitives.ciphers.aead import AESGCM import os key = AESGCM.generate_key(bit_length=256) # or 128, 192 iv = os.urandom(12) # 12 bytes for GCM aesgcm = AESGCM(key) plaintext = b"Hello, World!" ciphertext = aesgcm.encrypt(iv, plaintext, None) # associated data = None decrypted = aesgcm.decrypt(iv, ciphertext, None) # AES‑CBC from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend key = os.urandom(32) # 256 bits iv = os.urandom(16) # 16 bytes for CBC cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()) encryptor = cipher.encryptor() ciphertext = encryptor.update(plaintext) + encryptor.finalize()
AES in Code (Java)
// AES‑GCM (recommended) import javax.crypto.*; import javax.crypto.spec.GCMParameterSpec; import java.security.SecureRandom; byte[] key = new byte[32]; SecureRandom secureRandom = new SecureRandom(); secureRandom.nextBytes(key); SecretKey secretKey = new SecretKeySpec(key, "AES"); Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); GCMParameterSpec gcmSpec = new GCMParameterSpec(128, new byte[12]); cipher.init(Cipher.ENCRYPT_MODE, secretKey, gcmSpec); byte[] ciphertext = cipher.doFinal("Hello".getBytes()); // AES‑CBC Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); IvParameterSpec ivSpec = new IvParameterSpec(new byte[16]); cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
OpenSSL AES Commands
# Encrypt (AES‑256‑CBC) openssl enc -aes-256-cbc -salt -in plaintext.txt -out encrypted.bin # Decrypt openssl enc -d -aes-256-cbc -in encrypted.bin -out decrypted.txt # Encrypt with base64 output openssl enc -aes-256-cbc -a -in plaintext.txt -out encrypted.base64 # Encrypt with GCM (OpenSSL 1.1.0+) openssl enc -aes-256-gcm -in plaintext.txt -out encrypted.bin
Asymmetric Encryption – RSA
RSA Overview
- RSA – Rivest‑Shamir‑Adleman
- Public‑key cryptography (asymmetric)
- Based on factoring large numbers
- Key pair: Public (encryption/verify) and Private (decryption/sign)
- Key sizes: 1024 (obsolete), 2048 (standard), 4096 (high)
- Use cases: TLS, digital signatures, secure key exchange
RSA Key Sizes
| Key Size | Security Level | Performance | Use Case |
|---|---|---|---|
| 1024‑bit | Unsafe (breakable) | Fast | Avoid – deprecated |
| 2048‑bit | Standard (secure) | Moderate | General use (recommended) |
| 3072‑bit | High | Slower | Long‑term security |
| 4096‑bit | Very High | Slow | High‑security environments |
RSA Key Generation
# OpenSSL – Generate 2048-bit private key openssl genrsa -out private.pem 2048 # Extract public key openssl rsa -in private.pem -pubout -out public.pem # View key details openssl rsa -in private.pem -text -noout
RSA Encryption & Decryption
# Encrypt (RSA + AES hybrid usually recommended) openssl rsautl -encrypt -pubin -inkey public.pem -in plaintext.txt -out encrypted.bin # Decrypt openssl rsautl -decrypt -inkey private.pem -in encrypted.bin -out decrypted.txt # Sign openssl dgst -sha256 -sign private.pem -out signature.bin data.txt # Verify openssl dgst -sha256 -verify public.pem -signature signature.bin data.txt
RSA in Code (Python)
from cryptography.hazmat.primitives import serialization, hashes from cryptography.hazmat.primitives.asymmetric import rsa, padding # Generate key pair private_key = rsa.generate_private_key( public_exponent=65537, key_size=2048 ) # Serialise to PEM private_pem = private_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption() ) public_pem = private_key.public_key().public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo ) # Encrypt (RSA‑OAEP with SHA‑256) ciphertext = public_key.encrypt( b"Hello, World!", padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None ) ) # Decrypt plaintext = private_key.decrypt( ciphertext, padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None ) ) # Sign signature = private_key.sign( b"Hello, World!", padding.PSS( mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH ), hashes.SHA256() ) # Verify public_key.verify( signature, b"Hello, World!", padding.PSS( mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH ), hashes.SHA256() )
RSA in Code (Java)
// Generate key pair KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA"); gen.initialize(2048); KeyPair keyPair = gen.generateKeyPair(); // Encrypt Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic()); byte[] ciphertext = cipher.doFinal("Hello".getBytes()); // Decrypt cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate()); byte[] plaintext = cipher.doFinal(ciphertext); // Sign Signature sign = Signature.getInstance("SHA256withRSA"); sign.initSign(keyPair.getPrivate()); sign.update("Hello".getBytes()); byte[] signature = sign.sign(); // Verify sign.initVerify(keyPair.getPublic()); sign.update("Hello".getBytes()); boolean isValid = sign.verify(signature);
Symmetric vs Asymmetric
| Feature | Symmetric (AES) | Asymmetric (RSA) |
|---|---|---|
| Keys | Single key (shared secret) | Public/private key pair |
| Key Distribution | Difficult (must be secure) | Easy (public key can be shared) |
| Speed | Fast | Slow (100‑1000x slower) |
| Key Size | 128‑256 bits | 2048‑4096 bits |
| Use Case | Bulk encryption (files, TLS, disk) | Key exchange, signatures, small data |
| Security Assumption | Brute force (key space) | Factoring large numbers |
Hybrid Cryptography (Best Practice)
- Use RSA to encrypt a symmetric session key
- Use AES (or ChaCha20) to encrypt the actual data
- Combines speed of symmetric + key distribution of asymmetric
- Example: TLS, PGP, SSH
Hybrid Example
// 1. Generate AES session key byte[] sessionKey = new byte[32]; // 256 bits SecureRandom secureRandom = new SecureRandom(); secureRandom.nextBytes(sessionKey); // 2. Encrypt AES key with RSA public key Cipher rsaCipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); rsaCipher.init(Cipher.ENCRYPT_MODE, rsaPublicKey); byte[] encryptedKey = rsaCipher.doFinal(sessionKey); // 3. Encrypt data with AES using session key Cipher aesCipher = Cipher.getInstance("AES/GCM/NoPadding"); SecretKeySpec aesKey = new SecretKeySpec(sessionKey, "AES"); aesCipher.init(Cipher.ENCRYPT_MODE, aesKey, new GCMParameterSpec(128, iv)); byte[] ciphertext = aesCipher.doFinal(plaintext); // 4. Send encryptedKey + iv + ciphertext
Key Management
- Key generation: Use secure random sources (
os.urandom,SecureRandom) - Key storage: Use HSMs, key vaults, or encrypted files
- Key rotation: Regular key replacement schedule
- Key destruction: Secure deletion, cryptographic erasure
- Secrets Management: AWS KMS, HashiCorp Vault, Azure Key Vault
- Certificate Management: x.509 certificates, PKI
Common Pitfalls
- Reusing IV – with same key, GCM re‑use breaks confidentiality
- Using ECB mode – reveals patterns, avoid at all costs
- Short RSA keys – 1024‑bit is insecure, use 2048+
- Storing keys in source code – never hardcode secrets
- Weak random number generators – must be cryptographic secure
- No authentication – use GCM, CCM, or encrypt‑then‑HMAC
- Padding oracle attacks – use authenticated encryption (GCM/ChaCha20)
Hashing & Signatures
Common Hash Algorithms
- MD5 – broken, not for security
- SHA‑1 – broken, deprecated
- SHA‑256 – standard, recommended
- SHA‑384 – high security
- SHA‑512 – high security
- SHA‑3 – newer NIST standard
- BLAKE2 – fast, secure
HMAC (Hash‑based MAC)
- Used for message authentication
- HMAC‑SHA256 (recommended)
- HMAC‑SHA512
- Keyed hash, integrity + authentication
import hmac, hashlib hmac.new(key, message, hashlib.sha256).digest()
📌 Quick Reference
AES: 128/192/256‑bit keys, block size 128‑bit, recommended mode: GCM (authenticated)
RSA: 2048‑bit minimum, use OAEP (not PKCS1v1.5), sign with PSS
Hybrid: RSA for key exchange + AES for bulk encryption
IV: Unique per encryption, 12 bytes for GCM, 16 bytes for CBC
AES modes: GCM (recommended), CBC, CTR (parallel), ECB (avoid)
RSA padding: OAEP (encryption), PSS (signature)
Hashing: SHA‑256 (recommended), SHA‑384/512 (high security)
RSA: 2048‑bit minimum, use OAEP (not PKCS1v1.5), sign with PSS
Hybrid: RSA for key exchange + AES for bulk encryption
IV: Unique per encryption, 12 bytes for GCM, 16 bytes for CBC
AES modes: GCM (recommended), CBC, CTR (parallel), ECB (avoid)
RSA padding: OAEP (encryption), PSS (signature)
Hashing: SHA‑256 (recommended), SHA‑384/512 (high security)