Compare Versions - jose
⚠ BREAKING CHANGES
- The PEMImportOptions type interface is renamed to KeyImportOptions.
- all builds and bundles now use ES2022 as target
- createRemoteJWKSet now uses fetch, because of that its Node.js only options.agent property has been removed and new fetch-related options were added
- drop support for Ed448 and X448
- drop support for JWK key_ops and CryptoKey usages "(un)wrapKey" and "deriveKey"
- resolved keys returned as part of verify/decrypt operations (when get key functions are used) are always normalized to either Uint8Array / CryptoKey depending on what's more efficient for the executed operation
- Key "Type" Generics are removed
- CJS-style require is now only possible when require(esm) support is present in the Node.js runtime
- private KeyObject instances can no longer be used for verify operations
- private KeyObject instances can no longer be used for encryption operations
- generateSecret, generateKeyPair, importPKCS8, importSPKI, importJWK, and importX509 now yield a CryptoKey instead of a KeyObject in Node.js
- drop support for Node.js 18.x and earlier
- runtime-specific npm releases (jose-browser-runtime, jose-node-cjs-runtime, and jose-node-esm-runtime) are no longer maintained or supported
- removed secp256k1 JWS support
- removed deprecated experimental APIs
- removed RSA1_5 JWE support
Features
- enable CryptoKey and KeyObject inputs in JWK thumbprint functions (6fc9c44)
- JSON Web Key is now an allowed input everywhere (ebda967)
Refactor
- always use infered CryptoKey (c4abaa2)
- backport the Ed25519 JWS Algorithm Identifier support (7a94cb9)
- drop support for Ed448 and X448 (2fae1c4)
- drop support for JWK key_ops and CryptoKey usages "(un)wrapKey" and "deriveKey" (ef918be)
- ensure export functions continue to work with KeyObject inputs (28e9e68)
- hardcode the cryptoRuntime export since it is now always WebCryptoAPI (e00f273)
- JWK import extractable default for public keys is now true (64dcebe)
- PEM import extractable default for public keys is now true (4e9f114)
- removed deprecated APIs (5352083)
- removed secp256k1 JWS support (e2b58a5)
- restructure src/lib and src/runtime now that runtime is fixed (9b236ce)
- target is now ES2022 everywhere (aa590d5)
- update importJWK args to align with other import functions (355a2dd)
- WebCryptoAPI is now the only crypto used (161de46)
Features
- allow JWK objects as "key" input to sign and verify (c6302ea)
This method of passing private or public keys does not yield the same performance as passing a CryptoKey or KeyObject instances, its main purpose is for convenience or for when you're not going to be re-using the same set of keys for the operation, in which case you should use one of the import key methods to obtain a CryptoKey or KeyObject.
Example Signing
const alg = "RS256";
const jwk = {
kty: "RSA",
n: "whYOFK2Ocbbpb_zVypi9SeKiNUqKQH0zTKN1-6fpCTu6ZalGI82s7XK3tan4dJt90ptUPKD2zvxqTzFNfx4HHHsrYCf2-FMLn1VTJfQazA2BvJqAwcpW1bqRUEty8tS_Yv4hRvWfQPcc2Gc3-_fQOOW57zVy-rNoJc744kb30NjQxdGp03J2S3GLQu7oKtSDDPooQHD38PEMNnITf0pj-KgDPjymkMGoJlO3aKppsjfbt_AH6GGdRghYRLOUwQU-h-ofWHR3lbYiKtXPn5dN24kiHy61e3VAQ9_YAZlwXC_99GGtw_NpghFAuM4P1JDn0DppJldy3PGFC0GfBCZASw",
e: "AQAB",
d: "VuVE_KEP6323WjpbBdAIv7HGahGrgGANvbxZsIhm34lsVOPK0XDegZkhAybMZHjRhp-gwVxX5ChC-J3cUpOBH5FNxElgW6HizD2Jcq6t6LoLYgPSrfEHm71iHg8JsgrqfUnGYFzMJmv88C6WdCtpgG_qJV1K00_Ly1G1QKoBffEs-v4fAMJrCbUdCz1qWto-PU-HLMEo-krfEpGgcmtZeRlDADh8cETMQlgQfQX2VWq_aAP4a1SXmo-j0cvRU4W5Fj0RVwNesIpetX2ZFz4p_JmB5sWFEj_fC7h5z2lq-6Bme2T3BHtXkIxoBW0_pYVnASC8P2puO5FnVxDmWuHDYQ",
p: "07rgXd_tLUhVRF_g1OaqRZh5uZ8hiLWUSU0vu9coOaQcatSqjQlIwLW8UdKv_38GrmpIfgcEVQjzq6rFBowUm9zWBO9Eq6enpasYJBOeD8EMeDK-nsST57HjPVOCvoVC5ZX-cozPXna3iRNZ1TVYBY3smn0IaxysIK-zxESf4pM",
q: "6qrE9TPhCS5iNR7QrKThunLu6t4H_8CkYRPLbvOIt2MgZyPLiZCsvdkTVSOX76QQEXt7Y0nTNua69q3K3Jhf-YOkPSJsWTxgrfOnjoDvRKzbW3OExIMm7D99fVBODuNWinjYgUwGSqGAsb_3TKhtI-Gr5ls3fn6B6oEjVL0dpmk",
dp: "mHqjrFdgelT2OyiFRS3dAAPf3cLxJoAGC4gP0UoQyPocEP-Y17sQ7t-ygIanguubBy65iDFLeGXa_g0cmSt2iAzRAHrDzI8P1-pQl2KdWSEg9ssspjBRh_F_AiJLLSPRWn_b3-jySkhawtfxwO8Kte1QsK1My765Y0zFvJnjPws",
dq: "KmjaV4YcsVAUp4z-IXVa5htHWmLuByaFjpXJOjABEUN0467wZdgjn9vPRp-8Ia8AyGgMkJES_uUL_PDDrMJM9gb4c6P4-NeUkVtreLGMjFjA-_IQmIMrUZ7XywHsWXx0c2oLlrJqoKo3W-hZhR0bPFTYgDUT_mRWjk7wV6wl46E",
qi: "iYltkV_4PmQDfZfGFpzn2UtYEKyhy-9t3Vy8Mw2VHLAADKGwJvVK5ficQAr2atIF1-agXY2bd6KV-w52zR8rmZfTr0gobzYIyqHczOm13t7uXJv2WygY7QEC2OGjdxa2Fr9RnvS99ozMa5nomZBqTqT7z5QV33czjPRCjvg6FcE",
};
const jwt = await new jose.SignJWT({ "urn:example:claim": true })
.setProtectedHeader({ alg })
.setIssuedAt()
.setIssuer("urn:example:issuer")
.setAudience("urn:example:audience")
.setExpirationTime("2h")
.sign(jwk);
console.log(jwt);
Example Verification
const alg = "RS256";
const jwk = {
kty: "RSA",
n: "whYOFK2Ocbbpb_zVypi9SeKiNUqKQH0zTKN1-6fpCTu6ZalGI82s7XK3tan4dJt90ptUPKD2zvxqTzFNfx4HHHsrYCf2-FMLn1VTJfQazA2BvJqAwcpW1bqRUEty8tS_Yv4hRvWfQPcc2Gc3-_fQOOW57zVy-rNoJc744kb30NjQxdGp03J2S3GLQu7oKtSDDPooQHD38PEMNnITf0pj-KgDPjymkMGoJlO3aKppsjfbt_AH6GGdRghYRLOUwQU-h-ofWHR3lbYiKtXPn5dN24kiHy61e3VAQ9_YAZlwXC_99GGtw_NpghFAuM4P1JDn0DppJldy3PGFC0GfBCZASw",
e: "AQAB",
};
const jwt =
"eyJhbGciOiJSUzI1NiJ9.eyJ1cm46ZXhhbXBsZTpjbGFpbSI6dHJ1ZSwiaWF0IjoxNjY5MDU2NDg4LCJpc3MiOiJ1cm46ZXhhbXBsZTppc3N1ZXIiLCJhdWQiOiJ1cm46ZXhhbXBsZTphdWRpZW5jZSJ9.gXrPZ3yM_60dMXGE69dusbpzYASNA-XIOwsb5D5xYnSxyj6_D6OR_uR_1vqhUm4AxZxcrH1_-XJAve9HCw8az_QzHcN-nETt-v6stCsYrn6Bv1YOc-mSJRZ8ll57KVqLbCIbjKwerNX5r2_Qg2TwmJzQdRs-AQDhy-s_DlJd8ql6wR4n-kDZpar-pwIvz4fFIN0Fj57SXpAbLrV6Eo4Byzl0xFD8qEYEpBwjrMMfxCZXTlAVhAq6KCoGlDTwWuExps342-0UErEtyIqDnDGcrfNWiUsoo8j-29IpKd-w9-C388u-ChCxoHz--H8WmMSZzx3zTXsZ5lXLZ9IKfanDKg";
const { payload, protectedHeader } = await jose.jwtVerify(jwt, jwk, {
issuer: "urn:example:issuer",
audience: "urn:example:audience",
});
console.log(protectedHeader);
console.log(payload);
⚠ BREAKING CHANGES
- Node.js: return Uint8Array (not a Buffer) from base64url.decode
- Browser distribution is now built using ES2020 as a target
- Node.js distribution is now built using ES2022 as a target
- types: jwtVerify and jwtDecrypt type argument for the resolved KeyLike type is now a second optional type argument following a type for the JWT Claims Set (aka payload)
- PBES2 Key Management Algorithms' use in decrypt functions now requires the use of the keyManagementAlgorithms option to explicitly opt-in for their use.
- importJWK "octAsKeyObject" option was removed. importJWK will no longer return CryptoKey or KeyObject for "oct" (octet sequence) JWK key types, it will instead always return a Uint8Array formed from the "k" (Key Value) Parameter regardless of the other JWK Parameters that may be present.
- End-Of-Life versions of Node.js as of October 2023 are no longer supported. Node.js 18, 20, 21, and future releases are the ones that remain supported.
- The JWE "zip" (Compression Algorithm) Header Parameter is no longer supported by this JOSE implementation.
Features
- add Date as valid input to timestamp setting functions (bd830a4)
- default to an empty payload in JWT producing constructors (98d6ca1)
- types: add optional Generics for JWT verify and decrypt (61bd2a0), closes #568
Reverts
- Revert "test: fix test under lts/erbium" (b64b6c7)
Refactor
- Browser distribution is now built using ES2020 as a target (1836684)
- drop support for EOL Node.js versions (b5aee54)
- importJWK always returns a Uint8Array for symmetric key inputs (163e1b0)
- Node.js distribution is now built using ES2022 as a target (239697a)
- Node.js: return Uint8Array (not a Buffer) from base64url.decode (02d5182)
- PBES2 Algorithms require explicit opt-in during verification (e2da031)
- remove support for JWE "zip" (Compression Algorithm) Header Parameter (16998b1)
- types: rename type parameters for the KeyLike returns (eddd400)
- update allow list error messages (fe8114c)
Fixes
- add a maxOutputLength option to zlib inflate (1b91d88), fixes CVE-2024-28176
This release contains only Node.js CITGM related test updates.
This release is to start using provenance statements.
This release contains only minor code refactoring, documentation, and IntelliSense updates.
Features
- enable key iteration over JWKSMultipleMatchingKeys (a278acd)
const JWKS = jose.createRemoteJWKSet(new URL('https://www.googleapis.com/oauth2/v3/certs'))
const options = {
issuer: 'urn:example:issuer',
audience: 'urn:example:audience',
}
const { payload, protectedHeader } = await jose
.jwtVerify(jwt, JWKS, options)
.catch(async (error) => {
if (error?.code === 'ERR_JWKS_MULTIPLE_MATCHING_KEYS') {
for await (const publicKey of error) {
try {
return await jose.jwtVerify(jwt, publicKey, options)
} catch (innerError) {
if (innerError?.code === 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED') {
continue
}
throw innerError
}
}
throw new jose.errors.JWSSignatureVerificationFailed()
}
throw error
})
console.log(protectedHeader)
console.log(payload)
This release contains only code refactoring, documentation updates, and Node.js CITGM related test updates.
v4.10.1, v4.10.2, and v4.10.3 contain only code refactoring, documentation updates, and updates necessary to include jose in the Node.js CITGM builds.
Features
- Curve25519, and Curve448 support for WebCryptoAPI runtimes based on Secure Curves in the Web Cryptography API (fea359a)
Fixes
This release contains only code refactoring and documentation updates.
This release contains only code refactoring and documentation updates.
This release contains only code refactoring and documentation updates.
Fixes
- typescript: apply updated compact and jwt headers to compact/jwt verify and decrypt results (0c1946c)
Features
- General JWE Encryption (94eca81)
example Usage
import * as jose from "jose";
const firstRecipientKeyPair = await jose.generateKeyPair("RSA-OAEP-256");
const secondRecipientKeyPair = await jose.generateKeyPair("ECDH-ES+A256KW");
const thirdRecipientSecret = await jose.generateSecret("A256GCMKW");
const encoder = new TextEncoder();
const plaintext = encoder.encode(
"It’s a dangerous business, Frodo, going out your door."
);
const additionalAuthenticatedData = encoder.encode(
"The Fellowship of the Ring"
);
const enc = new jose.GeneralEncrypt(plaintext)
.setAdditionalAuthenticatedData(additionalAuthenticatedData)
.setProtectedHeader({ enc: "A256GCM" });
enc
.addRecipient(firstRecipientKeyPair.publicKey)
.setUnprotectedHeader({ alg: "RSA-OAEP-256" });
enc
.addRecipient(secondRecipientKeyPair.publicKey)
.setUnprotectedHeader({ alg: "ECDH-ES+A256KW" });
enc
.addRecipient(thirdRecipientSecret)
.setUnprotectedHeader({ alg: "A256GCMKW" });
const jwe = await enc.encrypt();
console.log(JSON.stringify(jwe, null, 4));
for (const recipientKey of [
firstRecipientKeyPair.privateKey,
secondRecipientKeyPair.privateKey,
thirdRecipientSecret,
]) {
await jose.generalDecrypt(jwe, recipientKey);
}
⚠ BREAKING CHANGES
- All module named exports have moved from subpaths to just "jose". For example,
import { jwtVerify } from 'jose/jwt/verify'is now justimport { jwtVerify } from 'jose'. - All submodule default exports and named have been removed in favour of just "jose" named exports.
- typescript: remove repeated type re-exports
- The undocumented
jose/util/randomwas removed. - The
jose/jwk/thumbprintnamed export is renamed tocalculateJwkThumbprint, nowimport { calculateJwkThumbprint } from 'jose' - The deprecated
jose/jwk/parsemodule was removed, useimport { importJWK } from 'jose'instead. - The deprecated
jose/jwk/from_key_likemodule was removed, useimport { exportJWK } from 'jose'instead.
Migration Guide
Migrating from v3.x to v4.x is very straight forward.
- All
importstatements,require(), orimport()invocations should be changed to use just'jose'as the target. - There are no more default exports. Everything was converted to a named export.
- Refer to the documentation if you're not sure how a given module should be imported / required.
- any custom resolvers targeting
josedist files for jest, typescript, or other tooling should be removed
// before (v3.x)
import { jwtVerify } from 'jose/jwt/verify'
import { SignJWT } from 'jose/jwt/sign'
import * as errors from 'jose/util/errors'
// after (v4.x)
import { jwtVerify, SignJWT, errors } from 'jose'
Bug Fixes
- typescript: PEM import functions always resolve a KeyLike, never a Uint8Array (8ef3a8e)
Bug Fixes
- defer AES CBC w/ HMAC decryption after tag verification passes (579485c), fixes CVE-2021-29443, CVE-2021-29444 , CVE-2021-29445, and CVE-2021-29446
⚠ BREAKING CHANGES
- Revised, Promise-based API
- No dependencies
- Browser support (using Web Cryptography API)
- Support for verification using a remote JWKS endpoint
- Experimental Node.js libuv thread pool based runtime (non-blocking 🎉)
Features
- Revised API, No dependencies, Browser Support, Promises (357fe0b)
Fixes
- add a maxOutputLength option to zlib inflate (02a6579), fixes CVE-2024-28176
Bug Fixes
- defer AES CBC w/ HMAC decryption after tag verification passes (812e03f), fixes CVE-2021-29443
⚠ BREAKING CHANGES
- the
JWE.decryptoptionalgorithmswas removed and replaced with contentEncryptionAlgorithms (handlesencallowlist) and keyManagementAlgorithms (handlesalgallowlist) - the
JWT.verifyprofile option was removed, use e.g.JWT.IdToken.verifyinstead. - removed the
maxAuthAgeJWT.verifyoption, this option is now only present at the specific JWT profile APIs where theauth_timeproperty applies. - removed the
nonceJWT.verifyoption, this option is now only present at the specific JWT profile APIs where thenonceproperty applies. - the
acr,amr,nonceandazpclaim value types will only be checked when verifying a specific JWT profile using its dedicated API. - using the draft implementing APIs will emit a one-time warning per process using
process.emitWarning JWT.signfunction options no longer accept anonceproperty. To create a JWT with anoncejust pass the value to the payload.- due to added ESM module support Node.js version with ESM implementation bugs are no longer supported, this only affects early v13.x versions. The resulting Node.js semver range is
>=10.13.0 < 13 || >=13.7.0 - deprecated method
JWK.importKeywas removed - deprecated method
JWKS.KeyStore.fromJWKSwas removed - the use of unregistered curve name P-256K for secp256k1 was removed
- jose.JWE.Encrypt constructor aad and unprotectedHeader arguments swapped places
- jose.JWE.encrypt.flattened header (unprotectedHeader) and aad arguments swapped places
- jose.JWE.encrypt.general header (unprotectedHeader) and aad arguments swapped places
- JWS.verify returned payloads are now always buffers
- JWS.verify options
encodingandparsewere removed
Features
- added support for ESM (ECMAScript modules) (1aa9035)
- decrypt allowlists for both key management and content encryption (30e5c46)
Bug Fixes
- typescript: allow Buffer when verifying detached signature (cadbd04)
- typescript: properly type all decode/verify/decrypt fn options (4c23bd6)
Refactor
Bug Fixes
- defer AES CBC w/ HMAC decryption after tag verification passes (08e1bc5), fixes CVE-2021-29443
Features
- update JWT Profile for OAuth 2.0 Access Tokens to latest draft (8c0a8a9)
BREAKING CHANGES
at+JWTJWT draft profile - in the draft's Section 2.2 the claimsiatandjtiare now REQUIRED (was RECOMMENDED).
Draft specification profiles are updated as minor versions of the library, therefore, since they may have breaking changes, use the ~ semver operator when using these and pay close attention to changelog and the drafts themselves.
Features
- two official jose plugins/extensions for those living on the edge, closes #56
https://github.com/panva/jose-chacha https://github.com/panva/jose-x25519-ecdh
See the docs of each if you need them.
Package was renamed from @panva/jose to just jose. No further updates will be made under the @panva/jose package name.
- rename package (26f4cf2)