unjwt 0.5.40 → 0.6.1

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 (40) hide show
  1. package/README.md +147 -6
  2. package/dist/_chunks/_crypto.mjs +1014 -0
  3. package/dist/_chunks/error.d.mts +67 -0
  4. package/dist/_chunks/index.d.mts +149 -45
  5. package/dist/_chunks/jwk.d.mts +154 -57
  6. package/dist/_chunks/jws.mjs +729 -683
  7. package/dist/_chunks/utils.mjs +74 -70
  8. package/dist/{_chunks/jws.d.mts → adapters/h3v1/index.d.mts} +98 -58
  9. package/dist/{_chunks/jws2.mjs → adapters/h3v1/index.mjs} +198 -85
  10. package/dist/adapters/h3v2/index.d.mts +213 -0
  11. package/dist/adapters/{h3v2.mjs → h3v2/index.mjs} +195 -89
  12. package/dist/core/_crypto/index.d.mts +71 -0
  13. package/dist/core/_crypto/index.mjs +2 -0
  14. package/dist/core/jwe.d.mts +40 -0
  15. package/dist/{_chunks → core}/jwe.mjs +61 -32
  16. package/dist/core/jwk.d.mts +231 -0
  17. package/dist/core/jwk.mjs +686 -0
  18. package/dist/core/jws.d.mts +31 -0
  19. package/dist/core/jws.mjs +104 -0
  20. package/dist/{_chunks/index2.d.mts → core/utils/index.d.mts} +13 -12
  21. package/dist/core/utils/index.mjs +2 -0
  22. package/dist/index.d.mts +7 -6
  23. package/dist/index.mjs +5 -5
  24. package/package.json +48 -40
  25. package/dist/_chunks/chunk.mjs +0 -13
  26. package/dist/_chunks/jwe.d.mts +0 -43
  27. package/dist/_chunks/jwk.mjs +0 -1592
  28. package/dist/adapters/h3.d.mts +0 -3
  29. package/dist/adapters/h3.mjs +0 -3
  30. package/dist/adapters/h3v1.d.mts +0 -3
  31. package/dist/adapters/h3v1.mjs +0 -3
  32. package/dist/adapters/h3v2.d.mts +0 -183
  33. package/dist/jwe.d.mts +0 -3
  34. package/dist/jwe.mjs +0 -2
  35. package/dist/jwk.d.mts +0 -3
  36. package/dist/jwk.mjs +0 -2
  37. package/dist/jws.d.mts +0 -3
  38. package/dist/jws.mjs +0 -2
  39. package/dist/utils.d.mts +0 -3
  40. package/dist/utils.mjs +0 -2
@@ -0,0 +1,71 @@
1
+ import { A as JWK, o as JWEHeaderParameters, s as JWEKeyManagementHeaderParameters } from "../../_chunks/index.mjs";
2
+
3
+ //#region src/core/_crypto/_sign-verify.d.ts
4
+ declare function sign(alg: string, key: CryptoKey, data: Uint8Array<ArrayBuffer>): Promise<Uint8Array<ArrayBuffer>>;
5
+ declare function verify(alg: string, key: CryptoKey, signature: Uint8Array<ArrayBuffer>, data: Uint8Array<ArrayBuffer>): Promise<boolean>;
6
+ //#endregion
7
+ //#region src/core/_crypto/_aes.d.ts
8
+ declare function generateIV(alg: string): Uint8Array<ArrayBuffer>;
9
+ declare function bitLengthCEK(alg: string): number;
10
+ declare function generateCEK(alg: string): Uint8Array<ArrayBuffer>;
11
+ declare function aesKwWrap(alg: string, key: CryptoKey | Uint8Array<ArrayBuffer>, cek: Uint8Array<ArrayBuffer>): Promise<Uint8Array<ArrayBuffer>>;
12
+ declare function aesKwUnwrap(alg: string, key: CryptoKey | Uint8Array<ArrayBuffer>, encryptedKey: Uint8Array<ArrayBuffer>): Promise<Uint8Array<ArrayBuffer>>;
13
+ declare function gcmkwEncrypt(alg: string, key: CryptoKey | Uint8Array<ArrayBuffer>, plaintext: Uint8Array<ArrayBuffer>, iv?: Uint8Array<ArrayBuffer>): Promise<{
14
+ encryptedKey: Uint8Array<ArrayBuffer>;
15
+ iv: string;
16
+ tag: string;
17
+ }>;
18
+ declare function gcmkwDecrypt(alg: string, key: CryptoKey | Uint8Array<ArrayBuffer>, ciphertext: Uint8Array<ArrayBuffer>, iv: Uint8Array<ArrayBuffer>, tag: Uint8Array<ArrayBuffer>): Promise<Uint8Array<ArrayBuffer>>;
19
+ declare function encrypt(enc: string, plaintext: Uint8Array<ArrayBuffer>, cek: Uint8Array<ArrayBuffer> | CryptoKey, iv: Uint8Array<ArrayBuffer> | undefined, aad: Uint8Array<ArrayBuffer>): Promise<{
20
+ ciphertext: Uint8Array<ArrayBuffer>;
21
+ tag: Uint8Array<ArrayBuffer> | undefined;
22
+ iv: Uint8Array<ArrayBuffer> | undefined;
23
+ }>;
24
+ declare function decrypt(enc: string, cek: Uint8Array<ArrayBuffer> | CryptoKey, ciphertext: Uint8Array<ArrayBuffer>, iv: Uint8Array<ArrayBuffer> | undefined, tag: Uint8Array<ArrayBuffer> | undefined, aad: Uint8Array<ArrayBuffer>): Promise<Uint8Array<ArrayBuffer>>;
25
+ //#endregion
26
+ //#region src/core/_crypto/_key-encryption.d.ts
27
+ declare function encryptKey(alg: string, enc: string, key: CryptoKey | Uint8Array<ArrayBuffer>, providedCek?: Uint8Array<ArrayBuffer>, providedParameters?: JWEKeyManagementHeaderParameters): Promise<{
28
+ cek: CryptoKey | Uint8Array<ArrayBuffer>;
29
+ encryptedKey?: Uint8Array<ArrayBuffer>;
30
+ parameters?: JWEHeaderParameters;
31
+ }>;
32
+ declare function normalizeKey(key: CryptoKey | JWK | Uint8Array<ArrayBuffer>, alg: string): Promise<CryptoKey | Uint8Array<ArrayBuffer>>;
33
+ //#endregion
34
+ //#region src/core/_crypto/_key-codec.d.ts
35
+ declare function jwkTokey(jwk: JWK): Promise<CryptoKey>;
36
+ declare function keyToJWK<T extends JWK>(key: Uint8Array<ArrayBuffer> | CryptoKey): Promise<T>;
37
+ //#endregion
38
+ //#region src/core/_crypto/_pbes2.d.ts
39
+ declare function pbes2Wrap(alg: string, key: CryptoKey | Uint8Array<ArrayBuffer>, cek: Uint8Array<ArrayBuffer>, p2c: number, p2s: Uint8Array<ArrayBuffer>): Promise<{
40
+ encryptedKey: Uint8Array<ArrayBuffer>;
41
+ p2c: number;
42
+ p2s: string;
43
+ }>;
44
+ declare function pbes2Unwrap(alg: string, key: CryptoKey | Uint8Array<ArrayBuffer>, encryptedKey: Uint8Array<ArrayBuffer>, p2c: number, p2s: Uint8Array<ArrayBuffer>): Promise<Uint8Array<ArrayBuffer>>;
45
+ declare function deriveKey(p2s: Uint8Array<ArrayBuffer>, alg: string, p2c: number, key: CryptoKey | Uint8Array<ArrayBuffer>): Promise<Uint8Array<ArrayBuffer>>;
46
+ //#endregion
47
+ //#region src/core/_crypto/_ecdh.d.ts
48
+ declare function deriveECDHESKey(publicKey: CryptoKey, privateKey: CryptoKey, algorithm: string, keyLength: number, apu?: Uint8Array<ArrayBuffer>, apv?: Uint8Array<ArrayBuffer>): Promise<Uint8Array<ArrayBuffer>>;
49
+ declare function isECDHKeyAllowed(key: CryptoKey): boolean;
50
+ //#endregion
51
+ //#region src/core/_crypto/_rsa.d.ts
52
+ declare function encryptRSAES(alg: string, key: CryptoKey, cek: Uint8Array<ArrayBuffer>): Promise<Uint8Array<ArrayBuffer>>;
53
+ declare function decryptRSAES(alg: string, key: CryptoKey, encryptedKey: Uint8Array<ArrayBuffer>): Promise<Uint8Array<ArrayBuffer>>;
54
+ //#endregion
55
+ //#region src/core/_crypto/_pem.d.ts
56
+ /** Key Import Function options. */
57
+ interface KeyImportOptions {
58
+ /**
59
+ * The value to use as {@link !SubtleCrypto.importKey} `extractable` argument. Default is false for
60
+ * private keys, true otherwise.
61
+ */
62
+ extractable?: boolean;
63
+ }
64
+ declare const toSPKI: (key: unknown) => Promise<string>;
65
+ declare const toPKCS8: (key: unknown) => Promise<string>;
66
+ declare const fromPKCS8: PEMImportFunction;
67
+ declare const fromSPKI: PEMImportFunction;
68
+ declare const fromX509: PEMImportFunction;
69
+ type PEMImportFunction = (pem: string, alg: string, options?: KeyImportOptions) => Promise<CryptoKey>;
70
+ //#endregion
71
+ export { type KeyImportOptions, aesKwUnwrap, aesKwWrap, bitLengthCEK, decrypt, decryptRSAES, deriveECDHESKey, deriveKey as deriveKeyPBES2, encrypt, encryptKey, encryptRSAES, fromPKCS8, fromSPKI, fromX509, gcmkwDecrypt, gcmkwEncrypt, generateCEK, generateIV, isECDHKeyAllowed, jwkTokey, keyToJWK, normalizeKey, pbes2Unwrap, pbes2Wrap, sign, toPKCS8, toSPKI, verify };
@@ -0,0 +1,2 @@
1
+ import { C as gcmkwEncrypt, D as verify, E as sign, S as gcmkwDecrypt, T as generateIV, _ as aesKwUnwrap, a as toSPKI, b as decrypt, c as deriveKey, d as deriveECDHESKey, f as isECDHKeyAllowed, g as keyToJWK, h as jwkTokey, i as toPKCS8, l as pbes2Unwrap, m as encryptRSAES, n as fromSPKI, o as encryptKey, p as decryptRSAES, r as fromX509, s as normalizeKey, t as fromPKCS8, u as pbes2Wrap, v as aesKwWrap, w as generateCEK, x as encrypt, y as bitLengthCEK } from "../../_chunks/_crypto.mjs";
2
+ export { aesKwUnwrap, aesKwWrap, bitLengthCEK, decrypt, decryptRSAES, deriveECDHESKey, deriveKey as deriveKeyPBES2, encrypt, encryptKey, encryptRSAES, fromPKCS8, fromSPKI, fromX509, gcmkwDecrypt, gcmkwEncrypt, generateCEK, generateIV, isECDHKeyAllowed, jwkTokey, keyToJWK, normalizeKey, pbes2Unwrap, pbes2Wrap, sign, toPKCS8, toSPKI, verify };
@@ -0,0 +1,40 @@
1
+ import { A as JWK, L as JWKSet, N as JWKLookupFunction, S as ContentEncryptionAlgorithm, a as JWEEncryptOptions, c as JWEProtectedHeader, g as JOSEPayload, i as JWEDecryptResult, nt as JWK_Private, o as JWEHeaderParameters, pt as KeyManagementAlgorithm, r as JWEDecryptOptions, s as JWEKeyManagementHeaderParameters, ut as JWK_Symmetric } 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/jwe.d.ts
5
+ /**
6
+ * Encrypts a payload to produce a JWE Compact Serialization string.
7
+ *
8
+ * @param payload The payload to encrypt. Can be a string, Uint8Array, or a JSON-serializable object.
9
+ * @param key The key encryption key (KEK). Can be a CryptoKey, JWK, or for PBES2, a password string/Uint8Array.
10
+ * @param options JWE encryption options, including `alg` (key management algorithm) and `enc` (content encryption algorithm).
11
+ * @returns A Promise resolving to the JWE Compact Serialization string.
12
+ */
13
+ declare function encrypt(payload: JOSEPayload, key: JWK | string | Uint8Array<ArrayBuffer>, options?: JWEEncryptOptions): Promise<string>;
14
+ declare function encrypt(payload: JOSEPayload, key: CryptoKey | JWK_Symmetric | Uint8Array<ArrayBuffer>, options: JWEEncryptOptions & {
15
+ alg: "dir";
16
+ enc: ContentEncryptionAlgorithm;
17
+ }): Promise<string>;
18
+ declare function encrypt(payload: JOSEPayload, key: CryptoKey, options: JWEEncryptOptions & {
19
+ alg: KeyManagementAlgorithm;
20
+ enc: ContentEncryptionAlgorithm;
21
+ }): Promise<string>;
22
+ declare function encrypt(payload: JOSEPayload, key: CryptoKey | JWK | string | Uint8Array<ArrayBuffer>, options: JWEEncryptOptions & {
23
+ alg: KeyManagementAlgorithm;
24
+ enc: ContentEncryptionAlgorithm;
25
+ }): Promise<string>;
26
+ /**
27
+ * Decrypts a JWE Compact Serialization string.
28
+ *
29
+ * @param jwe The JWE Compact Serialization string.
30
+ * @param key The key decryption key (KEK) or a function to look up the key.
31
+ * @param options JWE decryption options.
32
+ * @returns A Promise resolving to an object containing the decrypted plaintext, protected header, CEK, and AAD.
33
+ * @throws If JWE is invalid, decryption fails, or options are not met.
34
+ */
35
+ declare function decrypt<T extends JOSEPayload>(jwe: string, key: CryptoKey | JWKSet | JWK_Private | JWK_Symmetric | string | Uint8Array<ArrayBuffer> | JWKLookupFunction, options?: JWEDecryptOptions): Promise<JWEDecryptResult<T>>;
36
+ declare function decrypt(jwe: string, key: CryptoKey | JWKSet | JWK_Private | JWK_Symmetric | string | Uint8Array<ArrayBuffer> | JWKLookupFunction, options: JWEDecryptOptions & {
37
+ forceUint8Array: true;
38
+ }): Promise<JWEDecryptResult<Uint8Array<ArrayBuffer>>>;
39
+ //#endregion
40
+ export { JWEDecryptOptions, JWEDecryptResult, JWEEncryptOptions, JWEHeaderParameters, JWEKeyManagementHeaderParameters, JWEProtectedHeader, JWTError, type JWTErrorCauseMap, type JWTErrorCode, decrypt, encrypt, isJWTError };
@@ -1,26 +1,25 @@
1
- import { t as __exportAll } from "./chunk.mjs";
2
- import { A as validateCriticalHeadersJWE, C as computeJwtTimeClaims, D as decodePayloadFromBytes, M as validateJwtClaims, O as getPlaintextBytes, a as base64UrlEncode, b as sanitizeObject, c as isCryptoKey, g as randomBytes, i as base64UrlDecode, l as isCryptoKeyPair, u as isJWK, v as textEncoder, x as applyTypCtyDefaults } from "./utils.mjs";
3
- import { d as unwrapKey, g as generateIV, h as encrypt$1, l as importKey, m as decrypt$1, p as encryptKey } from "./jwk.mjs";
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: additionalProtectedHeader, cek: providedCek, contentEncryptionIV: providedContentIV, keyManagementIV, p2s, p2c, ecdh } = options;
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) enc = isJWK(key) && "enc" in key ? key.enc : "A128GCM";
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 = 2048;
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 jweProtectedHeader = {
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 Error("Content encryption IV was not generated or returned.");
47
- if (!contentAuthTag) throw new Error("Content encryption auth tag was not generated or returned.");
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 Error("Invalid JWE: Must contain five sections (RFC7516, section-3).");
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 Error("Invalid JWE: Protected header could not be decoded.");
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 Error("Invalid JWE: Protected header must be an object with \"alg\" and \"enc\" properties.");
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 Error(`Key management algorithm not allowed: ${alg}`);
71
- if (options?.encryptionAlgorithms && !options.encryptionAlgorithms.includes(enc)) throw new Error(`Content encryption algorithm not allowed: ${enc}`);
72
- const unwrappingKey = await importKey(typeof key === "function" ? await key(protectedHeader, jwe) : key, alg);
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
- returnAs: enc.includes("GCM"),
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
- const payload = decodePayloadFromBytes(await decrypt$1(enc, cek, ciphertextBytes, contentIVBytes, contentAuthTagBytes, aadBytes), protectedHeader, options?.forceUint8Array);
94
- if (protectedHeader.crit || options?.critical?.length || options?.requiredHeaders?.length) validateCriticalHeadersJWE(protectedHeader, [...options?.critical || [], ...options?.requiredHeaders || []]);
95
- if (payload && typeof payload === "object" && options.validateJWT !== false && (options.validateJWT === true || protectedHeader.typ?.toLowerCase().includes("jwt")) && !options.forceUint8Array && !(payload instanceof Uint8Array)) validateJwtClaims(payload, options);
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 { encrypt as n, jwe_exports as r, decrypt as t };
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 };