

0 / 2 embers
0 / 3000 xp
click for more info
Complete a lesson to start your streak
click for more info
Still calibrating
click for more info
Not enough gems
Cost: 6 gems
1: Encrypting Data at Rest
incomplete
2: Key Management and Rotation
incomplete
3: Password KDFs
incomplete
4: Salts
incomplete
5: Argon2 Parameters
incomplete
6: Encrypted Files
incomplete
7: Secure Database Practices
incomplete
8: Personally Identifiable Information
incomplete
9: Financial Data
incomplete
Back
ctrl+,
Next
ctrl+.
This lesson's interactive features are locked, please to keep using them
Encrypted data is only as safe as the key used to encrypt it. But a single unversioned key means replacing it makes every value encrypted with the old key unreadable!
Instead, use a keyring. This isn't as complex as it sounds: start with one key and call it version 1 (v1):
DOCUMENT_ENC_KEY_V1=A927FD...
Then, whenever you encrypt a value, store its key version with the ciphertext:
| Ciphertext | Key Version |
|---|---|
0xdeadbeef... |
v1 |
0xfeedface... |
v1 |
| ... | ... |
When you need to rotate your key, add a new one and change the active version:
DOCUMENT_ENC_KEY_V1=A927FD...
DOCUMENT_ENC_KEY_V2=3B1C9A...
DOCUMENT_ENC_ACTIVE_VERSION=v2
Your application should always decrypt with the version recorded on the payload and encrypt with the current active version. That way, old ciphertext remains readable after rotation.
If a key was compromised, rotate it and re-encrypt live data as soon as you can. This limits future exposure, but it can't protect ciphertext an attacker already copied with the old key.
Losing an encryption key can mean permanently losing the data it protects. Treat rotation, backup recovery, access control, and key retirement as one lifecycle.
Bearly Secure already routes TOTP secrets through encryptStringWithKeyring and decryptStringWithKeyring in src/storage/keyring.ts, but both are insecure pass-throughs, and the app treats the keyring as optional. Complete the versioned keyring so TOTP secrets are encrypted at rest with the active key.
DATA_ENCRYPTION_ACTIVE_VERSION=v1
DATA_ENCRYPTION_KEY_V1=replace_with_64_hex_characters
Run and submit the CLI tests from the project root.