feat(encryption): Implement e2e encryption using encryptedStorage composable
๐ Linked issue
#24
โ Type of change
- [x] ๐ Documentation (updates to the documentation, readme, or JSdoc annotations)
- [ ] ๐ Bug fix (a non-breaking change that fixes an issue)
- [ ] ๐ Enhancement (improving an existing functionality like performance)
- [X] โจ New feature (a non-breaking change that adds functionality)
- [ ] ๐งน Chore (updates to the build process or auxiliary tools and libraries)
- [ ] โ ๏ธ Breaking change (fix or feature that would cause existing functionality to change)
๐ Description
Implements a new composable function encryptedStorage similar to prefixStorage that wraps a unstorage instance and offers encryption for values and optionally for keys as well.
- Adds new composable
encryptedStoragethat can also be used in combination with others likeprefixStorage. Usage isencryptedStorage(createStorage({ driver }), encryptionKey, true)where the last parameter (set totrue) defines if keys should also be encrypted - Uses
@noble/ciphersfor encryption, as it is 0 deps and works in Node, Bun, Deno and Workers (tested on CF). It supports AES-GCM-SIV (not implemented in Web/Node Crypto) which is nonce misuse resistant, what we need for deterministic key encryption with the same IV/nonce for keys. - For content encryption, XChaCha20-Poly1305 (which is also used in TLS 1.3) is used. It is a fast modern and future proof cipher and safe to use with random nonces. Nonces are generated with
getRandomValuesfromuncrypto. The content is wrapped into aStorageValueEnvelope:
export interface StorageValueEnvelope {
nonce: string;
encryptedValue: string;
}
- The implementation was tested against common drivers like
fs,memory,redis, 'lrs' andazure-blob-storagefor content as well as key encryption and in combination withprefixStorage:
const storage = createStorage();
const pStorage = prefixStorage(storage, "foo");
const encStorage = encryptedStorage(pStorage, encryptionKey, true);
- Tests include an encryption example for
fsdriver, an update to thetestDriverutility to optionally test for content and key encryption as well es tests for the storage server and the combination withprefixStorage
๐ Checklist
- [X] I have linked an issue or discussion.
- [ ] I have updated the documentation accordingly.
Would appreciate your feedback @pi0, @danielroe, @Atinux. If the implementation is fine for you, I would add an option to provide the encryption key via. env variable and write the docs.
Codecov Report
Attention: 28 lines in your changes are missing coverage. Please review.
Comparison is base (
293a2a6) 75.32% compared to head (1c88d64) 76.08%.
| Files | Patch % | Lines |
|---|---|---|
| src/utils.ts | 83.97% | 25 Missing :warning: |
| src/drivers/encryption.ts | 94.87% | 2 Missing :warning: |
| src/_utils.ts | 98.92% | 1 Missing :warning: |
Additional details and impacted files
@@ Coverage Diff @@
## main #363 +/- ##
==========================================
+ Coverage 75.32% 76.08% +0.76%
==========================================
Files 30 31 +1
Lines 3534 3822 +288
Branches 494 531 +37
==========================================
+ Hits 2662 2908 +246
- Misses 871 913 +42
Partials 1 1
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
Anything I can do to bring this forward @pi0 ?
Anything I can do to bring this forward @pi0 ?
@pi0 ?