blind-encryption-sodium 1.0.0 → 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 +27 -5
  2. package/index.js +34 -13
  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,10 +33,25 @@ 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
 
43
+ ### Usage with encryption-encoding
44
+
45
+ Internally, Autobase uses this with encryption-encoding
46
+
47
+ ```js
48
+ const { encrypt, decrypt } = require('encryption-encoding')
49
+ const BlindEncryptionSodium = require('blind-encryption-sodium')
50
+
51
+ const encryptedAndEncoded = await encrypt(encryptionKey, bes.encrypt.bind(bes))
52
+ const decrypted = await decrypt(encryptedAndEncoded, bes.decrypt.bind(bes))
53
+ ```
54
+
33
55
  ## License
34
56
 
35
57
  Apache-2.0
package/index.js CHANGED
@@ -2,34 +2,55 @@ 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)
7
+
8
+ this.encrypt = async (value) => {
9
+ // use latest
10
+ const entropy = this._entropies[0]
11
+ const buffer = this._encrypt(value, entropy.key)
12
+
13
+ return { value: buffer, type: entropy.type }
14
+ }
15
+
16
+ this.decrypt = async ({ value, type }) => {
17
+ let entropy = this._entropies[0]
18
+
19
+ // no backward compat
20
+ if (type > entropy.type) throw new Error('Encrypted using new type: ' + type)
21
+
22
+ let rotated = false
23
+
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 }
32
+ }
8
33
  }
9
34
 
10
- async encrypt(key) {
35
+ _encrypt(value, entropy) {
11
36
  const buffer = b4a.allocUnsafe(
12
- key.byteLength + sodium.crypto_secretbox_MACBYTES + sodium.crypto_secretbox_NONCEBYTES
37
+ value.byteLength + sodium.crypto_secretbox_MACBYTES + sodium.crypto_secretbox_NONCEBYTES
13
38
  )
14
39
  const nonce = buffer.subarray(0, sodium.crypto_secretbox_NONCEBYTES)
15
40
  const box = buffer.subarray(nonce.byteLength)
16
41
 
17
42
  sodium.randombytes_buf(nonce)
18
- sodium.crypto_secretbox_easy(box, key, nonce, this._entropy)
43
+ sodium.crypto_secretbox_easy(box, value, nonce, entropy)
19
44
 
20
- return { value: buffer, type: 1 }
45
+ return buffer
21
46
  }
22
47
 
23
- async decrypt({ value, type }) {
24
- if (type !== this._type) {
25
- throw new Error('Not encrypted using BlindEncryptionSodium')
26
- }
27
-
48
+ _decrypt(value, entropy) {
28
49
  const nonce = value.subarray(0, sodium.crypto_secretbox_NONCEBYTES)
29
50
  const box = value.subarray(nonce.byteLength)
30
51
  const output = b4a.allocUnsafe(box.byteLength - sodium.crypto_secretbox_MACBYTES)
31
52
 
32
- sodium.crypto_secretbox_open_easy(output, box, nonce, this._entropy)
53
+ sodium.crypto_secretbox_open_easy(output, box, nonce, entropy)
33
54
  return output
34
55
  }
35
56
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blind-encryption-sodium",
3
- "version": "1.0.0",
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": {