~/learn / cryptography
Cryptography
The building blocks every security engineer needs, from encoding versus encryption to symmetric ciphers, hashing, and public key systems, what each primitive does and does not guarantee, and why nearly every real break is misuse rather than broken math.
Cryptography is everywhere you look as a practitioner: TLS on every site, password hashes in every database, signatures on every token, encrypted disks on every laptop. You do not need to be a mathematician to build or test systems that use it well. You need a precise mental model of what each primitive guarantees and, more importantly, what it does not, because the gap between those two is where real systems break.
Encoding, encryption, and hashing
These three are confused constantly, in code reviews and in bug reports, and the confusion is itself a finding.
| Reversible? | Needs a key? | Purpose | |
|---|---|---|---|
| Encoding (Base64, hex, URL encoding) | Yes, by anyone | No | Represent data safely in another format |
| Encryption (AES, ChaCha20, RSA) | Yes, with the key | Yes | Keep data confidential |
| Hashing (SHA-256, BLAKE2) | No | No | Fingerprint data, detect change |
If a “secret” is stored as Base64, it is not protected at all. Paste it into the encoder and it is plaintext. This is one of the most common real findings, and it usually means someone reached for the word “encode” when they needed “encrypt.”
The four properties
Every cryptographic design is assembling some mix of these four, and naming the one you actually need prevents most mistakes:
- Confidentiality: only the intended party can read the data. Provided by encryption. Broken by: weak ciphers, ECB, nonce reuse.
- Integrity: any change to the data is detected. Provided by MACs, signatures, and authenticated encryption. Broken by: encryption without a MAC, which lets an attacker flip bits in ciphertext and change the plaintext.
- Authenticity: you know who produced the data. Provided by MACs (shared key) or signatures (public key). Broken by: trusting an unauthenticated channel, or a signature algorithm the attacker gets to choose.
- Non-repudiation: the producer cannot later deny it. Only signatures provide this, because only one party holds the private key. A shared-key MAC cannot, because either holder could have produced the tag.
The single most common conceptual error is assuming encryption gives integrity. It does not. Plain AES-CBC or AES-CTR is perfectly confidential and completely malleable at the same time, which is why authenticated encryption exists and why it is the default you should reach for.
What to actually use
When in doubt, these are the safe defaults, and the rest of this section explains why:
- Encrypt data: AES-256-GCM or ChaCha20-Poly1305 (authenticated encryption).
- Hash for integrity: SHA-256, SHA-3, or BLAKE2.
- Authenticate a message with a shared key: HMAC-SHA256.
- Store passwords: Argon2id (or scrypt, bcrypt).
- Random secrets: your platform CSPRNG, never
Math.random. - Key exchange and signatures: X25519 and Ed25519, or P-256.
Kerckhoffs’s principle
A system should stay secure even if everything about it except the key is public. Custom “secret algorithms” violate this and nearly always fall apart the moment someone looks. When you meet homegrown crypto in a test, it deserves real attention; the cipher workbench breaks the classic constructions in seconds, which is a practical demonstration of why secrecy of design is not security.
Where this topic goes
- Symmetric encryption: block and stream ciphers, modes, padding oracles, nonce reuse, and why AEAD is the default.
- Hashing and password storage: hash guarantees, MACs and length extension, salts, peppers, and memory-hard password hashes.
- Public key cryptography: RSA and elliptic curves with worked examples, key exchange, signatures, certificates, and post-quantum.
- Common crypto mistakes: the patterns that actually lead to breaks, and how to spot them in code.
The one rule
Do not design your own cryptography, and prefer high-level, well-reviewed libraries (libsodium, Tink, your platform’s standard library) over hand-assembling primitives. The algorithms are the part that already works. Your job is to wire them together without introducing the misuse that breaks them.
Go deeper
- Symmetric EncryptionHow block and stream ciphers really work, what modes of operation do, a worked CBC bit-flip, how padding oracles and nonce reuse break confidentiality, and why authenticated encryption is the only safe default.
- Hashing and Password StorageWhat cryptographic hashes guarantee, how MACs and length extension work, the cracking economics that make fast hashes wrong for passwords, and how salts, peppers, and memory-hard algorithms like Argon2id protect credentials.
- Public Key CryptographyHow asymmetric keys work with a tiny worked RSA and Diffie-Hellman example, what RSA and elliptic curves are for, how key exchange creates a shared secret, how signatures and certificate chains build trust, and what post-quantum changes.
- Common Crypto MistakesThe real-world patterns behind cryptographic failures, from weak randomness and hardcoded keys to missing integrity, nonce reuse, key reuse across purposes, and homegrown schemes, each with the mechanism and the fix.