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.
Files changed (3) hide show
  1. package/README.md +15 -5
  2. package/index.js +42 -21
  3. 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 entropy = b4a.alloc(32) // 32-byte key
12
- // ... fill entropy
11
+ const key = b4a.alloc(32) // 32-byte key
13
12
 
14
- const encryption = new BlindEncryptionSodium(entropy)
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 decrypted = await encryption.decrypt(encrypted)
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(entropy)
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(entropy) {
6
- this._entropy = entropy || null
7
- this._type = 1
5
+ constructor(entropies) {
6
+ this._entropies = entropies.sort((a, b) => b.type - a.type)
8
7
 
9
- this.encrypt = async (key) => {
10
- const buffer = b4a.allocUnsafe(
11
- key.byteLength + sodium.crypto_secretbox_MACBYTES + sodium.crypto_secretbox_NONCEBYTES
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
- sodium.randombytes_buf(nonce)
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
- if (type !== this._type) {
24
- throw new Error('Not encrypted using BlindEncryptionSodium')
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
- const nonce = value.subarray(0, sodium.crypto_secretbox_NONCEBYTES)
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
- sodium.crypto_secretbox_open_easy(output, box, nonce, this._entropy)
32
- return output
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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blind-encryption-sodium",
3
- "version": "1.0.2",
3
+ "version": "2.0.0",
4
4
  "description": "Implemention of encryption encoding for Autobase blind encryption using sodium easy box",
5
5
  "main": "index.js",
6
6
  "exports": {