Key Management
Key Rotation
Replacing keys without breaking running systems.
Every key that stays in use accumulates risk: more data encrypted under it, more places it has been copied, more people who have touched it. Rotation caps that exposure by retiring old keys and introducing new ones on a schedule, and the hard part is doing it without breaking systems that still depend on the old key.
Why rotate
Two forces drive rotation, one gradual and one sudden.
- Exposure windows: the longer a key lives, the more ciphertext or signatures depend on it, and the bigger the prize if it leaks. Regular rotation shrinks the window and limits how much a single compromise unlocks.
- Personnel and event changes: when someone with key access leaves, when a laptop is lost, or when you suspect exposure, you rotate immediately. Scheduled rotation also proves the process works so the emergency case is not the first time you try it.
| Trigger | Timing | Urgency |
|---|---|---|
| Routine policy | e.g. every 90 days or annually | Planned |
| Employee offboarding | On departure | Prompt |
| Suspected or confirmed leak | Immediately | Emergency |
| Algorithm deprecation | On migration | Planned |
Key versioning and dual-read for zero-downtime rotation
The mistake is treating rotation as an instant swap: delete old key, install new key, watch everything that used the old key fail. The fix is versioning plus a dual-read window.
- Every key has a version identifier, and every encrypted blob or signature records which version produced it.
- To rotate, introduce the new version and start using it for all new writes and signatures.
- Keep the old version available for reads and verification so existing data and signatures still resolve.
- Once nothing references the old version (data re-encrypted or naturally expired), retire and destroy it.
Phase 1 write: v2 read: v1, v2 (v1 being phased out)
Phase 2 write: v2 read: v2 only (v1 retired)
During the dual-read window there is no downtime: readers accept both versions while writers move forward. This is exactly what SSH authorized_keys with two keys, or JWT signing with a published key set (JWKS) carrying multiple key IDs, lets you do in practice.
Envelope encryption: rotate the key without re-encrypting the data
Re-encrypting terabytes of data every rotation is painful. Envelope encryption avoids it. You encrypt your data with a data encryption key (DEK), then encrypt that small DEK with a key encryption key (KEK). The KEK is the one you rotate.
data --encrypted-by--> DEK --encrypted-by--> KEK (in KMS/HSM)
Rotating the KEK means re-encrypting only the tiny wrapped DEK, not the bulk data. Here is the idea end to end with local tooling:
cd ~/crypto-lab
# Generate a random data key (DEK) and encrypt data with it
openssl rand -out dek.bin 32
openssl enc -aes-256-gcm -K "$(xxd -p -c64 dek.bin)" \
-iv "$(openssl rand -hex 12)" -in bigdata.txt -out bigdata.enc
# Wrap (encrypt) the DEK under a KEK public key; rotate by re-wrapping only this
openssl pkeyutl -encrypt -pubin -inkey kek.pub.pem \
-pkeyopt rsa_padding_mode:oaep -in dek.bin -out dek.wrapped
ls -l dek.wrapped bigdata.enc
Expected output:
-rw------- 1 you staff 384 Jul 6 10:20 dek.wrapped
-rw------- 1 you staff 10M Jul 6 10:20 bigdata.enc
To rotate the KEK you only re-wrap the 384-byte dek.wrapped; the 10 MB ciphertext is untouched. Cloud KMS services (see the sibling KMS & HSM) implement this pattern natively and often re-wrap the DEK for you.
Practical Guidance
- Rotate on a schedule and immediately on any suspected exposure or personnel change; do not wait for an incident.
- Version every key and tag each ciphertext or signature with the version that produced it.
- Use a dual-read window: write with the new key while still reading and verifying with the old, then retire the old.
- Adopt envelope encryption so rotating the KEK never requires re-encrypting bulk data.
- Automate rotation. Manual rotation is skipped rotation, and the emergency case should not be the first rehearsal.
- Destroy retired keys once nothing depends on them, and keep an audit trail of what rotated and when.