jose 3.16.0 → 3.19.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 +22 -114
- package/dist/browser/jwe/compact/decrypt.js +5 -1
- package/dist/browser/jwe/flattened/decrypt.js +10 -5
- package/dist/browser/jwe/flattened/encrypt.js +5 -2
- package/dist/browser/jwk/embedded.js +2 -2
- package/dist/browser/jwk/from_key_like.js +2 -2
- package/dist/browser/jwk/parse.js +2 -31
- package/dist/browser/jwk/thumbprint.js +1 -1
- package/dist/browser/jwks/remote.js +2 -2
- package/dist/browser/jws/compact/verify.js +5 -1
- package/dist/browser/jws/flattened/sign.js +5 -2
- package/dist/browser/jws/flattened/verify.js +7 -2
- package/dist/browser/jwt/decrypt.js +5 -1
- package/dist/browser/jwt/unsecured.js +1 -1
- package/dist/browser/jwt/verify.js +5 -1
- package/dist/browser/key/export.js +12 -0
- package/dist/browser/key/import.js +119 -0
- package/dist/browser/lib/decrypt_key_management.js +4 -4
- package/dist/browser/lib/encrypt_key_management.js +3 -3
- package/dist/browser/lib/format_pem.js +4 -0
- package/dist/browser/runtime/aeskw.js +1 -1
- package/dist/browser/runtime/asn1.js +119 -0
- package/dist/browser/runtime/base64url.js +12 -7
- package/dist/browser/runtime/decrypt.js +1 -1
- package/dist/browser/runtime/encrypt.js +1 -1
- package/dist/browser/runtime/fetch_jwks.js +2 -2
- package/dist/browser/runtime/generate.js +18 -2
- package/dist/browser/runtime/global.js +17 -0
- package/dist/browser/runtime/jwk_to_key.js +29 -5
- package/dist/browser/runtime/sign.js +1 -1
- package/dist/browser/runtime/subtle_dsa.js +4 -1
- package/dist/browser/runtime/verify.js +1 -1
- package/dist/node/cjs/jwe/compact/decrypt.js +5 -1
- package/dist/node/cjs/jwe/flattened/decrypt.js +10 -5
- package/dist/node/cjs/jwe/flattened/encrypt.js +5 -2
- package/dist/node/cjs/jwk/embedded.js +2 -2
- package/dist/node/cjs/jwk/from_key_like.js +2 -2
- package/dist/node/cjs/jwk/parse.js +2 -31
- package/dist/node/cjs/jwk/thumbprint.js +1 -1
- package/dist/node/cjs/jwks/remote.js +2 -2
- package/dist/node/cjs/jws/compact/verify.js +5 -1
- package/dist/node/cjs/jws/flattened/sign.js +5 -2
- package/dist/node/cjs/jws/flattened/verify.js +7 -2
- package/dist/node/cjs/jwt/decrypt.js +5 -1
- package/dist/node/cjs/jwt/unsecured.js +1 -1
- package/dist/node/cjs/jwt/verify.js +5 -1
- package/dist/node/cjs/key/export.js +18 -0
- package/dist/node/cjs/key/import.js +126 -0
- package/dist/node/cjs/lib/decrypt_key_management.js +4 -4
- package/dist/node/cjs/lib/encrypt_key_management.js +3 -3
- package/dist/node/cjs/lib/format_pem.js +6 -0
- package/dist/node/cjs/runtime/aeskw.js +1 -1
- package/dist/node/cjs/runtime/asn1.js +46 -0
- package/dist/node/cjs/runtime/asn1_sequence_encoder.js +1 -1
- package/dist/node/cjs/runtime/base64url.js +5 -1
- package/dist/node/cjs/runtime/decrypt.js +1 -1
- package/dist/node/cjs/runtime/ecdhes.js +28 -16
- package/dist/node/cjs/runtime/encrypt.js +1 -1
- package/dist/node/cjs/runtime/generate.js +2 -2
- package/dist/node/cjs/runtime/get_named_curve.js +12 -8
- package/dist/node/cjs/runtime/is_key_object.js +3 -12
- package/dist/node/cjs/runtime/jwk_to_key.js +1 -1
- package/dist/node/cjs/runtime/key_to_jwk.js +3 -3
- package/dist/node/cjs/runtime/webcrypto.js +12 -18
- package/dist/node/esm/jwe/compact/decrypt.js +5 -1
- package/dist/node/esm/jwe/flattened/decrypt.js +10 -5
- package/dist/node/esm/jwe/flattened/encrypt.js +5 -2
- package/dist/node/esm/jwk/embedded.js +2 -2
- package/dist/node/esm/jwk/from_key_like.js +2 -2
- package/dist/node/esm/jwk/parse.js +2 -31
- package/dist/node/esm/jwk/thumbprint.js +1 -1
- package/dist/node/esm/jwks/remote.js +2 -2
- package/dist/node/esm/jws/compact/verify.js +5 -1
- package/dist/node/esm/jws/flattened/sign.js +5 -2
- package/dist/node/esm/jws/flattened/verify.js +7 -2
- package/dist/node/esm/jwt/decrypt.js +5 -1
- package/dist/node/esm/jwt/unsecured.js +1 -1
- package/dist/node/esm/jwt/verify.js +5 -1
- package/dist/node/esm/key/export.js +12 -0
- package/dist/node/esm/key/import.js +119 -0
- package/dist/node/esm/lib/decrypt_key_management.js +4 -4
- package/dist/node/esm/lib/encrypt_key_management.js +3 -3
- package/dist/node/esm/lib/format_pem.js +4 -0
- package/dist/node/esm/runtime/aeskw.js +1 -1
- package/dist/node/esm/runtime/asn1.js +39 -0
- package/dist/node/esm/runtime/asn1_sequence_encoder.js +1 -1
- package/dist/node/esm/runtime/base64url.js +2 -0
- package/dist/node/esm/runtime/decrypt.js +1 -1
- package/dist/node/esm/runtime/ecdhes.js +28 -16
- package/dist/node/esm/runtime/encrypt.js +1 -1
- package/dist/node/esm/runtime/generate.js +2 -2
- package/dist/node/esm/runtime/get_named_curve.js +12 -8
- package/dist/node/esm/runtime/is_key_object.js +3 -12
- package/dist/node/esm/runtime/jwk_to_key.js +1 -1
- package/dist/node/esm/runtime/key_to_jwk.js +3 -3
- package/dist/node/esm/runtime/webcrypto.js +12 -18
- package/dist/types/jwe/compact/decrypt.d.ts +3 -2
- package/dist/types/jwe/flattened/decrypt.d.ts +3 -2
- package/dist/types/jwe/general/decrypt.d.ts +3 -2
- package/dist/types/jws/compact/verify.d.ts +3 -2
- package/dist/types/jws/flattened/verify.d.ts +3 -2
- package/dist/types/jws/general/verify.d.ts +3 -2
- package/dist/types/jwt/decrypt.d.ts +3 -2
- package/dist/types/jwt/verify.d.ts +3 -2
- package/dist/types/key/export.d.ts +5 -0
- package/dist/types/key/import.d.ts +9 -0
- package/dist/types/types.d.ts +3 -0
- package/package.json +18 -115
package/README.md
CHANGED
|
@@ -23,40 +23,6 @@ implementation is correct.
|
|
|
23
23
|
|
|
24
24
|
If you or your business use `jose`, please consider becoming a [sponsor][support-sponsor] so I can continue maintaining it and adding new features carefree.
|
|
25
25
|
|
|
26
|
-
## Install
|
|
27
|
-
|
|
28
|
-
```console
|
|
29
|
-
npm install jose
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
<details>
|
|
33
|
-
<summary><em>Looking for a Browser only distribution?</em> (Click to expand)</summary>
|
|
34
|
-
|
|
35
|
-
```console
|
|
36
|
-
npm install jose-browser-runtime
|
|
37
|
-
```
|
|
38
|
-
</details>
|
|
39
|
-
|
|
40
|
-
<details>
|
|
41
|
-
<summary><em>Looking for a Deno distribution?</em> (Click to expand)</summary>
|
|
42
|
-
|
|
43
|
-
see [deno.land/x/jose][]
|
|
44
|
-
</details>
|
|
45
|
-
|
|
46
|
-
<details>
|
|
47
|
-
<summary><em>Looking for a Node.js only distribution?</em> (Click to expand)</summary>
|
|
48
|
-
|
|
49
|
-
ESM module (import):
|
|
50
|
-
```console
|
|
51
|
-
npm install jose-node-esm-runtime
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
CJS module (require):
|
|
55
|
-
```console
|
|
56
|
-
npm install jose-node-cjs-runtime
|
|
57
|
-
```
|
|
58
|
-
</details>
|
|
59
|
-
|
|
60
26
|
## Documentation
|
|
61
27
|
|
|
62
28
|
- JSON Web Tokens (JWT)
|
|
@@ -65,6 +31,11 @@ npm install jose-node-cjs-runtime
|
|
|
65
31
|
- Encrypted JSON Web Tokens
|
|
66
32
|
- [Encryption](docs/classes/jwt_encrypt.EncryptJWT.md#readme)
|
|
67
33
|
- [Decryption & Claims Set Validation](docs/functions/jwt_decrypt.jwtDecrypt.md#readme)
|
|
34
|
+
- Key Import
|
|
35
|
+
- [JWK Import](docs/functions/key_import.importJWK.md#readme)
|
|
36
|
+
- [Public Key Import (SPKI)](docs/functions/key_import.importSPKI.md#readme)
|
|
37
|
+
- [Public Key Import (X.509 Certificate)](docs/functions/key_import.importX509.md#readme)
|
|
38
|
+
- [Private Key Import (PKCS #8)](docs/functions/key_import.importPKCS8.md#readme)
|
|
68
39
|
- JSON Web Encryption (JWE)
|
|
69
40
|
- Encryption - [Compact](docs/classes/jwe_compact_encrypt.CompactEncrypt.md#readme), [Flattened](docs/classes/jwe_flattened_encrypt.FlattenedEncrypt.md#readme)
|
|
70
41
|
- Decryption - [Compact](docs/functions/jwe_compact_decrypt.compactDecrypt.md#readme), [Flattened](docs/functions/jwe_flattened_decrypt.flattenedDecrypt.md#readme), [General](docs/functions/jwe_general_decrypt.generalDecrypt.md#readme)
|
|
@@ -72,96 +43,29 @@ npm install jose-node-cjs-runtime
|
|
|
72
43
|
- Signing - [Compact](docs/classes/jws_compact_sign.CompactSign.md#readme), [Flattened](docs/classes/jws_flattened_sign.FlattenedSign.md#readme), [General](docs/classes/jws_general_sign.GeneralSign.md#readme)
|
|
73
44
|
- Verification - [Compact](docs/functions/jws_compact_verify.compactVerify.md#readme), [Flattened](docs/functions/jws_flattened_verify.flattenedVerify.md#readme), [General](docs/functions/jws_general_verify.generalVerify.md#readme)
|
|
74
45
|
- JSON Web Key (JWK)
|
|
75
|
-
- [Parsing (JWK to KeyLike)](docs/functions/jwk_parse.parseJwk.md#readme)
|
|
76
|
-
- [Conversion (KeyLike to JWK)](docs/functions/jwk_from_key_like.fromKeyLike.md#readme)
|
|
77
46
|
- [Thumbprints](docs/functions/jwk_thumbprint.calculateThumbprint.md#readme)
|
|
78
47
|
- [EmbeddedJWK](docs/functions/jwk_embedded.EmbeddedJWK.md#readme)
|
|
79
48
|
- JSON Web Key Set (JWKS)
|
|
80
49
|
- [Verify using a remote JWKSet](docs/functions/jwks_remote.createRemoteJWKSet.md#readme)
|
|
81
|
-
- Key Pair or Secret Generation
|
|
50
|
+
- Key Pair or Secret Generation
|
|
82
51
|
- [Asymmetric Key Pair Generation](docs/functions/util_generate_key_pair.generateKeyPair.md#readme)
|
|
83
52
|
- [Symmetric Secret Generation](docs/functions/util_generate_secret.generateSecret.md#readme)
|
|
53
|
+
- Key Export
|
|
54
|
+
- [JWK Export](docs/functions/key_export.exportJWK.md#readme)
|
|
55
|
+
- [Private Key Export](docs/functions/key_export.exportPKCS8.md#readme)
|
|
56
|
+
- [Public Key Export](docs/functions/key_export.exportSPKI.md#readme)
|
|
84
57
|
- Utilities
|
|
85
58
|
- [Decoding Token's Protected Header](docs/functions/util_decode_protected_header.decodeProtectedHeader.md#readme)
|
|
86
59
|
- [Unsecured JWT](docs/classes/jwt_unsecured.UnsecuredJWT.md#readme)
|
|
87
60
|
- [JOSE Errors](docs/modules/util_errors.md#readme)
|
|
88
61
|
|
|
89
|
-
##
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
| Octet sequence | ✓ | oct | |
|
|
97
|
-
|
|
98
|
-
| Serialization | JWS Sign | JWS Verify | JWE Encrypt | JWE Decrypt |
|
|
99
|
-
| -- | -- | -- | -- | -- |
|
|
100
|
-
| Compact | ✓ | ✓ | ✓ | ✓ |
|
|
101
|
-
| General JSON | ✓ | ✓ | ✕ | ✓ |
|
|
102
|
-
| Flattened JSON | ✓ | ✓ | ✓ | ✓ |
|
|
103
|
-
|
|
104
|
-
| JWT Sign | JWT Verify | JWT Encrypt | JWT Decrypt |
|
|
105
|
-
| -- | -- | -- | -- |
|
|
106
|
-
| ✓ | ✓ | ✓ | ✓ |
|
|
107
|
-
|
|
108
|
-
| JWS Algorithms | Supported | |
|
|
109
|
-
| -- | -- | -- |
|
|
110
|
-
| RSASSA-PKCS1-v1_5 | ✓ | RS256, RS384, RS512 |
|
|
111
|
-
| RSASSA-PSS | ✓ | PS256, PS384, PS512 |
|
|
112
|
-
| ECDSA | ✓ | ES256, ES256K, ES384, ES512 |
|
|
113
|
-
| Edwards-curve DSA | ✓ | EdDSA |
|
|
114
|
-
| HMAC with SHA-2 | ✓ | HS256, HS384, HS512 |
|
|
115
|
-
| Unsecured JWS | ✓ | none |
|
|
116
|
-
|
|
117
|
-
| JWE Key Management Algorithms | Supported | |
|
|
118
|
-
| -- | -- | -- |
|
|
119
|
-
| AES | ✓ | A128KW, A192KW, A256KW |
|
|
120
|
-
| AES GCM | ✓ | A128GCMKW, A192GCMKW, A256GCMKW |
|
|
121
|
-
| Direct Key Agreement | ✓ | dir |
|
|
122
|
-
| RSAES OAEP | ✓ | RSA-OAEP, RSA-OAEP-256, RSA-OAEP-384, RSA-OAEP-512 |
|
|
123
|
-
| RSAES-PKCS1-v1_5 | ✓ | RSA1_5 |
|
|
124
|
-
| PBES2 | ✓ | PBES2-HS256+A128KW, PBES2-HS384+A192KW, PBES2-HS512+A256KW |
|
|
125
|
-
| ECDH-ES | ✓ | ECDH-ES, ECDH-ES+A128KW, ECDH-ES+A192KW, ECDH-ES+A256KW |
|
|
126
|
-
|
|
127
|
-
| JWE Content Encryption Algorithms | Supported | |
|
|
128
|
-
| -- | -- | -- |
|
|
129
|
-
| AES GCM | ✓ | A128GCM, A192GCM, A256GCM |
|
|
130
|
-
| AES CBC w/ HMAC | ✓ | A128CBC-HS256, A192CBC-HS384, A256CBC-HS512 |
|
|
131
|
-
|
|
132
|
-
Legend:
|
|
133
|
-
- **✓** Implemented
|
|
134
|
-
- **✕** Not Considered
|
|
135
|
-
|
|
136
|
-
## Runtime Support Matrix
|
|
137
|
-
|
|
138
|
-
| Platform | supported versions | caveats |
|
|
139
|
-
| -- | -- | -- |
|
|
140
|
-
| Node.js | LTS ^12.19.0 || ^14.15.0 | |
|
|
141
|
-
| Electron | ^12.0.0 | see <sup>[1]</sup> |
|
|
142
|
-
| Cloudflare Workers | ✓ | see <sup>[2], [4]</sup> |
|
|
143
|
-
| Deno | experimental | see Deno's [Web Cryptography API roadmap](https://github.com/denoland/deno/issues/11690) |
|
|
144
|
-
| React Native | ✕ | has no available and usable crypto runtime |
|
|
145
|
-
| IE | ✕ | implements old version of the Web Cryptography API specification |
|
|
146
|
-
| Browsers | see [caniuse.com][caniuse] | |
|
|
147
|
-
| --- | | |
|
|
148
|
-
| Edge | 79+ | see <sup>[2], [4]</sup> |
|
|
149
|
-
| Firefox | 57+ | see <sup>[2]</sup> |
|
|
150
|
-
| Chrome | 63+ | see <sup>[2], [4]</sup> |
|
|
151
|
-
| Safari | 11+ | see <sup>[2], [3]</sup> |
|
|
152
|
-
| Opera | 50+ | see <sup>[2], [4]</sup> |
|
|
153
|
-
| iOS Safari | 12+ | see <sup>[2], [3]</sup> |
|
|
154
|
-
|
|
155
|
-
<sup>1</sup> Due to its use of BoringSSL the following is not supported in Electron
|
|
156
|
-
- A128KW, A192KW, A256KW, and all composite algorithms utilizing those
|
|
157
|
-
- secp256k1 EC curve
|
|
158
|
-
- Ed448, X25519, and X448 OKP Sub Types
|
|
159
|
-
|
|
160
|
-
<sup>2</sup> RSA1_5, OKP JWK Key Type, and secp256k1 EC curve is not supported in [Web Cryptography API][webcrypto].
|
|
161
|
-
|
|
162
|
-
<sup>3</sup> P-521 EC curve is not supported in Safari
|
|
163
|
-
|
|
164
|
-
<sup>4</sup> 192 bit AES keys are not supported in Chromium
|
|
62
|
+
## Supported Runtimes, Environments, Platforms
|
|
63
|
+
|
|
64
|
+
- [Browser Support][]
|
|
65
|
+
- [Cloudflare Workers Support][]
|
|
66
|
+
- [Deno Support][]
|
|
67
|
+
- [Electron Support][]
|
|
68
|
+
- [Node.js Support][]
|
|
165
69
|
|
|
166
70
|
## FAQ
|
|
167
71
|
|
|
@@ -240,5 +144,9 @@ install size should not be a cause for concern.
|
|
|
240
144
|
[conditional-exports]: https://nodejs.org/api/packages.html#packages_conditional_exports
|
|
241
145
|
[webcrypto]: https://www.w3.org/TR/WebCryptoAPI/
|
|
242
146
|
[nodewebcrypto]: https://nodejs.org/docs/latest-v15.x/api/webcrypto.html
|
|
243
|
-
[caniuse]: https://caniuse.com/mdn-javascript_operators_await,async-functions,mdn-javascript_statements_for_await_of,cryptography,textencoder
|
|
244
147
|
[deno.land/x/jose]: https://deno.land/x/jose
|
|
148
|
+
[Browser Support]: https://github.com/panva/jose/issues/263
|
|
149
|
+
[Cloudflare Workers Support]: https://github.com/panva/jose/issues/265
|
|
150
|
+
[Deno Support]: https://github.com/panva/jose/issues/266
|
|
151
|
+
[Electron Support]: https://github.com/panva/jose/issues/264
|
|
152
|
+
[Node.js Support]: https://github.com/panva/jose/issues/262
|
|
@@ -19,7 +19,11 @@ async function compactDecrypt(jwe, key, options) {
|
|
|
19
19
|
tag: (tag || undefined),
|
|
20
20
|
encrypted_key: encryptedKey || undefined,
|
|
21
21
|
}, key, options);
|
|
22
|
-
|
|
22
|
+
const result = { plaintext: decrypted.plaintext, protectedHeader: decrypted.protectedHeader };
|
|
23
|
+
if (typeof key === 'function') {
|
|
24
|
+
return { ...result, key: decrypted.key };
|
|
25
|
+
}
|
|
26
|
+
return result;
|
|
23
27
|
}
|
|
24
28
|
export { compactDecrypt };
|
|
25
29
|
export default compactDecrypt;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { JOSEAlgNotAllowed, JOSENotSupported, JWEInvalid } from '../../util/errors.js';
|
|
2
|
-
import isDisjoint from '../../lib/is_disjoint.js';
|
|
3
|
-
import isObject from '../../lib/is_object.js';
|
|
4
1
|
import { decode as base64url } from '../../runtime/base64url.js';
|
|
5
2
|
import decrypt from '../../runtime/decrypt.js';
|
|
6
3
|
import { inflate } from '../../runtime/zlib.js';
|
|
4
|
+
import random from '../../runtime/random.js';
|
|
5
|
+
import { JOSEAlgNotAllowed, JOSENotSupported, JWEInvalid } from '../../util/errors.js';
|
|
6
|
+
import isDisjoint from '../../lib/is_disjoint.js';
|
|
7
|
+
import isObject from '../../lib/is_object.js';
|
|
7
8
|
import decryptKeyManagement from '../../lib/decrypt_key_management.js';
|
|
8
9
|
import { encoder, decoder, concat } from '../../lib/buffer_utils.js';
|
|
9
10
|
import cekFactory from '../../lib/cek.js';
|
|
10
|
-
import random from '../../runtime/random.js';
|
|
11
11
|
import validateCrit from '../../lib/validate_crit.js';
|
|
12
12
|
import validateAlgorithms from '../../lib/validate_algorithms.js';
|
|
13
13
|
const generateCek = cekFactory(random);
|
|
@@ -70,7 +70,7 @@ async function flattenedDecrypt(jwe, key, options) {
|
|
|
70
70
|
throw new JWEInvalid('JWE "zip" (Compression Algorithm) Header MUST be integrity protected');
|
|
71
71
|
}
|
|
72
72
|
if (joseHeader.zip !== 'DEF') {
|
|
73
|
-
throw new JOSENotSupported('
|
|
73
|
+
throw new JOSENotSupported('Unsupported JWE "zip" (Compression Algorithm) Header Parameter value');
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
const { alg, enc } = joseHeader;
|
|
@@ -92,8 +92,10 @@ async function flattenedDecrypt(jwe, key, options) {
|
|
|
92
92
|
if (jwe.encrypted_key !== undefined) {
|
|
93
93
|
encryptedKey = base64url(jwe.encrypted_key);
|
|
94
94
|
}
|
|
95
|
+
let resolvedKey = false;
|
|
95
96
|
if (typeof key === 'function') {
|
|
96
97
|
key = await key(parsedProt, jwe);
|
|
98
|
+
resolvedKey = true;
|
|
97
99
|
}
|
|
98
100
|
let cek;
|
|
99
101
|
try {
|
|
@@ -132,6 +134,9 @@ async function flattenedDecrypt(jwe, key, options) {
|
|
|
132
134
|
if (jwe.header !== undefined) {
|
|
133
135
|
result.unprotectedHeader = jwe.header;
|
|
134
136
|
}
|
|
137
|
+
if (resolvedKey) {
|
|
138
|
+
return { ...result, key };
|
|
139
|
+
}
|
|
135
140
|
return result;
|
|
136
141
|
}
|
|
137
142
|
export { flattenedDecrypt };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import ivFactory from '../../lib/iv.js';
|
|
2
1
|
import { encode as base64url } from '../../runtime/base64url.js';
|
|
3
2
|
import random from '../../runtime/random.js';
|
|
4
3
|
import encrypt from '../../runtime/encrypt.js';
|
|
5
4
|
import { deflate } from '../../runtime/zlib.js';
|
|
5
|
+
import ivFactory from '../../lib/iv.js';
|
|
6
6
|
import encryptKeyManagement from '../../lib/encrypt_key_management.js';
|
|
7
7
|
import { JOSENotSupported, JWEInvalid } from '../../util/errors.js';
|
|
8
8
|
import isDisjoint from '../../lib/is_disjoint.js';
|
|
@@ -12,6 +12,9 @@ const generateIv = ivFactory(random);
|
|
|
12
12
|
const checkExtensions = validateCrit.bind(undefined, JWEInvalid, new Map());
|
|
13
13
|
class FlattenedEncrypt {
|
|
14
14
|
constructor(plaintext) {
|
|
15
|
+
if (!(plaintext instanceof Uint8Array)) {
|
|
16
|
+
throw new TypeError('plaintext must be an instance of Uint8Array');
|
|
17
|
+
}
|
|
15
18
|
this._plaintext = plaintext;
|
|
16
19
|
}
|
|
17
20
|
setKeyManagementParameters(parameters) {
|
|
@@ -78,7 +81,7 @@ class FlattenedEncrypt {
|
|
|
78
81
|
throw new JWEInvalid('JWE "zip" (Compression Algorithm) Header MUST be integrity protected');
|
|
79
82
|
}
|
|
80
83
|
if (joseHeader.zip !== 'DEF') {
|
|
81
|
-
throw new JOSENotSupported('
|
|
84
|
+
throw new JOSENotSupported('Unsupported JWE "zip" (Compression Algorithm) Header Parameter value');
|
|
82
85
|
}
|
|
83
86
|
}
|
|
84
87
|
const { alg, enc } = joseHeader;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { importJWK } from '../key/import.js';
|
|
2
2
|
import isObject from '../lib/is_object.js';
|
|
3
3
|
import { JWSInvalid } from '../util/errors.js';
|
|
4
4
|
async function EmbeddedJWK(protectedHeader, token) {
|
|
@@ -9,7 +9,7 @@ async function EmbeddedJWK(protectedHeader, token) {
|
|
|
9
9
|
if (!isObject(joseHeader.jwk)) {
|
|
10
10
|
throw new JWSInvalid('"jwk" (JSON Web Key) Header Parameter must be a JSON object');
|
|
11
11
|
}
|
|
12
|
-
const key = await
|
|
12
|
+
const key = (await importJWK({ ...joseHeader.jwk, ext: true }, joseHeader.alg, true));
|
|
13
13
|
if (key.type !== 'public') {
|
|
14
14
|
throw new JWSInvalid('"jwk" (JSON Web Key) Header Parameter must be a public key');
|
|
15
15
|
}
|
|
@@ -1,35 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import asKeyObject from '../runtime/jwk_to_key.js';
|
|
3
|
-
import { JOSENotSupported } from '../util/errors.js';
|
|
4
|
-
import isObject from '../lib/is_object.js';
|
|
1
|
+
import { importJWK } from '../key/import.js';
|
|
5
2
|
async function parseJwk(jwk, alg, octAsKeyObject) {
|
|
6
|
-
|
|
7
|
-
throw new TypeError('JWK must be an object');
|
|
8
|
-
}
|
|
9
|
-
alg || (alg = jwk.alg);
|
|
10
|
-
if (typeof alg !== 'string' || !alg) {
|
|
11
|
-
throw new TypeError('"alg" argument is required when "jwk.alg" is not present');
|
|
12
|
-
}
|
|
13
|
-
switch (jwk.kty) {
|
|
14
|
-
case 'oct':
|
|
15
|
-
if (typeof jwk.k !== 'string' || !jwk.k) {
|
|
16
|
-
throw new TypeError('missing "k" (Key Value) Parameter value');
|
|
17
|
-
}
|
|
18
|
-
octAsKeyObject !== null && octAsKeyObject !== void 0 ? octAsKeyObject : (octAsKeyObject = jwk.ext !== true);
|
|
19
|
-
if (octAsKeyObject) {
|
|
20
|
-
return asKeyObject({ ...jwk, alg, ext: false });
|
|
21
|
-
}
|
|
22
|
-
return base64url(jwk.k);
|
|
23
|
-
case 'RSA':
|
|
24
|
-
if (jwk.oth !== undefined) {
|
|
25
|
-
throw new JOSENotSupported('RSA JWK "oth" (Other Primes Info) Parameter value is not supported');
|
|
26
|
-
}
|
|
27
|
-
case 'EC':
|
|
28
|
-
case 'OKP':
|
|
29
|
-
return asKeyObject({ ...jwk, alg });
|
|
30
|
-
default:
|
|
31
|
-
throw new JOSENotSupported('unsupported "kty" (Key Type) Parameter value');
|
|
32
|
-
}
|
|
3
|
+
return importJWK(jwk, alg, octAsKeyObject);
|
|
33
4
|
}
|
|
34
5
|
export { parseJwk };
|
|
35
6
|
export default parseJwk;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { JOSENotSupported, JWKInvalid } from '../util/errors.js';
|
|
2
1
|
import digest from '../runtime/digest.js';
|
|
3
2
|
import { encode as base64url } from '../runtime/base64url.js';
|
|
3
|
+
import { JOSENotSupported, JWKInvalid } from '../util/errors.js';
|
|
4
4
|
import { encoder } from '../lib/buffer_utils.js';
|
|
5
5
|
import isObject from '../lib/is_object.js';
|
|
6
6
|
const check = (value, description) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import fetchJwks from '../runtime/fetch_jwks.js';
|
|
1
2
|
import parseJWK from '../jwk/parse.js';
|
|
2
3
|
import { JWKSInvalid, JOSENotSupported, JWKSNoMatchingKey, JWKSMultipleMatchingKeys, } from '../util/errors.js';
|
|
3
|
-
import fetchJwks from '../runtime/fetch_jwks.js';
|
|
4
4
|
import isObject from '../lib/is_object.js';
|
|
5
5
|
function getKtyFromAlg(alg) {
|
|
6
6
|
switch (alg.substr(0, 2)) {
|
|
@@ -93,7 +93,7 @@ class RemoteJWKSet {
|
|
|
93
93
|
}
|
|
94
94
|
const cached = this._cached.get(jwk);
|
|
95
95
|
if (cached[protectedHeader.alg] === undefined) {
|
|
96
|
-
const keyObject = await parseJWK({ ...jwk, alg: protectedHeader.alg });
|
|
96
|
+
const keyObject = (await parseJWK({ ...jwk, alg: protectedHeader.alg, ext: true }));
|
|
97
97
|
if (keyObject.type !== 'public') {
|
|
98
98
|
throw new JWKSInvalid('JSON Web Key Set members must be public keys');
|
|
99
99
|
}
|
|
@@ -17,7 +17,11 @@ async function compactVerify(jws, key, options) {
|
|
|
17
17
|
protected: protectedHeader || undefined,
|
|
18
18
|
signature: (signature || undefined),
|
|
19
19
|
}, key, options);
|
|
20
|
-
|
|
20
|
+
const result = { payload: verified.payload, protectedHeader: verified.protectedHeader };
|
|
21
|
+
if (typeof key === 'function') {
|
|
22
|
+
return { ...result, key: verified.key };
|
|
23
|
+
}
|
|
24
|
+
return result;
|
|
21
25
|
}
|
|
22
26
|
export { compactVerify };
|
|
23
27
|
export default compactVerify;
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
+
import { encode as base64url } from '../../runtime/base64url.js';
|
|
2
|
+
import sign from '../../runtime/sign.js';
|
|
1
3
|
import isDisjoint from '../../lib/is_disjoint.js';
|
|
2
4
|
import { JWSInvalid } from '../../util/errors.js';
|
|
3
5
|
import { encoder, decoder, concat } from '../../lib/buffer_utils.js';
|
|
4
|
-
import { encode as base64url } from '../../runtime/base64url.js';
|
|
5
|
-
import sign from '../../runtime/sign.js';
|
|
6
6
|
import checkKeyType from '../../lib/check_key_type.js';
|
|
7
7
|
import validateCrit from '../../lib/validate_crit.js';
|
|
8
8
|
const checkExtensions = validateCrit.bind(undefined, JWSInvalid, new Map([['b64', true]]));
|
|
9
9
|
class FlattenedSign {
|
|
10
10
|
constructor(payload) {
|
|
11
|
+
if (!(payload instanceof Uint8Array)) {
|
|
12
|
+
throw new TypeError('payload must be an instance of Uint8Array');
|
|
13
|
+
}
|
|
11
14
|
this._payload = payload;
|
|
12
15
|
}
|
|
13
16
|
setProtectedHeader(protectedHeader) {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { decode as base64url } from '../../runtime/base64url.js';
|
|
2
|
+
import verify from '../../runtime/verify.js';
|
|
1
3
|
import { JOSEAlgNotAllowed, JWSInvalid, JWSSignatureVerificationFailed } from '../../util/errors.js';
|
|
2
4
|
import { concat, encoder, decoder } from '../../lib/buffer_utils.js';
|
|
3
5
|
import isDisjoint from '../../lib/is_disjoint.js';
|
|
4
6
|
import isObject from '../../lib/is_object.js';
|
|
5
7
|
import checkKeyType from '../../lib/check_key_type.js';
|
|
6
|
-
import { decode as base64url } from '../../runtime/base64url.js';
|
|
7
|
-
import verify from '../../runtime/verify.js';
|
|
8
8
|
import validateCrit from '../../lib/validate_crit.js';
|
|
9
9
|
import validateAlgorithms from '../../lib/validate_algorithms.js';
|
|
10
10
|
const checkExtensions = validateCrit.bind(undefined, JWSInvalid, new Map([['b64', true]]));
|
|
@@ -70,8 +70,10 @@ async function flattenedVerify(jws, key, options) {
|
|
|
70
70
|
else if (typeof jws.payload !== 'string' && !(jws.payload instanceof Uint8Array)) {
|
|
71
71
|
throw new JWSInvalid('JWS Payload must be a string or an Uint8Array instance');
|
|
72
72
|
}
|
|
73
|
+
let resolvedKey = false;
|
|
73
74
|
if (typeof key === 'function') {
|
|
74
75
|
key = await key(parsedProt, jws);
|
|
76
|
+
resolvedKey = true;
|
|
75
77
|
}
|
|
76
78
|
checkKeyType(alg, key, 'verify');
|
|
77
79
|
const data = concat(encoder.encode((_a = jws.protected) !== null && _a !== void 0 ? _a : ''), encoder.encode('.'), typeof jws.payload === 'string' ? encoder.encode(jws.payload) : jws.payload);
|
|
@@ -97,6 +99,9 @@ async function flattenedVerify(jws, key, options) {
|
|
|
97
99
|
if (jws.header !== undefined) {
|
|
98
100
|
result.unprotectedHeader = jws.header;
|
|
99
101
|
}
|
|
102
|
+
if (resolvedKey) {
|
|
103
|
+
return { ...result, key };
|
|
104
|
+
}
|
|
100
105
|
return result;
|
|
101
106
|
}
|
|
102
107
|
export { flattenedVerify };
|
|
@@ -15,7 +15,11 @@ async function jwtDecrypt(jwt, key, options) {
|
|
|
15
15
|
JSON.stringify(protectedHeader.aud) !== JSON.stringify(payload.aud)) {
|
|
16
16
|
throw new JWTClaimValidationFailed('replicated "aud" claim header parameter mismatch', 'aud', 'mismatch');
|
|
17
17
|
}
|
|
18
|
-
|
|
18
|
+
const result = { payload, protectedHeader };
|
|
19
|
+
if (typeof key === 'function') {
|
|
20
|
+
return { ...result, key: decrypted.key };
|
|
21
|
+
}
|
|
22
|
+
return result;
|
|
19
23
|
}
|
|
20
24
|
export { jwtDecrypt };
|
|
21
25
|
export default jwtDecrypt;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { decoder } from '../lib/buffer_utils.js';
|
|
2
1
|
import * as base64url from '../runtime/base64url.js';
|
|
2
|
+
import { decoder } from '../lib/buffer_utils.js';
|
|
3
3
|
import { JWTInvalid } from '../util/errors.js';
|
|
4
4
|
import jwtPayload from '../lib/jwt_claims_set.js';
|
|
5
5
|
import ProduceJWT from '../lib/jwt_producer.js';
|
|
@@ -8,7 +8,11 @@ async function jwtVerify(jwt, key, options) {
|
|
|
8
8
|
throw new JWTInvalid('JWTs MUST NOT use unencoded payload');
|
|
9
9
|
}
|
|
10
10
|
const payload = jwtPayload(verified.protectedHeader, verified.payload, options);
|
|
11
|
-
|
|
11
|
+
const result = { payload, protectedHeader: verified.protectedHeader };
|
|
12
|
+
if (typeof key === 'function') {
|
|
13
|
+
return { ...result, key: verified.key };
|
|
14
|
+
}
|
|
15
|
+
return result;
|
|
12
16
|
}
|
|
13
17
|
export { jwtVerify };
|
|
14
18
|
export default jwtVerify;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { toSPKI as exportPublic } from '../runtime/asn1.js';
|
|
2
|
+
import { toPKCS8 as exportPrivate } from '../runtime/asn1.js';
|
|
3
|
+
import keyToJWK from '../runtime/key_to_jwk.js';
|
|
4
|
+
export async function exportSPKI(key) {
|
|
5
|
+
return exportPublic(key);
|
|
6
|
+
}
|
|
7
|
+
export async function exportPKCS8(key) {
|
|
8
|
+
return exportPrivate(key);
|
|
9
|
+
}
|
|
10
|
+
export async function exportJWK(key) {
|
|
11
|
+
return keyToJWK(key);
|
|
12
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { decode as decodeBase64URL, encodeBase64, decodeBase64 } from '../runtime/base64url.js';
|
|
2
|
+
import { fromSPKI as importPublic } from '../runtime/asn1.js';
|
|
3
|
+
import { fromPKCS8 as importPrivate } from '../runtime/asn1.js';
|
|
4
|
+
import asKeyObject from '../runtime/jwk_to_key.js';
|
|
5
|
+
import { JOSENotSupported } from '../util/errors.js';
|
|
6
|
+
import formatPEM from '../lib/format_pem.js';
|
|
7
|
+
import isObject from '../lib/is_object.js';
|
|
8
|
+
function getElement(seq) {
|
|
9
|
+
let result = [];
|
|
10
|
+
let next = 0;
|
|
11
|
+
while (next < seq.length) {
|
|
12
|
+
let nextPart = parseElement(seq.subarray(next));
|
|
13
|
+
result.push(nextPart);
|
|
14
|
+
next += nextPart.byteLength;
|
|
15
|
+
}
|
|
16
|
+
return result;
|
|
17
|
+
}
|
|
18
|
+
function parseElement(bytes) {
|
|
19
|
+
let position = 0;
|
|
20
|
+
let tag = bytes[0] & 0x1f;
|
|
21
|
+
position++;
|
|
22
|
+
if (tag === 0x1f) {
|
|
23
|
+
tag = 0;
|
|
24
|
+
while (bytes[position] >= 0x80) {
|
|
25
|
+
tag = tag * 128 + bytes[position] - 0x80;
|
|
26
|
+
position++;
|
|
27
|
+
}
|
|
28
|
+
tag = tag * 128 + bytes[position] - 0x80;
|
|
29
|
+
position++;
|
|
30
|
+
}
|
|
31
|
+
let length = 0;
|
|
32
|
+
if (bytes[position] < 0x80) {
|
|
33
|
+
length = bytes[position];
|
|
34
|
+
position++;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
let numberOfDigits = bytes[position] & 0x7f;
|
|
38
|
+
position++;
|
|
39
|
+
length = 0;
|
|
40
|
+
for (let i = 0; i < numberOfDigits; i++) {
|
|
41
|
+
length = length * 256 + bytes[position];
|
|
42
|
+
position++;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (length === 0x80) {
|
|
46
|
+
length = 0;
|
|
47
|
+
while (bytes[position + length] !== 0 || bytes[position + length + 1] !== 0) {
|
|
48
|
+
length++;
|
|
49
|
+
}
|
|
50
|
+
const byteLength = position + length + 2;
|
|
51
|
+
return {
|
|
52
|
+
byteLength,
|
|
53
|
+
contents: bytes.subarray(position, position + length),
|
|
54
|
+
raw: bytes.subarray(0, byteLength),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
const byteLength = position + length;
|
|
58
|
+
return {
|
|
59
|
+
byteLength,
|
|
60
|
+
contents: bytes.subarray(position, byteLength),
|
|
61
|
+
raw: bytes.subarray(0, byteLength),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function spkiFromX509(buf) {
|
|
65
|
+
return encodeBase64(getElement(getElement(parseElement(buf).contents)[0].contents)[6].raw);
|
|
66
|
+
}
|
|
67
|
+
function getSPKI(x509) {
|
|
68
|
+
const pem = x509.replace(/(?:-----(?:BEGIN|END) CERTIFICATE-----|\s)/g, '');
|
|
69
|
+
const raw = decodeBase64(pem);
|
|
70
|
+
return formatPEM(spkiFromX509(raw), 'PUBLIC KEY');
|
|
71
|
+
}
|
|
72
|
+
export async function importSPKI(spki, alg, options) {
|
|
73
|
+
if (typeof spki !== 'string' || spki.indexOf('-----BEGIN PUBLIC KEY-----') !== 0) {
|
|
74
|
+
throw new TypeError('"spki" must be SPKI formatted string');
|
|
75
|
+
}
|
|
76
|
+
return importPublic(spki, alg, options);
|
|
77
|
+
}
|
|
78
|
+
export async function importX509(x509, alg, options) {
|
|
79
|
+
if (typeof x509 !== 'string' || x509.indexOf('-----BEGIN CERTIFICATE-----') !== 0) {
|
|
80
|
+
throw new TypeError('"x509" must be X.509 formatted string');
|
|
81
|
+
}
|
|
82
|
+
const spki = getSPKI(x509);
|
|
83
|
+
return importPublic(spki, alg, options);
|
|
84
|
+
}
|
|
85
|
+
export async function importPKCS8(pkcs8, alg, options) {
|
|
86
|
+
if (typeof pkcs8 !== 'string' || pkcs8.indexOf('-----BEGIN PRIVATE KEY-----') !== 0) {
|
|
87
|
+
throw new TypeError('"pkcs8" must be PCKS8 formatted string');
|
|
88
|
+
}
|
|
89
|
+
return importPrivate(pkcs8, alg, options);
|
|
90
|
+
}
|
|
91
|
+
export async function importJWK(jwk, alg, octAsKeyObject) {
|
|
92
|
+
if (!isObject(jwk)) {
|
|
93
|
+
throw new TypeError('JWK must be an object');
|
|
94
|
+
}
|
|
95
|
+
alg || (alg = jwk.alg);
|
|
96
|
+
if (typeof alg !== 'string' || !alg) {
|
|
97
|
+
throw new TypeError('"alg" argument is required when "jwk.alg" is not present');
|
|
98
|
+
}
|
|
99
|
+
switch (jwk.kty) {
|
|
100
|
+
case 'oct':
|
|
101
|
+
if (typeof jwk.k !== 'string' || !jwk.k) {
|
|
102
|
+
throw new TypeError('missing "k" (Key Value) Parameter value');
|
|
103
|
+
}
|
|
104
|
+
octAsKeyObject !== null && octAsKeyObject !== void 0 ? octAsKeyObject : (octAsKeyObject = jwk.ext !== true);
|
|
105
|
+
if (octAsKeyObject) {
|
|
106
|
+
return asKeyObject({ ...jwk, alg, ext: false });
|
|
107
|
+
}
|
|
108
|
+
return decodeBase64URL(jwk.k);
|
|
109
|
+
case 'RSA':
|
|
110
|
+
if (jwk.oth !== undefined) {
|
|
111
|
+
throw new JOSENotSupported('RSA JWK "oth" (Other Primes Info) Parameter value is not supported');
|
|
112
|
+
}
|
|
113
|
+
case 'EC':
|
|
114
|
+
case 'OKP':
|
|
115
|
+
return asKeyObject({ ...jwk, alg });
|
|
116
|
+
default:
|
|
117
|
+
throw new JOSENotSupported('Unsupported "kty" (Key Type) Parameter value');
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { JOSENotSupported, JWEInvalid } from '../util/errors.js';
|
|
2
1
|
import { unwrap as aesKw } from '../runtime/aeskw.js';
|
|
3
2
|
import * as ECDH from '../runtime/ecdhes.js';
|
|
4
3
|
import { decrypt as pbes2Kw } from '../runtime/pbes2kw.js';
|
|
5
4
|
import { decrypt as rsaEs } from '../runtime/rsaes.js';
|
|
6
5
|
import { unwrap as aesGcmKw } from '../runtime/aesgcmkw.js';
|
|
7
6
|
import { decode as base64url } from '../runtime/base64url.js';
|
|
7
|
+
import { JOSENotSupported, JWEInvalid } from '../util/errors.js';
|
|
8
8
|
import { bitLengths as cekLengths } from '../lib/cek.js';
|
|
9
|
-
import {
|
|
9
|
+
import { importJWK } from '../key/import.js';
|
|
10
10
|
import checkKeyType from './check_key_type.js';
|
|
11
11
|
function assertEnryptedKey(encryptedKey) {
|
|
12
12
|
if (!encryptedKey) {
|
|
@@ -38,7 +38,7 @@ async function decryptKeyManagement(alg, key, encryptedKey, joseHeader) {
|
|
|
38
38
|
if (!ECDH.ecdhAllowed(key)) {
|
|
39
39
|
throw new JOSENotSupported('ECDH-ES with the provided key is not allowed or not supported by your javascript runtime');
|
|
40
40
|
}
|
|
41
|
-
const epk = await
|
|
41
|
+
const epk = await importJWK(joseHeader.epk, alg);
|
|
42
42
|
let partyUInfo;
|
|
43
43
|
let partyVInfo;
|
|
44
44
|
if (joseHeader.apu !== undefined)
|
|
@@ -88,7 +88,7 @@ async function decryptKeyManagement(alg, key, encryptedKey, joseHeader) {
|
|
|
88
88
|
return aesGcmKw(alg, key, encryptedKey, iv, tag);
|
|
89
89
|
}
|
|
90
90
|
default: {
|
|
91
|
-
throw new JOSENotSupported('
|
|
91
|
+
throw new JOSENotSupported('Invalid or unsupported "alg" (JWE Algorithm) header value');
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import cekFactory, { bitLengths as cekLengths } from '../lib/cek.js';
|
|
2
|
-
import { JOSENotSupported } from '../util/errors.js';
|
|
3
1
|
import random from '../runtime/random.js';
|
|
4
2
|
import { wrap as aesKw } from '../runtime/aeskw.js';
|
|
5
3
|
import * as ECDH from '../runtime/ecdhes.js';
|
|
@@ -7,6 +5,8 @@ import { encrypt as pbes2Kw } from '../runtime/pbes2kw.js';
|
|
|
7
5
|
import { encrypt as rsaEs } from '../runtime/rsaes.js';
|
|
8
6
|
import { wrap as aesGcmKw } from '../runtime/aesgcmkw.js';
|
|
9
7
|
import { encode as base64url } from '../runtime/base64url.js';
|
|
8
|
+
import cekFactory, { bitLengths as cekLengths } from '../lib/cek.js';
|
|
9
|
+
import { JOSENotSupported } from '../util/errors.js';
|
|
10
10
|
import { fromKeyLike } from '../jwk/from_key_like.js';
|
|
11
11
|
import checkKeyType from './check_key_type.js';
|
|
12
12
|
const generateCek = cekFactory(random);
|
|
@@ -79,7 +79,7 @@ async function encryptKeyManagement(alg, enc, key, providedCek, providedParamete
|
|
|
79
79
|
break;
|
|
80
80
|
}
|
|
81
81
|
default: {
|
|
82
|
-
throw new JOSENotSupported('
|
|
82
|
+
throw new JOSENotSupported('Invalid or unsupported "alg" (JWE Algorithm) header value');
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
return { cek, encryptedKey, parameters };
|