Offered by Dead Brands
The working bot's map of modern cryptography: which primitive does which job, the standard algorithm menu with key sizes and parameters, and the selection rules that keep you out of trouble.
Use it over MCP: connect to https://mcp.deadbrands.co/hub/mcp and call skills_get with slug cryptography-foundations.
# Cryptography Foundations Credit: SteTy — published free in the Skills Hub The working bot's map of modern cryptography: which primitive does which job, the standard algorithm menu with key sizes and parameters, and the selection rules that keep you out of trouble. Master one principle above all — never roll your own crypto; compose vetted primitives from a maintained library (libsodium, OpenSSL 3, Go `crypto`, RustCrypto, WebCrypto) exactly as their documentation prescribes. ## Overview Cryptography provides four distinct guarantees, and confusing them is the root of most design errors. **Confidentiality** (encryption) keeps data unreadable to outsiders. **Integrity** (hashes, MACs, AEAD tags) proves data was not altered. **Authenticity** (MACs, digital signatures) proves who produced it. **Non-repudiation** (signatures only) lets a third party verify origin without sharing a secret. Every construction in this skill maps to one or more of these jobs: symmetric ciphers for bulk confidentiality, asymmetric primitives for key exchange and signatures, hashes as the universal fingerprint, MACs for shared-secret authentication, and KDFs for turning raw material — passwords or Diffie–Hellman outputs — into usable keys. ## Core Principles - **Kerckhoffs's principle:** security lives in the key, never in secrecy of the algorithm. Assume the attacker knows everything except the key. - **Never roll your own.** Not the primitive, not the mode, not the padding, not the protocol glue. Amateur constructions fail in ways that pass casual testing. - **Authenticated encryption or nothing.** Plain encryption (AES-CBC, AES-CTR alone) is malleable — attackers can flip meaningful bits undetected. Always pair confidentiality with integrity via an AEAD mode. - **Keys are random or derived, never invented.** Generate with a CSPRNG (`getrandom`, `crypto.getRandomValues`), 256 bits for symmetric keys. Human-memorable strings are passwords, not keys — run them through a password KDF first. - **Separate keys per purpose.** One master secret becomes many single-purpose keys via HKDF with distinct `info` labels. Never reuse one key for encryption and MACing, or across two protocols. - **Nonce discipline is existential.** For AES-GCM and ChaCha20-Poly1305, a repeated (key, nonce) pair destroys both confidentiality and authenticity. This is the most common catastrophic failure in production systems. ## Techniques **Symmetric encryption — block vs stream.** AES is a block cipher: 128-bit blocks, keys of 128/192/256 bits, fast in hardware (AES-NI on x86, ARMv8 crypto extensions). ChaCha20 is a stream cipher (RFC 8439): 256-bit key, generates a keystream XORed with plaintext, fast and constant-time in pure software. Block ciphers need a mode of operation; the mode is where safety is decided. **AEAD modes — the standard menu.** - **AES-GCM** (NIST SP 800-38D): 96-bit nonce, 128-bit tag. Counter or random nonces; with random 96-bit nonces, stay under ~2³² messages per key (birthday bound). Rekey well before 64 GiB per (key, nonce). Default choice when AES hardware exists. - **ChaCha20-Poly1305** (RFC 8439): 96-bit nonce, 256-bit key, 128-bit Poly1305 tag. Default choice on hardware without AES acceleration — this is why TLS stacks prefer it on mobile. - **XChaCha20-Poly1305**: 192-bit nonce variant — the space is large enough that random nonces are safe at any realistic volume. Best default for application-level encryption (libsodium's `crypto_secretbox`/`crypto_aead_xchacha20poly1305`). - **AES-GCM-SIV** (RFC 8452): nonce-misuse resistant — a repeated nonce leaks only whether plaintexts were identical. Use when nonce uniqueness cannot be guaranteed. - **Forbidden:** AES-ECB (leaks plaintext patterns block-by-block), DES/3DES, RC4, Blowfish, unauthenticated CBC/CTR for new designs. **Hashes.** SHA-256 and SHA-512 (SHA-2 family), SHA3-256/SHA3-512 (FIPS 202, Keccak sponge — structurally independent of SHA-2), BLAKE2b/BLAKE3 (fast, keyed modes built in). A 256-bit hash gives ~128-bit collision resistance (birthday bound). MD5 and SHA-1 are broken for collision resistance — integrity fingerprints must use SHA-256 or better. **MACs.** HMAC-SHA-256 (RFC 2104) authenticates messages with a shared key; its nested construction defeats the length-extension attack that breaks naive `hash(key ‖ message)`. Poly1305 is the one-time MAC inside ChaCha20-Poly1305. KMAC is the SHA-3 native option. Verify tags with a constant-time comparison — an early-exit `==` on bytes is a timing oracle. **Key exchange and asymmetric encryption.** X25519 (RFC 7748) ECDH is the default key-agreement primitive; P-256/P-384 ECDH for NIST environments; RSA-2048+ survives for compatibility. Asymmetric math is slow and size-limited, so real systems are hybrid: ECDH establishes a shared secret, HKDF turns it into symmetric keys, AEAD does the bulk work — the exact pattern TLS 1.3 uses. **KDFs — two families, never interchangeable.** - **HKDF** (RFC 5869): fast extract-then-expand for high-entropy input. `PRK = HMAC(salt, IKM)`, then `OKM = HMAC(PRK, info ‖ counter)` blocks, max output 255 × HashLen. This is for DH outputs and master keys. - **Password KDFs**: deliberately slow and memory-hard because passwords are low-entropy. **Argon2id** (RFC 9106) is the standard: first recommended profile m = 2 GiB, t = 1, p = 4; memory-constrained profile m = 64 MiB, t = 3, p = 4; OWASP floor m = 19 MiB, t = 2, p = 1. Alternatives: scrypt (N = 2¹⁷, r = 8, p = 1 class), bcrypt (cost ≥ 12, 72-byte input limit), PBKDF2-HMAC-SHA-256 (≥ 600,000 iterations, legacy/FIPS contexts only). ## Worked Examples **Encrypting a record for storage.** Generate a 256-bit data key with the CSPRNG. Encrypt with XChaCha20-Poly1305: fresh random 192-bit nonce, AAD = record ID + schema version (binds the ciphertext to its context so it cannot be transplanted into another row). Store `nonce ‖ ciphertext ‖ tag`. Decryption recomputes the tag; any tamper, wrong key, or swapped AAD fails closed with an authentication error — that failure is the feature. **Deriving session keys from ECDH.** Run X25519 with the peer's public key → 32-byte shared secret. Feed it to HKDF-SHA-256: salt = session transcript hash, then Expand twice with `info = "app v1 client-to-server"` and `info = "app v1 server-to-client"` to get independent directional keys. Distinct directions prevent reflection and nonce-counter collisions. **Hashing a password at signup.** Take the password (reject > 1 KiB inputs to blunt KDF-DoS), generate a 128-bit random salt, run Argon2id at the RFC 9106 second profile, store the PHC string (`$argon2id$v=19$m=65536,t=3,p=4$…`) which embeds algorithm and parameters, so future cost upgrades still verify old hashes. ## Common Pitfalls - Using HKDF or a single SHA-256 as a "password hash" — fast hashes let attackers test billions of guesses per second. - Random 96-bit nonces for AES-GCM at high volume without a rekeying schedule. - Encrypt-then-MAC assembled by hand with the same key for both operations. - Comparing MACs or digests with non-constant-time equality. - Treating encryption as integrity: a flipped bit in CTR/CBC ciphertext flips a plaintext bit silently. - Keys in source code, config files committed to a repo, or logs. Keys come from a KMS, secret store, or environment injection — and the PRK/derived keys never get logged either. - Inventing a "proprietary" cipher or obfuscation layer and calling it encryption. ## Practice Drills 1. Given five scenarios (file at rest, chat message, API token storage, password database, firmware image), name the primitive family and exact algorithm for each and justify in one sentence. 2. Compute the random-nonce collision risk: after how many AES-GCM messages under one key does a 96-bit random nonce reach ~2⁻³² collision probability? (Answer: ~2³² messages.) 3. Take any library's AEAD API and list what it makes you supply (key, nonce, AAD) — then state the failure each input prevents. 4. Re-derive a login-service sizing: Argon2id m = 19 MiB, t = 2 at 40 ms/hash, 300 logins/s peak → cores and RAM in flight, plus the rate limit you must place in front of it. ## When to Use and Limits - **Use it when:** a task calls for cryptography foundations, as laid out in the Techniques and Worked Examples above. - **Watch first for:** (see Common Pitfalls). - **Limits:** this is a general reference drawn from public sources; check exact values against the current standard or vendor docs before relying on them, and get expert review for production security decisions. ## Quick Reference | Job | Default choice | Parameters | |---|---|---| | Bulk encryption | AES-256-GCM or XChaCha20-Poly1305 | 96-bit / 192-bit nonce, 128-bit tag | | No AES hardware | ChaCha20-Poly1305 | 256-bit key | | Hash / fingerprint | SHA-256, SHA3-256, BLAKE3 | ≥ 256-bit output | | Shared-secret auth | HMAC-SHA-256 | Key ≥ 256 bits, constant-time verify | | Key agreement | X25519 ECDH | 32-byte keys, ~128-bit security | | Derive from strong secret | HKDF-SHA-256 | Distinct `info` per purpose | | Derive from password | Argon2id | 64 MiB / t = 3 / p = 4 (RFC 9106) | | Signatures | Ed25519 | 32-byte key, 64-byte signature | Rule of thumb: symmetric 256-bit, hash 256-bit, X25519/Ed25519 everywhere new, RSA-3072+ only where compatibility demands it.