unjwt 0.5.39 → 0.6.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 +156 -13
- package/dist/_chunks/_crypto.mjs +1014 -0
- package/dist/_chunks/error.d.mts +67 -0
- package/dist/_chunks/index.d.mts +631 -219
- package/dist/_chunks/jwk.d.mts +220 -87
- package/dist/_chunks/jws.mjs +729 -682
- package/dist/_chunks/utils.mjs +74 -69
- package/dist/adapters/h3v1/index.d.mts +282 -0
- package/dist/{_chunks/h3v1.mjs → adapters/h3v1/index.mjs} +204 -91
- package/dist/adapters/h3v2/index.d.mts +213 -0
- package/dist/adapters/{h3v2.mjs → h3v2/index.mjs} +215 -113
- package/dist/core/_crypto/index.d.mts +71 -0
- package/dist/core/_crypto/index.mjs +2 -0
- package/dist/core/jwe.d.mts +40 -0
- package/dist/{_chunks → core}/jwe.mjs +61 -32
- package/dist/core/jwk.d.mts +231 -0
- package/dist/core/jwk.mjs +686 -0
- package/dist/core/jws.d.mts +31 -0
- package/dist/core/jws.mjs +104 -0
- package/dist/{_chunks/index2.d.mts → core/utils/index.d.mts} +13 -12
- package/dist/core/utils/index.mjs +2 -0
- package/dist/index.d.mts +7 -6
- package/dist/index.mjs +5 -5
- package/package.json +50 -41
- package/dist/_chunks/chunk.mjs +0 -13
- package/dist/_chunks/jwe.d.mts +0 -43
- package/dist/_chunks/jwk.mjs +0 -1592
- package/dist/_chunks/jws.d.mts +0 -46
- package/dist/adapters/h3.d.mts +0 -3
- package/dist/adapters/h3.mjs +0 -3
- package/dist/adapters/h3v1.d.mts +0 -3
- package/dist/adapters/h3v1.mjs +0 -3
- package/dist/adapters/h3v2.d.mts +0 -184
- package/dist/jwe.d.mts +0 -3
- package/dist/jwe.mjs +0 -4
- package/dist/jwk.d.mts +0 -3
- package/dist/jwk.mjs +0 -3
- package/dist/jws.d.mts +0 -3
- package/dist/jws.mjs +0 -4
- package/dist/utils.d.mts +0 -3
- package/dist/utils.mjs +0 -2
|
@@ -1,26 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { D as getPlaintextBytes, E as decodePayloadFromBytes, M as JWTError, N as isJWTError, S as computeJwtTimeClaims, a as base64UrlEncode, b as applyTypCtyDefaults, c as isCryptoKey, d as isJWKSet, g as randomBytes, i as base64UrlDecode, j as validateJwtClaims, k as validateCriticalHeadersJWE, l as isCryptoKeyPair, u as isJWK, v as textEncoder, y as sanitizeObject } from "../_chunks/utils.mjs";
|
|
2
|
+
import { T as generateIV, b as decrypt$1, o as encryptKey, x as encrypt$1 } from "../_chunks/_crypto.mjs";
|
|
3
|
+
import { getJWKsFromSet, importKey, unwrapKey } from "./jwk.mjs";
|
|
4
4
|
//#region src/core/jwe.ts
|
|
5
|
-
var jwe_exports = /* @__PURE__ */ __exportAll({
|
|
6
|
-
decrypt: () => decrypt,
|
|
7
|
-
encrypt: () => encrypt
|
|
8
|
-
});
|
|
9
5
|
async function encrypt(payload, key, options = {}) {
|
|
10
|
-
const { protectedHeader:
|
|
6
|
+
const { protectedHeader: userHeader, cek: providedCek, contentEncryptionIV: providedContentIV, keyManagementIV, p2s, p2c, ecdh } = options;
|
|
11
7
|
let { alg, enc } = options;
|
|
12
8
|
if (!alg) {
|
|
13
9
|
if (typeof key === "string" || key instanceof Uint8Array) alg = "PBES2-HS256+A128KW";
|
|
14
10
|
else if (isJWK(key)) alg = key.alg === "A128GCM" || key.alg === "A192GCM" || key.alg === "A256GCM" ? `${key.alg}KW` : key.alg;
|
|
15
11
|
}
|
|
16
12
|
if (!alg) throw new TypeError("JWE \"alg\" (Key Management Algorithm) must be provided in options or inferable from the key");
|
|
17
|
-
if (!enc)
|
|
13
|
+
if (!enc) if (alg === "dir") {
|
|
14
|
+
enc = isJWK(key) && "enc" in key ? key.enc : void 0;
|
|
15
|
+
if (!enc) throw new TypeError("JWE \"enc\" must be provided when alg is \"dir\"");
|
|
16
|
+
} else enc = isJWK(key) && "enc" in key ? key.enc : "A128GCM";
|
|
18
17
|
const jweKeyManagementParams = {};
|
|
19
18
|
if (keyManagementIV) jweKeyManagementParams.iv = keyManagementIV;
|
|
20
19
|
if (p2s) jweKeyManagementParams.p2s = p2s;
|
|
21
20
|
else if (alg?.startsWith("PBES2")) jweKeyManagementParams.p2s = randomBytes(16);
|
|
22
21
|
if (p2c) jweKeyManagementParams.p2c = p2c;
|
|
23
|
-
else if (alg?.startsWith("PBES2")) jweKeyManagementParams.p2c =
|
|
22
|
+
else if (alg?.startsWith("PBES2")) jweKeyManagementParams.p2c = 6e5;
|
|
24
23
|
if (ecdh?.partyUInfo) jweKeyManagementParams.apu = ecdh.partyUInfo;
|
|
25
24
|
if (ecdh?.partyVInfo) jweKeyManagementParams.apv = ecdh.partyVInfo;
|
|
26
25
|
if (ecdh?.ephemeralKey) {
|
|
@@ -30,21 +29,14 @@ async function encrypt(payload, key, options = {}) {
|
|
|
30
29
|
}
|
|
31
30
|
const wrappingKeyMaterial = await importKey(key, alg);
|
|
32
31
|
const { cek: finalCek, encryptedKey: jweEncryptedKey, parameters: keyManagementHeaderParams } = await encryptKey(alg, enc, wrappingKeyMaterial, providedCek, jweKeyManagementParams);
|
|
33
|
-
const
|
|
34
|
-
...additionalProtectedHeader,
|
|
35
|
-
...keyManagementHeaderParams,
|
|
36
|
-
alg,
|
|
37
|
-
enc
|
|
38
|
-
};
|
|
39
|
-
if (isJWK(key) && key.kid) jweProtectedHeader.kid = key.kid;
|
|
40
|
-
const protectedHeader = applyTypCtyDefaults(jweProtectedHeader, payload);
|
|
32
|
+
const protectedHeader = _buildJWEHeader(alg, enc, key, userHeader, keyManagementHeaderParams, payload);
|
|
41
33
|
const plaintextBytes = getPlaintextBytes(computeJwtTimeClaims(payload, protectedHeader.typ, options.expiresIn, options.currentDate) || payload);
|
|
42
34
|
const protectedHeaderEncoded = base64UrlEncode(JSON.stringify(protectedHeader));
|
|
43
35
|
const aadBytes = textEncoder.encode(protectedHeaderEncoded);
|
|
44
36
|
const contentIVBytes = providedContentIV ?? generateIV(enc);
|
|
45
37
|
const { ciphertext: contentCiphertext, tag: contentAuthTag, iv: actualContentIV } = await encrypt$1(enc, plaintextBytes, finalCek, contentIVBytes, aadBytes);
|
|
46
|
-
if (!actualContentIV) throw new
|
|
47
|
-
if (!contentAuthTag) throw new
|
|
38
|
+
if (!actualContentIV) throw new JWTError("Content encryption IV was not generated or returned.", "ERR_JWE_INVALID");
|
|
39
|
+
if (!contentAuthTag) throw new JWTError("Content encryption auth tag was not generated or returned.", "ERR_JWE_INVALID");
|
|
48
40
|
return [
|
|
49
41
|
protectedHeaderEncoded,
|
|
50
42
|
jweEncryptedKey ? base64UrlEncode(jweEncryptedKey) : "",
|
|
@@ -55,28 +47,28 @@ async function encrypt(payload, key, options = {}) {
|
|
|
55
47
|
}
|
|
56
48
|
async function decrypt(jwe, key, options = {}) {
|
|
57
49
|
const parts = jwe.split(".");
|
|
58
|
-
if (parts.length !== 5) throw new
|
|
50
|
+
if (parts.length !== 5) throw new JWTError("Invalid JWE: Must contain five sections (RFC7516, section-3).", "ERR_JWE_INVALID");
|
|
59
51
|
const [protectedHeaderEncoded, encryptedKeyEncoded, ivEncoded, ciphertextEncoded, authTagEncoded] = parts;
|
|
60
52
|
let protectedHeader;
|
|
61
53
|
try {
|
|
62
54
|
const protectedHeaderJson = base64UrlDecode(protectedHeaderEncoded);
|
|
63
55
|
protectedHeader = sanitizeObject(JSON.parse(protectedHeaderJson));
|
|
64
56
|
} catch {
|
|
65
|
-
throw new
|
|
57
|
+
throw new JWTError("Invalid JWE: Protected header could not be decoded.", "ERR_JWE_INVALID");
|
|
66
58
|
}
|
|
67
|
-
if (!protectedHeader || typeof protectedHeader !== "object" || !protectedHeader.alg || !protectedHeader.enc) throw new
|
|
59
|
+
if (!protectedHeader || typeof protectedHeader !== "object" || !protectedHeader.alg || !protectedHeader.enc) throw new JWTError("Invalid JWE: Protected header must be an object with \"alg\" and \"enc\" properties.", "ERR_JWE_INVALID");
|
|
68
60
|
const alg = protectedHeader.alg;
|
|
69
61
|
const enc = protectedHeader.enc;
|
|
70
|
-
if (options?.algorithms && !options.algorithms.includes(alg)) throw new
|
|
71
|
-
if (options?.encryptionAlgorithms && !options.encryptionAlgorithms.includes(enc)) throw new
|
|
72
|
-
const
|
|
62
|
+
if (options?.algorithms && !options.algorithms.includes(alg)) throw new JWTError(`Key management algorithm not allowed: ${alg}`, "ERR_JWE_ALG_NOT_ALLOWED");
|
|
63
|
+
if (options?.encryptionAlgorithms && !options.encryptionAlgorithms.includes(enc)) throw new JWTError(`Content encryption algorithm not allowed: ${enc}`, "ERR_JWE_ALG_NOT_ALLOWED");
|
|
64
|
+
const rawKeyMaterial = typeof key === "function" ? await key(protectedHeader, jwe) : key;
|
|
73
65
|
const encryptedKeyBytes = base64UrlDecode(encryptedKeyEncoded, false);
|
|
74
66
|
const contentIVBytes = base64UrlDecode(ivEncoded, false);
|
|
75
67
|
const contentAuthTagBytes = base64UrlDecode(authTagEncoded, false);
|
|
76
68
|
const ciphertextBytes = base64UrlDecode(ciphertextEncoded, false);
|
|
77
69
|
const unwrapKeyOpts = {
|
|
78
70
|
enc,
|
|
79
|
-
|
|
71
|
+
format: enc.includes("GCM") ? "cryptokey" : "raw",
|
|
80
72
|
keyUsage: options?.keyUsage || ["decrypt"]
|
|
81
73
|
};
|
|
82
74
|
if (protectedHeader.iv) unwrapKeyOpts.iv = protectedHeader.iv;
|
|
@@ -88,11 +80,34 @@ async function decrypt(jwe, key, options = {}) {
|
|
|
88
80
|
if (protectedHeader.apv) unwrapKeyOpts.apv = protectedHeader.apv;
|
|
89
81
|
if (options?.unwrappedKeyAlgorithm) unwrapKeyOpts.unwrappedKeyAlgorithm = options.unwrappedKeyAlgorithm;
|
|
90
82
|
if (options?.extractable) unwrapKeyOpts.extractable = options.extractable;
|
|
91
|
-
const cek = await unwrapKey(alg, encryptedKeyBytes, unwrappingKey, unwrapKeyOpts);
|
|
92
83
|
const aadBytes = textEncoder.encode(protectedHeaderEncoded);
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if (
|
|
84
|
+
let cek;
|
|
85
|
+
let plaintextBytes;
|
|
86
|
+
if (isJWKSet(rawKeyMaterial)) {
|
|
87
|
+
const candidates = getJWKsFromSet(rawKeyMaterial, _buildJWESetFilter(protectedHeader));
|
|
88
|
+
if (candidates.length === 0) throw new JWTError(`No key found in JWK Set${protectedHeader.kid ? ` with kid "${protectedHeader.kid}"` : ""}.`, "ERR_JWK_KEY_NOT_FOUND");
|
|
89
|
+
let decrypted = false;
|
|
90
|
+
for (const candidate of candidates) try {
|
|
91
|
+
const candidateCek = await unwrapKey(alg, encryptedKeyBytes, await importKey(candidate, alg), unwrapKeyOpts);
|
|
92
|
+
plaintextBytes = await decrypt$1(enc, candidateCek, ciphertextBytes, contentIVBytes, contentAuthTagBytes, aadBytes);
|
|
93
|
+
cek = candidateCek;
|
|
94
|
+
decrypted = true;
|
|
95
|
+
break;
|
|
96
|
+
} catch {}
|
|
97
|
+
if (!decrypted) throw new JWTError("JWE decryption failed.", "ERR_JWE_DECRYPTION_FAILED");
|
|
98
|
+
} else {
|
|
99
|
+
const unwrappingKey = await importKey(rawKeyMaterial, alg);
|
|
100
|
+
try {
|
|
101
|
+
cek = await unwrapKey(alg, encryptedKeyBytes, unwrappingKey, unwrapKeyOpts);
|
|
102
|
+
plaintextBytes = await decrypt$1(enc, cek, ciphertextBytes, contentIVBytes, contentAuthTagBytes, aadBytes);
|
|
103
|
+
} catch (error_) {
|
|
104
|
+
if (error_ instanceof JWTError) throw error_;
|
|
105
|
+
throw new JWTError("JWE decryption failed.", "ERR_JWE_DECRYPTION_FAILED", error_);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const payload = decodePayloadFromBytes(plaintextBytes, protectedHeader, options?.forceUint8Array);
|
|
109
|
+
if (protectedHeader.crit || options?.recognizedHeaders?.length) validateCriticalHeadersJWE(protectedHeader, options?.recognizedHeaders);
|
|
110
|
+
if (payload && typeof payload === "object" && options.validateClaims !== false && (options.validateClaims === true || protectedHeader.typ?.toLowerCase().includes("jwt")) && !options.forceUint8Array && !(payload instanceof Uint8Array)) validateJwtClaims(payload, options);
|
|
96
111
|
const result = {
|
|
97
112
|
payload,
|
|
98
113
|
protectedHeader
|
|
@@ -128,5 +143,19 @@ function parseEphemeralKey(ephemeralKey) {
|
|
|
128
143
|
epkPrivateKey
|
|
129
144
|
};
|
|
130
145
|
}
|
|
146
|
+
function _buildJWESetFilter(header) {
|
|
147
|
+
const { kid, alg } = header;
|
|
148
|
+
return (k) => (!kid || k.kid === kid) && (!k.alg || k.alg === alg);
|
|
149
|
+
}
|
|
150
|
+
function _buildJWEHeader(alg, enc, key, userHeader, keyManagementParams, payload) {
|
|
151
|
+
const safeHeader = sanitizeObject(userHeader);
|
|
152
|
+
return applyTypCtyDefaults({
|
|
153
|
+
...isJWK(key) && key.kid ? { kid: key.kid } : {},
|
|
154
|
+
...safeHeader,
|
|
155
|
+
...keyManagementParams,
|
|
156
|
+
alg,
|
|
157
|
+
enc
|
|
158
|
+
}, payload);
|
|
159
|
+
}
|
|
131
160
|
//#endregion
|
|
132
|
-
export {
|
|
161
|
+
export { JWTError, decrypt, encrypt, isJWTError };
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { $ as JWK_OKP_SIGN, A as JWK, B as JWK_AES_GCM_KW, C as DeriveKeyOptions, D as GenerateKeyAlgorithm, E as GenerateJWKReturn, F as JWKPEMAlgorithm, G as JWK_ECDH_ES, H as JWK_Asymmetric, I as JWKParameters, J as JWK_EC_Public, K as JWK_ECDSA, L as JWKSet, M as JWKCacheAdapter, N as JWKLookupFunction, O as GenerateKeyOptions, P as JWKLookupFunctionHeader, Q as JWK_OKP_Public, R as JWK_AES_CBC_HMAC, S as ContentEncryptionAlgorithm, T as GenerateJWKOptions, U as JWK_Asymmetric_Algorithm, V as JWK_AES_KW, W as JWK_EC, X as JWK_OKP, Y as JWK_HMAC, Z as JWK_OKP_Private, at as JWK_RSA_ENC, b as JoseHeaderParameters, ct as JWK_RSA_Public, dt as JWK_Symmetric_Algorithm, et as JWK_PBES2, ft as JWK_oct, gt as WrapKeyResult, ht as WrapKeyOptions, it as JWK_RSA, j as JWKAlgorithm, k as GenerateKeyReturn, lt as JWK_RSA_SIGN, mt as UnwrapKeyOptions, nt as JWK_Private, ot as JWK_RSA_PSS, pt as KeyManagementAlgorithm, q as JWK_EC_Private, rt as JWK_Public, st as JWK_RSA_Private, tt as JWK_Pair, ut as JWK_Symmetric, w as DeriveKeyReturn, x as CompositeKey, z as JWK_AES_GCM } from "../_chunks/index.mjs";
|
|
2
|
+
import { i as isJWTError, n as JWTErrorCauseMap, r as JWTErrorCode, t as JWTError } from "../_chunks/error.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/core/jwk.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Generates a cryptographic key for the specified algorithm.
|
|
7
|
+
*
|
|
8
|
+
* @param alg The JWA algorithm identifier (e.g., "HS256", "RS256", "A128GCM").
|
|
9
|
+
* @param options Configuration options for key generation.
|
|
10
|
+
* @returns A Promise resolving to the generated key (CryptoKey, CryptoKeyPair, or Uint8Array) or its JWK representation.
|
|
11
|
+
*/
|
|
12
|
+
declare function generateKey<TAlg extends GenerateKeyAlgorithm, TOptions extends GenerateKeyOptions>(alg: TAlg, options?: TOptions): Promise<GenerateKeyReturn<TAlg, TOptions>>;
|
|
13
|
+
/**
|
|
14
|
+
* Generates a Json Web Key (JWK) for the specified algorithm.
|
|
15
|
+
*
|
|
16
|
+
* @param alg The JWA algorithm identifier (e.g., "HS256", "RS256", "A128GCM").
|
|
17
|
+
* @param jwkParams Optional partial JWK to merge with the generated key, allowing overrides.
|
|
18
|
+
* @param options Configuration options for key generation.
|
|
19
|
+
* @returns A Promise resolving to the generated JWK or JWK pair representation.
|
|
20
|
+
*/
|
|
21
|
+
declare function generateJWK<TAlg extends GenerateKeyAlgorithm>(alg: TAlg, jwkParams?: Omit<JWKParameters, "alg" | "kty" | "key_ops" | "ext">, options?: GenerateJWKOptions): Promise<GenerateJWKReturn<TAlg>>;
|
|
22
|
+
/**
|
|
23
|
+
* Derives a key from a password using PBKDF2 as specified by PBES2 algorithms.
|
|
24
|
+
*
|
|
25
|
+
* @param password The password to derive the key from (string or Uint8Array).
|
|
26
|
+
* @param alg The PBES2 algorithm identifier (e.g., "PBES2-HS256+A128KW").
|
|
27
|
+
* @param options Configuration options including salt and iterations.
|
|
28
|
+
* @returns A Promise resolving to the derived key (CryptoKey) or its JWK_oct representation.
|
|
29
|
+
*/
|
|
30
|
+
declare function deriveKeyFromPassword<TAlg extends JWK_PBES2, TOptions extends DeriveKeyOptions>(password: string | Uint8Array<ArrayBuffer>, alg: TAlg, options: TOptions): Promise<DeriveKeyReturn<TOptions>>;
|
|
31
|
+
/**
|
|
32
|
+
* Derives a Json Web Key (JWK) from a password using PBKDF2 as specified by PBES2 algorithms.
|
|
33
|
+
*
|
|
34
|
+
* @param password The password to derive the key from (string or Uint8Array).
|
|
35
|
+
* @param alg The PBES2 algorithm identifier (e.g., "PBES2-HS256+A128KW").
|
|
36
|
+
* @param jwkParams Optional partial JWK to merge with the generated key, allowing overrides.
|
|
37
|
+
* @param options Configuration options including salt and iterations.
|
|
38
|
+
* @returns A Promise resolving to the derived JWK (JWK_oct).
|
|
39
|
+
*/
|
|
40
|
+
declare function deriveJWKFromPassword(password: string | Uint8Array<ArrayBuffer>, alg: JWK_PBES2, options: Omit<DeriveKeyOptions, "toJWK">, jwkParams?: Omit<JWKParameters, "alg" | "kty" | "key_ops" | "ext">): Promise<JWK_oct>;
|
|
41
|
+
/**
|
|
42
|
+
* Default JWK import cache backed by a WeakMap.
|
|
43
|
+
*
|
|
44
|
+
* The outer WeakMap is keyed by the JWK object reference — a cache hit only
|
|
45
|
+
* occurs when the exact same object variable is passed to {@link importKey}.
|
|
46
|
+
* Reconstructing a structurally identical JWK (e.g. `{ ...jwk }`) will miss
|
|
47
|
+
* the cache.
|
|
48
|
+
*
|
|
49
|
+
* The inner `Record<string, CryptoKey>` uses a plain object rather than `Map`
|
|
50
|
+
* because typical entries have 1–2 algorithm strings per key. V8 applies
|
|
51
|
+
* hidden-class optimisation to small plain objects, making property access
|
|
52
|
+
* faster than `Map.get()` at this cardinality.
|
|
53
|
+
*/
|
|
54
|
+
declare class WeakMapJWKCache implements JWKCacheAdapter {
|
|
55
|
+
private readonly _map;
|
|
56
|
+
get(jwk: JWK, alg: string): CryptoKey | undefined;
|
|
57
|
+
set(jwk: JWK, alg: string, key: CryptoKey): void;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Replace or disable the JWK import cache used by {@link importKey}.
|
|
61
|
+
*
|
|
62
|
+
* Pass a custom {@link JWKCacheAdapter} to use your own cache strategy
|
|
63
|
+
* (LRU, Redis-backed wrapper, test spy, etc.). Pass `false` to disable
|
|
64
|
+
* caching entirely.
|
|
65
|
+
*
|
|
66
|
+
* @example Disable caching:
|
|
67
|
+
* ```ts
|
|
68
|
+
* configureJWKCache(false);
|
|
69
|
+
* ```
|
|
70
|
+
* @example Use a custom kid-keyed cache:
|
|
71
|
+
* ```ts
|
|
72
|
+
* const map = new Map<string, CryptoKey>();
|
|
73
|
+
* configureJWKCache({
|
|
74
|
+
* get: (jwk, alg) => map.get(`${jwk.kid}:${alg}`),
|
|
75
|
+
* set: (jwk, alg, key) => map.set(`${jwk.kid}:${alg}`, key),
|
|
76
|
+
* });
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
declare function configureJWKCache(cache: JWKCacheAdapter | false): void;
|
|
80
|
+
/**
|
|
81
|
+
* Reset the JWK import cache to a fresh {@link WeakMapJWKCache}.
|
|
82
|
+
* Useful in test environments to clear all cached CryptoKey references
|
|
83
|
+
* between test runs without disabling the cache entirely.
|
|
84
|
+
*/
|
|
85
|
+
declare function clearJWKCache(): void;
|
|
86
|
+
/**
|
|
87
|
+
* Imports a key from various formats (CryptoKey, JWK, Uint8Array).
|
|
88
|
+
*
|
|
89
|
+
* - If `key` is a CryptoKey, it's returned directly.
|
|
90
|
+
* - If `key` is a Uint8Array, it's returned directly.
|
|
91
|
+
* - If `key` is a JWK_oct (symmetric key with 'k'), the raw key bytes are returned as Uint8Array.
|
|
92
|
+
* - If `key` is any other JWK type (asymmetric), the `alg` parameter is required, and a CryptoKey is returned.
|
|
93
|
+
*
|
|
94
|
+
* @param key The key to import.
|
|
95
|
+
* @param alg The algorithm hint, required when importing asymmetric JWKs.
|
|
96
|
+
* @returns A Promise resolving to the imported key as CryptoKey or Uint8Array.
|
|
97
|
+
*/
|
|
98
|
+
declare function importKey(key: string): Promise<Uint8Array<ArrayBuffer>>;
|
|
99
|
+
declare function importKey(key: Uint8Array<ArrayBuffer>): Promise<Uint8Array<ArrayBuffer>>;
|
|
100
|
+
declare function importKey(key: CryptoKey): Promise<CryptoKey>;
|
|
101
|
+
declare function importKey(key: JWK_oct): Promise<Uint8Array<ArrayBuffer>>;
|
|
102
|
+
declare function importKey(key: JWK_oct, options: {
|
|
103
|
+
asCryptoKey: true; /** Algorithm to import the key as (e.g. `{ name: "AES-GCM", length: 256 }`). */
|
|
104
|
+
algorithm: Parameters<typeof crypto.subtle.importKey>[2]; /** Key usages for the resulting CryptoKey. */
|
|
105
|
+
usage: KeyUsage[]; /** Mark the key as extractable. Defaults to `false`. */
|
|
106
|
+
extractable?: boolean;
|
|
107
|
+
}): Promise<CryptoKey>;
|
|
108
|
+
declare function importKey(key: CryptoKey | JWK | Uint8Array<ArrayBuffer> | string, alg?: string): Promise<CryptoKey | Uint8Array<ArrayBuffer>>;
|
|
109
|
+
/**
|
|
110
|
+
* Exports a CryptoKey to a JWK (JSON Web Key) format.
|
|
111
|
+
*
|
|
112
|
+
* @param key The CryptoKey to export.
|
|
113
|
+
* @param jwk Optional partial JWK to merge with the exported key, allowing overrides.
|
|
114
|
+
* @returns A Promise resolving to the exported JWK.
|
|
115
|
+
*/
|
|
116
|
+
declare function exportKey<T extends JWK>(key: CryptoKey, jwk?: Partial<JWK>): Promise<T>;
|
|
117
|
+
/**
|
|
118
|
+
* Wraps a Content Encryption Key (CEK) using the specified algorithm and wrapping key.
|
|
119
|
+
*
|
|
120
|
+
* @param alg The JWA key management algorithm (e.g., "A128KW", "RSA-OAEP", "PBES2-HS256+A128KW").
|
|
121
|
+
* @param keyToWrap The key to be wrapped (CEK), typically a symmetric key as Uint8Array or CryptoKey.
|
|
122
|
+
* @param wrappingKey The key used to wrap the CEK (CryptoKey, JWK, or password string/Uint8Array for PBES2).
|
|
123
|
+
* @param options Additional options required by certain algorithms (e.g., p2s, p2c for PBES2).
|
|
124
|
+
* @returns A Promise resolving to an object containing the wrapped key and any necessary parameters (iv, tag, epk, etc.).
|
|
125
|
+
*/
|
|
126
|
+
declare function wrapKey(alg: KeyManagementAlgorithm, keyToWrap: CryptoKey | Uint8Array<ArrayBuffer>, wrappingKey: CryptoKey | JWK | string | Uint8Array<ArrayBuffer>, options?: WrapKeyOptions): Promise<WrapKeyResult>;
|
|
127
|
+
/**
|
|
128
|
+
* Unwraps a Content Encryption Key (CEK) using the specified algorithm and unwrapping key.
|
|
129
|
+
*
|
|
130
|
+
* @param alg The JWA key management algorithm (e.g., "A128KW", "RSA-OAEP", "PBES2-HS256+A128KW").
|
|
131
|
+
* @param wrappedKey The wrapped key (ciphertext) as Uint8Array.
|
|
132
|
+
* @param unwrappingKey The key used to unwrap the CEK (CryptoKey, JWK, or password string/Uint8Array for PBES2).
|
|
133
|
+
* @param options Additional options required by certain algorithms (e.g., iv, tag, p2s, p2c, epk).
|
|
134
|
+
* @returns A Promise resolving to the unwrapped key (CEK) as a CryptoKey or Uint8Array.
|
|
135
|
+
*/
|
|
136
|
+
declare function unwrapKey(alg: KeyManagementAlgorithm, wrappedKey: Uint8Array<ArrayBuffer>, unwrappingKey: CryptoKey | JWK | string | Uint8Array<ArrayBuffer>, options: UnwrapKeyOptions & {
|
|
137
|
+
format: "raw";
|
|
138
|
+
}): Promise<Uint8Array<ArrayBuffer>>;
|
|
139
|
+
declare function unwrapKey(alg: KeyManagementAlgorithm, wrappedKey: Uint8Array<ArrayBuffer>, unwrappingKey: CryptoKey | JWK | string | Uint8Array<ArrayBuffer>, options?: UnwrapKeyOptions & {
|
|
140
|
+
format?: "cryptokey";
|
|
141
|
+
}): Promise<CryptoKey>;
|
|
142
|
+
declare function unwrapKey(alg: KeyManagementAlgorithm, wrappedKey: Uint8Array<ArrayBuffer>, unwrappingKey: CryptoKey | JWK | string | Uint8Array<ArrayBuffer>, options: UnwrapKeyOptions): Promise<CryptoKey | Uint8Array<ArrayBuffer>>;
|
|
143
|
+
/**
|
|
144
|
+
* Imports a key from a PEM-encoded string and converts it to a JWK.
|
|
145
|
+
*
|
|
146
|
+
* @param pem The PEM-encoded string.
|
|
147
|
+
* @param pemType The type of PEM encoding ('pkcs8' for private keys, 'spki' for public keys, 'x509' for certificates).
|
|
148
|
+
* @param alg The JWA algorithm identifier. This is crucial for `crypto.subtle.importKey`
|
|
149
|
+
* to understand the key's intended algorithm and for setting the 'alg' field in the resulting JWK.
|
|
150
|
+
* @param importOptions Options for the PEM import process (e.g., extractable for the CryptoKey).
|
|
151
|
+
* @param jwkExtras Additional properties to merge into the resulting JWK.
|
|
152
|
+
* @returns A Promise resolving to the imported key as a JWK.
|
|
153
|
+
*/
|
|
154
|
+
declare function importFromPEM<T extends JWK>(pem: string, pemType: "pkcs8" | "spki" | "x509", alg: JWKPEMAlgorithm, options?: {
|
|
155
|
+
/** Passed to `crypto.subtle.importKey`. Defaults to `false` for private keys, `true` otherwise. */extractable?: boolean; /** Additional JWK properties merged into the exported key (e.g. `kid`). */
|
|
156
|
+
jwkParams?: Omit<JWKParameters, "alg" | "kty" | "key_ops" | "ext">;
|
|
157
|
+
}): Promise<T>;
|
|
158
|
+
/**
|
|
159
|
+
* Exports a JWK to a PEM-encoded string.
|
|
160
|
+
*
|
|
161
|
+
* @param jwk The JWK to export.
|
|
162
|
+
* @param pemFormat The desired PEM format ('pkcs8' for private keys, 'spki' for public keys).
|
|
163
|
+
* @param algForCryptoKeyImport If the JWK does not have an 'alg' property, this algorithm hint is
|
|
164
|
+
* required to correctly convert it to a CryptoKey first.
|
|
165
|
+
* @returns A Promise resolving to the PEM-encoded key string.
|
|
166
|
+
*/
|
|
167
|
+
declare function exportToPEM(jwk: JWK, pemFormat: "pkcs8" | "spki", algForCryptoKeyImport?: JWKPEMAlgorithm): Promise<string>;
|
|
168
|
+
/**
|
|
169
|
+
* Derives a shared secret using ECDH-ES key agreement (RFC 7518 §4.6).
|
|
170
|
+
*
|
|
171
|
+
* Performs an Elliptic Curve Diffie-Hellman Ephemeral-Static key derivation
|
|
172
|
+
* followed by a Concat KDF (NIST SP 800-56A) to produce key material of the
|
|
173
|
+
* requested length. The result can be used directly as a CEK (for `ECDH-ES`
|
|
174
|
+
* direct key agreement) or as a KEK to wrap a separately generated CEK (for
|
|
175
|
+
* `ECDH-ES+A*KW`).
|
|
176
|
+
*
|
|
177
|
+
* For multi-recipient JWE, call this once per recipient with their public key
|
|
178
|
+
* and a fresh ephemeral private key, then wrap the shared CEK with the derived
|
|
179
|
+
* material using {@link wrapKey}.
|
|
180
|
+
*
|
|
181
|
+
* @param publicKey The recipient's static public key (or the sender's
|
|
182
|
+
* ephemeral public key on the decryption side).
|
|
183
|
+
* @param privateKey The sender's ephemeral private key (or the recipient's
|
|
184
|
+
* static private key on the decryption side).
|
|
185
|
+
* @param alg The algorithm identifier used as the `AlgorithmID` in the
|
|
186
|
+
* concat KDF info structure. Pass a {@link JWK_ECDH_ES} variant
|
|
187
|
+
* (e.g. `"ECDH-ES+A128KW"`) or a {@link ContentEncryptionAlgorithm}
|
|
188
|
+
* (e.g. `"A256GCM"`) for direct key agreement.
|
|
189
|
+
* @param options Optional overrides for key length and party info.
|
|
190
|
+
*/
|
|
191
|
+
declare function deriveSharedSecret(publicKey: CryptoKey | JWK_EC_Public, privateKey: CryptoKey | JWK_EC_Private, alg: JWK_ECDH_ES | ContentEncryptionAlgorithm, options?: {
|
|
192
|
+
/** Override the derived key length in bits. Defaults to the standard length for `alg`. */keyLength?: number; /** Agreement PartyUInfo (apu). */
|
|
193
|
+
partyUInfo?: Uint8Array<ArrayBuffer>; /** Agreement PartyVInfo (apv). */
|
|
194
|
+
partyVInfo?: Uint8Array<ArrayBuffer>;
|
|
195
|
+
}): Promise<Uint8Array<ArrayBuffer>>;
|
|
196
|
+
/**
|
|
197
|
+
* @deprecated For set queries, use {@link getJWKsFromSet} which returns all
|
|
198
|
+
* matching keys as an array. This function remains available for internal
|
|
199
|
+
* single-key resolution by `kid` or JOSE header (used by `verify` and `decrypt`).
|
|
200
|
+
*
|
|
201
|
+
* Retrieves a JWK (JSON Web Key) from a JWKSet based on a key ID (kid) or
|
|
202
|
+
* properties from a JOSE Header.
|
|
203
|
+
*
|
|
204
|
+
* @param jwkSet The JWKSet to search within.
|
|
205
|
+
* @param kidOrProtectedHeader Either a string representing the 'kid' (Key ID)
|
|
206
|
+
* or an object representing the JOSE Protected Header. If an object is
|
|
207
|
+
* provided, it must contain a 'kid' property. It can optionally contain
|
|
208
|
+
* 'alg' (Algorithm) and 'kty' (Key Type) to further refine the search.
|
|
209
|
+
* @returns The matching JWK from the set.
|
|
210
|
+
* @throws TypeError if `jwkSet` is invalid or `kidOrProtectedHeader` is not a
|
|
211
|
+
* string or a valid header object.
|
|
212
|
+
* @throws Error if no key is found matching the provided criteria, or if the
|
|
213
|
+
* header object is missing the 'kid' property.
|
|
214
|
+
*/
|
|
215
|
+
declare function getJWKFromSet(jwkSet: JWKSet, kidOrProtectedHeader: string | (JoseHeaderParameters & {
|
|
216
|
+
alg?: string;
|
|
217
|
+
kty?: string;
|
|
218
|
+
})): JWK;
|
|
219
|
+
/**
|
|
220
|
+
* Returns all JWKs from a JWK Set, optionally narrowed by a predicate.
|
|
221
|
+
*
|
|
222
|
+
* Useful for multi-key verification retry, key rotation tooling, and
|
|
223
|
+
* constructing multi-recipient JWE JSON Serialization structures.
|
|
224
|
+
*
|
|
225
|
+
* @param jwkSet The JWK Set to search.
|
|
226
|
+
* @param filter Optional predicate `(jwk: JWK) => boolean`. Returns all keys when omitted.
|
|
227
|
+
* @returns An array of matching JWKs.
|
|
228
|
+
*/
|
|
229
|
+
declare function getJWKsFromSet(jwkSet: JWKSet, filter?: (jwk: JWK) => boolean): JWK[];
|
|
230
|
+
//#endregion
|
|
231
|
+
export { CompositeKey, ContentEncryptionAlgorithm, DeriveKeyOptions, DeriveKeyReturn, GenerateJWKOptions, GenerateJWKReturn, GenerateKeyAlgorithm, GenerateKeyOptions, GenerateKeyReturn, JWK, JWKAlgorithm, JWKCacheAdapter, JWKLookupFunction, JWKLookupFunctionHeader, JWKPEMAlgorithm, JWKParameters, JWKSet, JWK_AES_CBC_HMAC, JWK_AES_GCM, JWK_AES_GCM_KW, JWK_AES_KW, JWK_Asymmetric, JWK_Asymmetric_Algorithm, JWK_EC, JWK_ECDH_ES, JWK_ECDSA, JWK_EC_Private, JWK_EC_Public, JWK_HMAC, JWK_OKP, JWK_OKP_Private, JWK_OKP_Public, JWK_OKP_SIGN, JWK_PBES2, JWK_Pair, JWK_Private, JWK_Public, JWK_RSA, JWK_RSA_ENC, JWK_RSA_PSS, JWK_RSA_Private, JWK_RSA_Public, JWK_RSA_SIGN, JWK_Symmetric, JWK_Symmetric_Algorithm, JWK_oct, JWTError, type JWTErrorCauseMap, type JWTErrorCode, KeyManagementAlgorithm, UnwrapKeyOptions, WeakMapJWKCache, WrapKeyOptions, WrapKeyResult, clearJWKCache, configureJWKCache, deriveJWKFromPassword, deriveKeyFromPassword, deriveSharedSecret, exportKey, exportToPEM, generateJWK, generateKey, getJWKFromSet, getJWKsFromSet, importFromPEM, importKey, isJWTError, unwrapKey, wrapKey };
|