24 lines
1.2 KiB
Markdown
24 lines
1.2 KiB
Markdown
# Storage encryption (IndexedDB) – Dec 2025
|
||
|
||
**Scope**
|
||
- Encrypt private article content and invoices stored in IndexedDB using Web Crypto (AES-GCM).
|
||
- Deterministic per-article secret derived from a persisted master key.
|
||
- No fallbacks; fails if IndexedDB or Web Crypto is unavailable.
|
||
|
||
**Key management**
|
||
- Master key generated once in browser (`article_storage_master_key`, random 32 bytes, base64) and kept in localStorage.
|
||
- Per-article secret: `<masterKey>:<articleId>` (used only client-side).
|
||
|
||
**Implementation**
|
||
- `lib/storage/cryptoHelpers.ts`: AES-GCM helpers (base64 encode/decode, encrypt/decrypt).
|
||
- `lib/storage/indexedDB.ts`: store/get now require a secret; payloads encrypted; unchanged API surface via `storageService`.
|
||
- `lib/articleStorage.ts`: derives per-article secret, encrypts content+invoice on write, decrypts on read, same expiration (30 days).
|
||
|
||
**Behavior**
|
||
- If IndexedDB or crypto is unavailable, operations throw (no silent fallback).
|
||
- Existing data written before encryption won’t decrypt; new writes are encrypted.
|
||
|
||
**Next steps (optional)**
|
||
- Rotate master key with migration plan.
|
||
- Add per-user secrets or hardware-bound keys if required.
|