Key Management
In one line: Strong algorithms protect nothing if the key is guessable, hardcoded, never rotated, or stolen — so key management (generating keys with real randomness, storing them in a KMS/HSM instead of your code, rotating them, and minimizing each key's reach) is where cryptography succeeds or fails in practice.
Every lesson so far assumed "you have a key." This lesson is about that assumption — and it's where real systems break. The cryptography is almost never the weak point; the handling of the keys is. A perfect AES-256 cipher is worthless if the key is the word password, sitting in a config file committed to GitHub, shared across every environment, and never changed in five years. Think of keys like the physical keys to a building: it doesn't matter how strong the lock is if you tape the key to the door, hand copies to everyone, and never re-key it after someone quits. Key management is the boring, unglamorous discipline that decides whether all the elegant math actually protects anything. Get it wrong and you've built a vault with the combination written on the front.
The key lifecycle
A cryptographic key isn't a static thing you create once. It has a lifecycle, and each stage has a way to go wrong:
Generate ──▶ Store ──▶ Use ──▶ Rotate ──▶ Revoke/Destroy
│ │ │ │ │
real KMS/HSM, least replace wipe old keys;
randomness not code privilege regularly contain compromise
- Generate — create the key using a cryptographically secure random number generator (CSPRNG). Keys must be unguessable; a key derived from weak randomness (a timestamp, a counter,
rand()) can be predicted and the whole scheme falls. - Store — keep the key somewhere it can't be casually read. Not in source code, not in a plaintext config file, not in the same database it protects. (See where keys should live.)
- Use — apply least privilege: only the services that truly need a key can access it, and each key does one job (separate keys for separate purposes, environments, and tenants).
- Rotate — periodically replace keys with new ones, so that even an undetected leak has a limited useful life, and so a known-good key is always recent.
- Revoke / destroy — when a key is compromised or retired, invalidate it and securely erase old copies so it can't be used again.
- CSPRNG — Cryptographically Secure Pseudo-Random Number Generator: a randomness source safe for keys (e.g., the OS's
/dev/urandom,crypto.randomBytes). Ordinaryrandom()is not one. - KMS (Key Management Service) — a managed service (AWS KMS, GCP KMS, Azure Key Vault, HashiCorp Vault) that generates, stores, and uses keys on your behalf, so the raw key never sits in your app.
- HSM (Hardware Security Module) — a tamper-resistant hardware device that stores keys and performs crypto inside itself; the private key never leaves the hardware. The gold standard for high-value keys.
- Envelope encryption — encrypt your data with a data key, then encrypt that data key with a master key held in the KMS. You store the encrypted data key beside the data; only the KMS can unwrap it.
- Rotation — replacing a key with a fresh one on a schedule or after suspicion of compromise.
- Secret — the broader category: keys, API tokens, passwords, connection strings. Same handling rules apply.
Where keys should live
The single most common catastrophic mistake is a hardcoded key — a secret sitting in source code or a committed config file. Once it's in version control, it's effectively public (and stays in Git history even after you "delete" it). The fix is a hierarchy, from worst to best:
| Approach | Safety | Notes |
|---|---|---|
| Hardcoded in source / committed config | ❌ Never | In Git history forever; leaks on every clone |
Plaintext env var / .env on disk | ⚠️ Weak | Better than code, but readable by anything on the host |
| Secrets manager (Vault, cloud Secrets Manager) | ✅ Good | Centralized, access-controlled, audited, rotatable |
| KMS (key used, never exposed) | ✅✅ Better | App asks KMS to encrypt/decrypt; raw key never leaves |
| HSM (key never leaves hardware) | ✅✅✅ Best | Tamper-resistant; for root/master keys and high value |
You need to encrypt millions of customer records. You don't hand the master key to your app — instead:
- The app asks the KMS to generate a data key. KMS returns it twice: once in plaintext (to use right now) and once encrypted under the master key (which never leaves KMS).
- The app encrypts the records with the plaintext data key, then throws the plaintext data key away, storing only the encrypted data key next to the ciphertext.
- To decrypt later, the app sends the encrypted data key back to KMS, which unwraps it (because only KMS holds the master key) and returns the plaintext data key for that one operation.
The payoff: the master key never touches your servers, you can rotate it centrally, every unwrap is logged and access-controlled, and a stolen database (with only encrypted data keys) is useless without KMS access. This is how cloud encryption-at-rest works under the hood.
Rotation: limiting the damage of a leak
You should assume any key might eventually leak. Rotation — replacing keys regularly — is the defense-in-depth answer:
- A key rotated every 90 days means a leaked-but-undetected key has at most a bounded useful life.
- Rotation forces you to build the ability to change keys — which is exactly what you need, fast, on the day a key is actually compromised. Teams that never rotate discover during an incident that they can't without downtime.
- Good systems support overlapping keys: the new key starts being used while the old one can still decrypt existing data, so rotation doesn't require re-encrypting everything at once or causing an outage.
The hardest case is the root/master key at the top of the hierarchy — which is why it lives in an HSM, is rotated rarely and carefully, and is often protected by split knowledge (no single person holds the whole key) and separation of duties.
Containing a compromise
When a key is compromised, key management determines how bad it gets — this is blast radius again:
- One key, one job. Separate keys per environment (dev/staging/prod), per service, and per data class mean a leaked dev key doesn't expose production. A single shared key everywhere means one leak exposes everything.
- Rapid revocation + rotation. The ability to invalidate the old key and roll out a new one quickly is what turns a key leak from a catastrophe into an incident.
- Audit logging. A KMS logs every use of a key. After a suspected leak, those logs tell you what the attacker could have touched — and unusual key usage can detect the leak in the first place (detection).
Why it matters
- It's the real-world failure point. Survey after survey of breaches finds leaked credentials and mismanaged keys among the top root causes — far more than broken algorithms. The math holds; the key handling doesn't.
- It's where every prior lesson cashes out. Symmetric keys, private keys, certificate keys — all of them are only as safe as their management. This lesson is why the chapter's mantra is "use vetted tools," because KMS/HSM are those tools for key handling.
- It applies far beyond crypto. "Don't hardcode secrets, store them centrally, rotate them, scope them" is identical guidance for API tokens, database passwords, and cloud credentials — the daily reality of secure SDLC and cloud security.
Common pitfalls
- Hardcoding keys/secrets in source or config. The number-one mistake. It's in Git history forever and leaks with every clone, screenshot, and log. Use a secrets manager or KMS. (Scan your repos for committed secrets — it's a standard DevSecOps check.)
- Weak key generation. Deriving keys from non-cryptographic randomness (
Math.random(), timestamps, predictable seeds) makes them guessable. Always use a CSPRNG. - Never rotating. A key that's never changed has unlimited exposure and, worse, the capability to rotate is never built — so you can't react when it's compromised.
- One key everywhere. Sharing a single key across environments, services, and customers maximizes blast radius: one leak exposes all of it. Scope keys narrowly.
- Storing the key next to what it protects. Encrypting a database with a key stored in that same database (or on the same server with the same access) means whoever steals the data steals the key. Separate them (envelope encryption, KMS).
- Logging secrets. Keys and tokens accidentally written to application logs, error reports, or URLs leak quietly and persist in log archives. Scrub secrets from logs.
- Forgetting to destroy old keys. A "retired" key that still exists in a backup or old config is still a live risk. Securely erase it.
Page checkpoint
Key management — locked in?
Pass to unlock the Next button belowWhat's next
You've now seen the full cryptographic toolkit — symmetric and asymmetric encryption, hashing and MACs, TLS, PKI, and the key management that holds it all together.
→ Continue to Post-Quantum Crypto & Crypto-Agility — why a future quantum computer threatens today's asymmetric crypto, why the migration is already underway, and the durable design lesson that ties the chapter together. Then take the Chapter 2 checkpoint to lock it all in.