simple-hpke 0.0.9 → 0.1.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 +43 -35
- package/dist/constants.cjs +1788 -0
- package/dist/constants.cjs.map +7 -0
- package/dist/constants.d.ts +14 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +1771 -0
- package/dist/constants.js.map +7 -0
- package/dist/constants.min.cjs +2 -0
- package/dist/constants.min.cjs.map +7 -0
- package/dist/constants.min.js +2 -0
- package/dist/constants.min.js.map +7 -0
- package/dist/index.cjs +229 -203
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +37 -105
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +229 -203
- package/dist/index.js.map +4 -4
- package/dist/index.min.cjs +1 -1
- package/dist/index.min.cjs.map +4 -4
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +4 -4
- package/dist/meta.json +299 -4
- package/dist/util.cjs +1787 -0
- package/dist/util.cjs.map +7 -0
- package/dist/util.d.ts +90 -0
- package/dist/util.d.ts.map +1 -0
- package/dist/util.js +1770 -0
- package/dist/util.js.map +7 -0
- package/dist/util.min.cjs +2 -0
- package/dist/util.min.cjs.map +7 -0
- package/dist/util.min.js +2 -0
- package/dist/util.min.js.map +7 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Simple HPKE
|
|
2
|
-
[](https://github.com/vanishing-page/simple-hpke/actions/workflows/nodejs.yml)
|
|
3
3
|
[](README.md)
|
|
4
4
|
[](README.md)
|
|
5
5
|
[](https://semver.org/)
|
|
@@ -24,7 +24,7 @@ Hybrid Public Key Encryption
|
|
|
24
24
|
* [Hybrid Encryption](#hybrid-encryption)
|
|
25
25
|
+ [Encrypt / Decrypt](#encrypt--decrypt)
|
|
26
26
|
- [`encrypt`](#encrypt)
|
|
27
|
-
- [
|
|
27
|
+
- [`encrypt.asString`](#encryptasstring)
|
|
28
28
|
- [`decrypt`](#decrypt)
|
|
29
29
|
- [`decrypt.asString`](#decryptasstring)
|
|
30
30
|
- [`decrypt.fromString`](#decryptfromstring)
|
|
@@ -54,44 +54,51 @@ Wrap an AES key, or encrypt a message.
|
|
|
54
54
|
Encrypt an AES key to yourself, then recover it later.
|
|
55
55
|
|
|
56
56
|
```ts
|
|
57
|
-
import { seal, open } from 'simple-hpke'
|
|
57
|
+
import { create, seal, open } from 'simple-hpke'
|
|
58
58
|
|
|
59
|
-
// An X25519 keypair.
|
|
60
|
-
//
|
|
59
|
+
// An X25519 keypair. (asymmetric keypair).
|
|
60
|
+
// The private key can be non-extractable.
|
|
61
|
+
// HPKE only needs `deriveBits`.
|
|
61
62
|
const keypair = await crypto.subtle.generateKey(
|
|
62
63
|
{ name: 'X25519' },
|
|
63
64
|
false, // extractable
|
|
64
65
|
['deriveBits']
|
|
65
66
|
)
|
|
66
67
|
|
|
67
|
-
//
|
|
68
|
-
const {
|
|
68
|
+
// Create a new AES key and encrypt it to your public key.
|
|
69
|
+
const { enc, key } = await create(keypair)
|
|
69
70
|
|
|
70
|
-
// Or wrap an existing AES key. The supplied key must be extractable.
|
|
71
|
+
// Or wrap an existing AES key. The supplied AES key must be extractable.
|
|
71
72
|
const aesKey = await crypto.subtle.generateKey(
|
|
72
73
|
{ name: 'AES-GCM', length: 256 },
|
|
73
74
|
true, // extractable
|
|
74
75
|
['encrypt', 'decrypt']
|
|
75
76
|
)
|
|
76
77
|
|
|
77
|
-
//
|
|
78
|
-
const {
|
|
78
|
+
// Wrap an existing key.
|
|
79
|
+
const { enc: sealedKey } = await seal(keypair, aesKey)
|
|
79
80
|
|
|
80
81
|
// Later, recover the same key with your private key.
|
|
81
|
-
const recoveredKey = await open(keypair,
|
|
82
|
+
const recoveredKey = await open(keypair, sealedKey)
|
|
83
|
+
|
|
84
|
+
// `recoveredKey` is equal to `aesKey`
|
|
82
85
|
```
|
|
83
86
|
|
|
84
87
|
See [docs/README.md](./docs/README.md) for the full API and rationale.
|
|
85
88
|
|
|
89
|
+
|
|
90
|
+
------------------------------------------------------
|
|
91
|
+
|
|
92
|
+
|
|
86
93
|
### Hybrid Encryption
|
|
87
94
|
|
|
88
|
-
|
|
89
|
-
The wrapped key is concattenated with the cipher text,
|
|
90
|
-
IV. The recipient uses their private key to open the AES key and
|
|
91
|
-
the message.
|
|
95
|
+
Encrypt a message with AES-GCM, then encrypt the AES key to a given
|
|
96
|
+
public key. The wrapped key is concattenated with the cipher text,
|
|
97
|
+
along with the IV. The recipient uses their private key to open the AES key and
|
|
98
|
+
decrypt the message.
|
|
92
99
|
|
|
93
100
|
```ts
|
|
94
|
-
import {
|
|
101
|
+
import { create, open } from 'simple-hpke'
|
|
95
102
|
|
|
96
103
|
const recipient = await crypto.subtle.generateKey(
|
|
97
104
|
{ name: 'X25519' },
|
|
@@ -99,31 +106,31 @@ const recipient = await crypto.subtle.generateKey(
|
|
|
99
106
|
['deriveBits']
|
|
100
107
|
)
|
|
101
108
|
|
|
102
|
-
// Create
|
|
103
|
-
const {
|
|
109
|
+
// Create a fresh AES-GCM key, and encrypt a message with it.
|
|
110
|
+
const { enc, key } = await create(recipient)
|
|
104
111
|
const iv = crypto.getRandomValues(new Uint8Array(12))
|
|
105
|
-
const
|
|
112
|
+
const ciphertextBuffer = await crypto.subtle.encrypt(
|
|
106
113
|
{ name: 'AES-GCM', iv },
|
|
107
114
|
key,
|
|
108
115
|
new TextEncoder().encode('attack at dawn')
|
|
109
116
|
)
|
|
110
117
|
|
|
111
|
-
// Send `
|
|
118
|
+
// Send `enc`, `iv`, and `ciphertext` together. `enc` is a fixed
|
|
112
119
|
// 80 bytes for this suite, and the AES-GCM IV is 12 bytes, so the recipient
|
|
113
120
|
// can slice the payload back apart at known offsets.
|
|
114
|
-
const ciphertext = new Uint8Array(
|
|
115
|
-
const message = new Uint8Array(
|
|
116
|
-
message.set(
|
|
117
|
-
message.set(iv,
|
|
118
|
-
message.set(ciphertext,
|
|
121
|
+
const ciphertext = new Uint8Array(ciphertextBuffer)
|
|
122
|
+
const message = new Uint8Array(enc.length + iv.length + ciphertext.length)
|
|
123
|
+
message.set(enc, 0)
|
|
124
|
+
message.set(iv, enc.length)
|
|
125
|
+
message.set(ciphertext, enc.length + iv.length)
|
|
119
126
|
|
|
120
127
|
// On the other side, split the payload back into its parts.
|
|
121
|
-
const
|
|
128
|
+
const enc2 = message.subarray(0, 80)
|
|
122
129
|
const iv2 = message.subarray(80, 80 + 12)
|
|
123
130
|
const ciphertext2 = message.subarray(80 + 12)
|
|
124
131
|
|
|
125
132
|
// Recover the key, then decrypt the message.
|
|
126
|
-
const recovered = await open(recipient,
|
|
133
|
+
const recovered = await open(recipient, enc2)
|
|
127
134
|
const plaintext = await crypto.subtle.decrypt(
|
|
128
135
|
{ name: 'AES-GCM', iv: iv2 },
|
|
129
136
|
recovered,
|
|
@@ -139,7 +146,8 @@ So that was a lot of code to encrypt and decrypt a message...
|
|
|
139
146
|
This package exposes functions `encrypt` and `decrypt` which do the same thing.
|
|
140
147
|
|
|
141
148
|
`encrypt` seals an AES key to the recipient, encrypts the message under
|
|
142
|
-
that key, and returns a single envelope:
|
|
149
|
+
that key, and returns a single envelope:
|
|
150
|
+
`wrappedLen + wrapped + iv + ciphertext`
|
|
143
151
|
(a 2-byte length prefix, the wrapped key, the 12-byte AES-GCM IV, and the
|
|
144
152
|
cipher text). `decrypt` reverses it, returning the plaintext bytes.
|
|
145
153
|
|
|
@@ -149,8 +157,8 @@ cipher text). `decrypt` reverses it, returning the plaintext bytes.
|
|
|
149
157
|
> [`decrypt.fromString`](#decryptfromstring) below for a convenient way
|
|
150
158
|
> to decrypt from a string.
|
|
151
159
|
>
|
|
152
|
-
> See [`encrypt.asString`](#
|
|
153
|
-
>
|
|
160
|
+
> See [`encrypt.asString`](#encryptasstring) for encrypting and encoding to a
|
|
161
|
+
> string.
|
|
154
162
|
>
|
|
155
163
|
|
|
156
164
|
|
|
@@ -211,9 +219,9 @@ async function encrypt (
|
|
|
211
219
|
):Promise<Uint8Array>
|
|
212
220
|
```
|
|
213
221
|
|
|
214
|
-
#####
|
|
222
|
+
##### `encrypt.asString`
|
|
215
223
|
|
|
216
|
-
`encrypt.asString` is `encrypt` with the envelope encoded to a string,
|
|
224
|
+
`encrypt.asString` is `encrypt` with the envelope encoded to a string, useful
|
|
217
225
|
for transports that carry text (JSON, URLs, headers). `opts.encoding` sets the
|
|
218
226
|
string encoding. Default encoding is `base64url`.
|
|
219
227
|
|
|
@@ -242,7 +250,7 @@ bytes to `decrypt` / `decrypt.asString`.
|
|
|
242
250
|
|
|
243
251
|
##### `decrypt`
|
|
244
252
|
|
|
245
|
-
|
|
253
|
+
Decrypt the given data, return a `Uint8Array`.
|
|
246
254
|
|
|
247
255
|
```ts
|
|
248
256
|
async function decrypt (
|
|
@@ -254,7 +262,7 @@ async function decrypt (
|
|
|
254
262
|
|
|
255
263
|
##### `decrypt.asString`
|
|
256
264
|
|
|
257
|
-
Take a `Uint8Array`, return a
|
|
265
|
+
Take a `Uint8Array`, return a string.
|
|
258
266
|
|
|
259
267
|
```ts
|
|
260
268
|
decrypt.asString = async function decryptToString (
|
|
@@ -286,7 +294,7 @@ This exposes ESM and common JS via
|
|
|
286
294
|
|
|
287
295
|
### ESM
|
|
288
296
|
```js
|
|
289
|
-
import { seal, open, encrypt, decrypt } from 'simple-hpke'
|
|
297
|
+
import { create, seal, open, encrypt, decrypt } from 'simple-hpke'
|
|
290
298
|
```
|
|
291
299
|
|
|
292
300
|
### Common JS
|