blind-encryption-sodium 1.0.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -5
- package/index.js +42 -21
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,17 +8,24 @@ Implemention of encryption encoding for Autobase blind encryption using sodium e
|
|
|
8
8
|
const BlindEncryptionSodium = require('blind-encryption-sodium')
|
|
9
9
|
const b4a = require('b4a')
|
|
10
10
|
|
|
11
|
-
const
|
|
12
|
-
// ... fill entropy
|
|
11
|
+
const key = b4a.alloc(32) // 32-byte key
|
|
13
12
|
|
|
14
|
-
const encryption = new BlindEncryptionSodium(
|
|
13
|
+
const encryption = new BlindEncryptionSodium([{ key, type: 0 }])
|
|
15
14
|
|
|
16
15
|
const encrypted = await encryption.encrypt(plaintext)
|
|
17
16
|
// { value: <Buffer>, type: 1 }
|
|
18
17
|
|
|
19
|
-
const
|
|
18
|
+
const { value, rotated } = await encryption.decrypt(encrypted)
|
|
19
|
+
|
|
20
|
+
// if rotated, it was decrypted with a newer type, and you should encrypt and store
|
|
20
21
|
```
|
|
21
22
|
|
|
23
|
+
Multiple values can be passed in. This enables you to "rotate" keys.
|
|
24
|
+
* Value encrypted with an old `type` will be upgraded to the latest `type`
|
|
25
|
+
* Cannot be downgraded
|
|
26
|
+
* Old types are no longer needed after upgrade
|
|
27
|
+
* Returns if rotated when decrypting. Note: if it was decrypted with a newer type, you should encrypt and store to ensure it uses your latest key/entropy
|
|
28
|
+
|
|
22
29
|
### Usage with Autobase:
|
|
23
30
|
|
|
24
31
|
```js
|
|
@@ -26,7 +33,10 @@ const base = new Autobase(store, {
|
|
|
26
33
|
apply,
|
|
27
34
|
open,
|
|
28
35
|
encryptionKey,
|
|
29
|
-
blindEncryption: new BlindEncryptionSodium(
|
|
36
|
+
blindEncryption: new BlindEncryptionSodium([
|
|
37
|
+
{ key: oldKey, type: 0 },
|
|
38
|
+
{ key: newKey, type: 1 },
|
|
39
|
+
])
|
|
30
40
|
})
|
|
31
41
|
```
|
|
32
42
|
|
package/index.js
CHANGED
|
@@ -2,36 +2,57 @@ const b4a = require('b4a')
|
|
|
2
2
|
const sodium = require('sodium-universal')
|
|
3
3
|
|
|
4
4
|
class BlindEncryptionSodium {
|
|
5
|
-
constructor(
|
|
6
|
-
this.
|
|
7
|
-
this._type = 1
|
|
5
|
+
constructor(entropies) {
|
|
6
|
+
this._entropies = entropies.sort((a, b) => b.type - a.type)
|
|
8
7
|
|
|
9
|
-
this.encrypt = async (
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
)
|
|
13
|
-
const nonce = buffer.subarray(0, sodium.crypto_secretbox_NONCEBYTES)
|
|
14
|
-
const box = buffer.subarray(nonce.byteLength)
|
|
8
|
+
this.encrypt = async (value) => {
|
|
9
|
+
// use latest
|
|
10
|
+
const entropy = this._entropies[0]
|
|
11
|
+
const buffer = this._encrypt(value, entropy.key)
|
|
15
12
|
|
|
16
|
-
|
|
17
|
-
sodium.crypto_secretbox_easy(box, key, nonce, this._entropy)
|
|
18
|
-
|
|
19
|
-
return { value: buffer, type: 1 }
|
|
13
|
+
return { value: buffer, type: entropy.type }
|
|
20
14
|
}
|
|
21
15
|
|
|
22
16
|
this.decrypt = async ({ value, type }) => {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
17
|
+
let entropy = this._entropies[0]
|
|
18
|
+
|
|
19
|
+
// no backward compat
|
|
20
|
+
if (type > entropy.type) throw new Error('Encrypted using new type: ' + type)
|
|
26
21
|
|
|
27
|
-
|
|
28
|
-
const box = value.subarray(nonce.byteLength)
|
|
29
|
-
const output = b4a.allocUnsafe(box.byteLength - sodium.crypto_secretbox_MACBYTES)
|
|
22
|
+
let rotated = false
|
|
30
23
|
|
|
31
|
-
|
|
32
|
-
|
|
24
|
+
// auto upgrade
|
|
25
|
+
if (type < entropy.type) {
|
|
26
|
+
entropy = this._entropies.find((e) => e.type === type)
|
|
27
|
+
if (!entropy) throw new Error('Missing type: ' + type)
|
|
28
|
+
rotated = true
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return { value: this._decrypt(value, entropy.key), rotated }
|
|
33
32
|
}
|
|
34
33
|
}
|
|
34
|
+
|
|
35
|
+
_encrypt(value, entropy) {
|
|
36
|
+
const buffer = b4a.allocUnsafe(
|
|
37
|
+
value.byteLength + sodium.crypto_secretbox_MACBYTES + sodium.crypto_secretbox_NONCEBYTES
|
|
38
|
+
)
|
|
39
|
+
const nonce = buffer.subarray(0, sodium.crypto_secretbox_NONCEBYTES)
|
|
40
|
+
const box = buffer.subarray(nonce.byteLength)
|
|
41
|
+
|
|
42
|
+
sodium.randombytes_buf(nonce)
|
|
43
|
+
sodium.crypto_secretbox_easy(box, value, nonce, entropy)
|
|
44
|
+
|
|
45
|
+
return buffer
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
_decrypt(value, entropy) {
|
|
49
|
+
const nonce = value.subarray(0, sodium.crypto_secretbox_NONCEBYTES)
|
|
50
|
+
const box = value.subarray(nonce.byteLength)
|
|
51
|
+
const output = b4a.allocUnsafe(box.byteLength - sodium.crypto_secretbox_MACBYTES)
|
|
52
|
+
|
|
53
|
+
sodium.crypto_secretbox_open_easy(output, box, nonce, entropy)
|
|
54
|
+
return output
|
|
55
|
+
}
|
|
35
56
|
}
|
|
36
57
|
|
|
37
58
|
module.exports = BlindEncryptionSodium
|