1 | # jose
|
2 |
|
3 | > "JSON Web Almost Everything" - JWA, JWS, JWE, JWT, JWK, JWKS for Node.js with minimal dependencies
|
4 |
|
5 | <p align="center"><img src="/img/demo.gif?raw=true"/></p>
|
6 |
|
7 | ## Implemented specs & features
|
8 |
|
9 | The following specifications are implemented by `jose`
|
10 |
|
11 | - JSON Web Signature (JWS) - [RFC7515][spec-jws]
|
12 | - JSON Web Encryption (JWE) - [RFC7516][spec-jwe]
|
13 | - JSON Web Key (JWK) - [RFC7517][spec-jwk]
|
14 | - JSON Web Algorithms (JWA) - [RFC7518][spec-jwa]
|
15 | - JSON Web Token (JWT) - [RFC7519][spec-jwt]
|
16 | - JSON Web Key Thumbprint - [RFC7638][spec-thumbprint]
|
17 | - JWS Unencoded Payload Option - [RFC7797][spec-b64]
|
18 | - CFRG Elliptic Curve ECDH and Signatures - [RFC8037][spec-okp]
|
19 | - secp256k1 EC Key curve support - [JOSE Registrations for WebAuthn Algorithms][draft-secp256k1]
|
20 |
|
21 | The test suite utilizes examples defined in [RFC7520][spec-cookbook] to confirm its JOSE
|
22 | implementation is correct.
|
23 |
|
24 | Available JWT validation profiles
|
25 |
|
26 | - Generic JWT
|
27 | - OIDC ID Token (`id_token`) - [OpenID Connect Core 1.0][spec-oidc-id_token]
|
28 | - OAuth 2.0 JWT Access Tokens (`at+JWT`) - [JWT Profile for OAuth 2.0 Access Tokens][draft-ietf-oauth-access-token-jwt]
|
29 | - OIDC Logout Token (`logout_token`) - [OpenID Connect Back-Channel Logout 1.0][spec-oidc-logout_token]
|
30 |
|
31 | <br>
|
32 |
|
33 | Have a question about using `jose`? - [ask][ask].
|
34 | Found a bug? - [report it][bug].
|
35 | Missing a feature? - If it wasn't already discussed before, [ask for it][suggest-feature].
|
36 | Found a vulnerability? - Reach out to us via email first, see [security vulnerability disclosure][security-vulnerability].
|
37 |
|
38 | ## Sponsor
|
39 |
|
40 | [<img width="65" height="65" align="left" src="https://avatars.githubusercontent.com/u/2824157?s=75&v=4" alt="auth0-logo">][sponsor-auth0] If you want to quickly add secure token-based authentication to Node.js projects, feel free to check Auth0’s free plan at [auth0.com/overview][sponsor-auth0].<br><br>
|
41 |
|
42 | ## Support
|
43 |
|
44 | 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.
|
45 |
|
46 | ## Documentation
|
47 |
|
48 | - [jose API Documentation][documentation]
|
49 | - [JWK (JSON Web Key)][documentation-jwk]
|
50 | - [JWKS (JSON Web Key Set)][documentation-jwks]
|
51 | - [JWT (JSON Web Token)][documentation-jwt]
|
52 | - [JWS (JSON Web Signature)][documentation-jws]
|
53 | - [JWE (JSON Web Encryption)][documentation-jwe]
|
54 |
|
55 | ## Usage
|
56 |
|
57 | For the best performance Node.js version **>=12.0.0** is recommended, but **^10.13.0** lts/dubnium
|
58 | is also supported.
|
59 |
|
60 | Installing `jose`
|
61 |
|
62 | ```console
|
63 | npm install jose
|
64 | ```
|
65 |
|
66 | Usage
|
67 | ```js
|
68 | const jose = require('jose')
|
69 | const {
|
70 | JWE, // JSON Web Encryption (JWE)
|
71 | JWK, // JSON Web Key (JWK)
|
72 | JWKS, // JSON Web Key Set (JWKS)
|
73 | JWS, // JSON Web Signature (JWS)
|
74 | JWT, // JSON Web Token (JWT)
|
75 | errors // errors utilized by jose
|
76 | } = jose
|
77 | ```
|
78 |
|
79 | #### Keys and KeyStores
|
80 |
|
81 | Prepare your Keys and KeyStores. See the [documentation][documentation-jwk] for more.
|
82 |
|
83 | ```js
|
84 | const key = jose.JWK.asKey(fs.readFileSync('path/to/key/file'))
|
85 |
|
86 | const jwk = { kty: 'EC',
|
87 | kid: 'dl4M_fcI7XoFCsQ22PYrQBkuxZ2pDcbDimcdFmmXM98',
|
88 | crv: 'P-256',
|
89 | x: 'v37avifcL-xgh8cy6IFzcINqqmFLc2JF20XUpn4Y2uQ',
|
90 | y: 'QTwy27XgP7ZMOdGOSopAHB-FU1JMQn3J9GEWGtUXreQ' }
|
91 | const anotherKey = jose.JWK.asKey(jwk)
|
92 |
|
93 | const keystore = new jose.JWKS.KeyStore(key, anotherKey)
|
94 | ```
|
95 |
|
96 | ### JWT vs JWS
|
97 |
|
98 | The JWT module provides IANA registered claim type and format validations on top of JWS as well as
|
99 | convenience options for verifying UNIX timestamps, setting maximum allowed JWT age, verifying
|
100 | audiences, and more.
|
101 |
|
102 | The JWS module on the other hand handles the other JWS Serialization Syntaxes with all their
|
103 | additional available features and allows signing of any payload, i.e. not just serialized JSON
|
104 | objects.
|
105 |
|
106 | #### JWT Signing
|
107 |
|
108 | Sign with a private or symmetric key with plethora of convenience options. See the
|
109 | [documentation][documentation-jwt] for more.
|
110 |
|
111 | ```js
|
112 | jose.JWT.sign(
|
113 | { 'urn:example:claim': 'foo' },
|
114 | privateKey,
|
115 | {
|
116 | algorithm: 'PS256',
|
117 | audience: 'urn:example:client_id',
|
118 | expiresIn: '1 hour',
|
119 | header: {
|
120 | typ: 'JWT'
|
121 | },
|
122 | issuer: 'https://op.example.com'
|
123 | }
|
124 | )
|
125 | ```
|
126 |
|
127 | #### JWT Verifying
|
128 |
|
129 | Verify with a public or symmetric key with plethora of convenience options. See the
|
130 | [documentation][documentation-jwt] for more.
|
131 |
|
132 | ```js
|
133 | jose.JWT.verify(
|
134 | 'eyJ0eXAiOiJKV1QiLCJhbGciOiJQUzI1NiIsImtpZCI6IjRQQXBsVkJIN0toS1ZqN0xob0RFM0VVQnNGc0hvaTRhSmxBZGstM3JuME0ifQ.eyJ1cm46ZXhhbXBsZTpjbGFpbSI6ImZvbyIsImF1ZCI6InVybjpleGFtcGxlOmNsaWVudF9pZCIsImlzcyI6Imh0dHBzOi8vb3AuZXhhbXBsZS5jb20iLCJpYXQiOjE1NTEyOTI2MjksImV4cCI6MTU1MTI5NjIyOX0.nE5fgRL8gvlStf_wB4mJ0TSXVmhJRnUVQuZ0ts6a1nWnnk0Rv69bEJ12BoMdpyPrGa_W6dxU4HFj89F4pQwW0kqBK2-TZ_n9lq-iqupj46w_lpKOfPC3clVc7ZmqYF81bEA-nX93cSKqVV-qPNPEFenb8XHKszYhBFu_uiRg9rXj2qXVU7PXGJAGTzhVgVxB-3XDB1bQ_6KiDCwzVPftrHxEYLydRCaHzggDg6sAFUhQqhPguKuE2gs6jVUh_gIL2RXeoLoinx6gZ72rfovaOmud-yzNIUN8Tvo0pqBmx0s_lEhTlfrQCzN7hZNmV1eG0GDDE-S_CfZhPePnVJZoRA',
|
135 | publicKey,
|
136 | {
|
137 | issuer: 'https://op.example.com',
|
138 | audience: 'urn:example:client_id',
|
139 | algorithms: ['PS256']
|
140 | }
|
141 | )
|
142 | ```
|
143 |
|
144 | <details>
|
145 | <summary><em><strong>Verifying OIDC ID Tokens</strong></em> (Click to expand)</summary><br>
|
146 |
|
147 | #### ID Token Verifying
|
148 |
|
149 | ID Token is a JWT, but profiled, there are additional requirements to a JWT to be accepted as an
|
150 | ID Token and it is pretty easy to omit some, use the `profile` option of `JWT.verify` or the
|
151 | `JWT.IdToken.verify` shorthand to make sure what you're accepting is really an ID Token meant to
|
152 | your Client. This will then perform all doable validations given the input. See the
|
153 | [documentation][documentation-jwt] for more.
|
154 |
|
155 | ```js
|
156 | jose.JWT.IdToken.verify(
|
157 | 'eyJhbGciOiJQUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6InIxTGtiQm8zOTI1UmIyWkZGckt5VTNNVmV4OVQyODE3S3gwdmJpNmlfS2MifQ.eyJzdWIiOiJmb28iLCJub25jZSI6ImE1MWNjZjA4ZjRiYmIwNmU4ODcxNWRkYzRiYmI0MWQ4IiwiYXVkIjoidXJuOmV4YW1wbGU6Y2xpZW50X2lkIiwiZXhwIjoxNTYzODg4ODMwLCJpYXQiOjE1NjM4ODUyMzAsImlzcyI6Imh0dHBzOi8vb3AuZXhhbXBsZS5jb20ifQ.RKCZczgICF5G9XdNDSwe4dolGauQHptpFKPzahA2wYGG2HKrKhyC8ZzqpeVc8cbntuqFBgABJVv6_9YICRx_dgwPYydTpZfZYjHnxrdWF9QsIPEGs672mrnhqIXUnXoseZ0TF6GOq6P7Qbf6gk1ru7TAbr_ieyJnNWcJhh5iHpz1k3mFz0TyTh7UNXshtQXftPUipqz4OBni5r9UaZXHw8B3QYOnms8__GJ3owOxaqkr1jgRs_EWqMlBNjPaj7ElVaeBWljDKuoK673tH0heSpgzUmUX_W8IDUVqs33uglpZwAQC7cAA5mGEg2odcRpvpP5M-WaP4RE9dl9jzcYmrw',
|
158 | keyOrStore,
|
159 | {
|
160 | issuer: 'https://op.example.com',
|
161 | audience: 'urn:example:client_id',
|
162 | nonce: 'a51ccf08f4bbb06e88715ddc4bbb41d8',
|
163 | algorithms: ['PS256']
|
164 | }
|
165 | )
|
166 | ```
|
167 |
|
168 | Note: Depending on the channel you receive an ID Token from the following claims may be required
|
169 | and must also be checked: `at_hash`, `c_hash` or `s_hash`. Use e.g. [`oidc-token-hash`][oidc-token-hash]
|
170 | to validate those hashes after getting the ID Token payload and signature validated by `jose`
|
171 |
|
172 | </details>
|
173 |
|
174 | <details>
|
175 | <summary><em><strong>Verifying OAuth 2.0 JWT Access Tokens</strong></em> (Click to expand)</summary><br>
|
176 |
|
177 | #### JWT Access Token Verifying
|
178 |
|
179 | When accepting a JWT-formatted OAuth 2.0 Access Token there are additional requirements for the JWT
|
180 | to be accepted as an Access Token according to the [specification][draft-ietf-oauth-access-token-jwt]
|
181 | and it is pretty easy to omit some. Use the `profile` option of `JWT.verify` or the
|
182 | `JWT.AccessToken.verify` shorthand to make sure what you're accepting is really a JWT Access Token
|
183 | meant for your Resource Server. This will then perform all doable validations given the input. See
|
184 | the [documentation][documentation-jwt] for more.
|
185 |
|
186 | ```js
|
187 | jose.JWT.AccessToken.verify(
|
188 | 'eyJhbGciOiJQUzI1NiIsInR5cCI6ImF0K0pXVCIsImtpZCI6InIxTGtiQm8zOTI1UmIyWkZGckt5VTNNVmV4OVQyODE3S3gwdmJpNmlfS2MifQ.eyJzdWIiOiJmb28iLCJjbGllbnRfaWQiOiJ1cm46ZXhhbXBsZTpjbGllbnRfaWQiLCJhdWQiOiJ1cm46ZXhhbXBsZTpyZXNvdXJjZS1zZXJ2ZXIiLCJleHAiOjE1NjM4ODg4MzAsImlzcyI6Imh0dHBzOi8vb3AuZXhhbXBsZS5jb20iLCJzY29wZSI6ImFwaTpyZWFkIn0.UYy8vEGWS0cS24giCYobMMy9-bqI45p807yV1l-2WXX2J4UO-eohV_R58LE2oM88gl414c6XydO6QSYXul5roNPoOs41jpEvreQIP-HmegjbWGutktWJKfvoOblE5FjYwjrwStjLQGUzkq6KWcnDLPGmpFy7n6gZ4LF8YVz4dLEaO335hMNVNrmSPSXYqr7bAWybnLVpLxjDYwNfCO1g0_TlFx8fHh2OftHoOOmJFltFwb8JypkSB-JXVVSEh43IOEjeeMJIG_ylWIOxfLLi5Q7vPWgub83ZTkuGNe4KmlQJKIsH5k0yZSshsLYUOOH0RiXqQ-SA4Ubh3Fowigdu-g',
|
189 | keyOrStore,
|
190 | {
|
191 | issuer: 'https://op.example.com',
|
192 | audience: 'urn:example:resource-server',
|
193 | algorithms: ['PS256']
|
194 | }
|
195 | )
|
196 | ```
|
197 |
|
198 | </details>
|
199 |
|
200 | <details>
|
201 | <summary><em><strong>Verifying OIDC Logout Token</strong></em> (Click to expand)</summary><br>
|
202 |
|
203 | #### Logout Token Verifying
|
204 |
|
205 | Logout Token is a JWT, but profiled, there are additional requirements to a JWT to be accepted as an
|
206 | Logout Token and it is pretty easy to omit some, use the `profile` option of `JWT.verify` or the
|
207 | `JWT.LogoutToken.verify` to make sure what you're accepting is really an Logout Token meant to your
|
208 | Client. This will then perform all doable validations given the input. See the
|
209 | [documentation][documentation-jwt] for more.
|
210 |
|
211 | ```js
|
212 | jose.JWT.LogoutToken.verify(
|
213 | 'eyJhbGciOiJQUzI1NiJ9.eyJzdWIiOiJmb28iLCJhdWQiOiJ1cm46ZXhhbXBsZTpjbGllbnRfaWQiLCJpYXQiOjE1NjM4ODg4MzAsImp0aSI6ImhqazMyN2RzYSIsImlzcyI6Imh0dHBzOi8vb3AuZXhhbXBsZS5jb20iLCJldmVudHMiOnsiaHR0cDovL3NjaGVtYXMub3BlbmlkLm5ldC9ldmVudC9iYWNrY2hhbm5lbC1sb2dvdXQiOnt9fX0.SBi7uNUvjHL9TFoFzautGgTQ1MjyeGUNYHL7inpgq3XgTv6xc9EAKuPRtpixmhdNhmInGwUvAeqDSJxomwv1KK1cTndrC9zAMZ7h657BGQAwGhu7nTm41fWMpKQdiLa9sqp3yit5_FNBmqUNeOoMPrYT_Vl9ytsoNO89MUQy2aqCd-Z7BrNJZH0QycdW6dmYlrmZL7w3t3TaAXoJDJ4Hgl2Itkkkb6_6gO-VoPIdVD8sDuf1zQzGhIkmcFrk0fXczVYOkeF2hNYBuvsM8LuO-EPA3oyE2In9djai3M7yceTQetRa1vwlqWkg_xmYS59ry-6wT44aN7-Y6p0TdXm-Zg',
|
214 | keyOrStore,
|
215 | {
|
216 | issuer: 'https://op.example.com',
|
217 | audience: 'urn:example:client_id',
|
218 | algorithms: ['PS256']
|
219 | }
|
220 | )
|
221 | ```
|
222 |
|
223 | </details>
|
224 |
|
225 | #### JWS Signing
|
226 |
|
227 | Sign with a private or symmetric key using compact serialization. See the
|
228 | [documentation][documentation-jws] for more.
|
229 |
|
230 | ```js
|
231 | jose.JWS.sign(
|
232 | { sub: 'johndoe' },
|
233 | privateKey,
|
234 | { kid: privateKey.kid }
|
235 | )
|
236 | ```
|
237 |
|
238 | #### JWS Verifying
|
239 |
|
240 | Verify with a public or symmetric key. See the [documentation][documentation-jws] for more.
|
241 |
|
242 | ```js
|
243 | jose.JWS.verify(
|
244 | 'eyJhbGciOiJFUzI1NiJ9.eyJzdWIiOiJqb2huZG9lIn0.T_SYLQV3A5_kFDDVNuoadoURSEtuSOR-dG2CMmrP-ULK9xbIf2vYeiHOkvTrnqGlWEGBGxYtsP1VkXmNsi1uOw',
|
245 | publicKey
|
246 | )
|
247 | ```
|
248 |
|
249 | #### JWE Encrypting
|
250 |
|
251 | Encrypt using the recipient's public key or a shared symmetrical secret. See the
|
252 | [documentation][documentation-jwe] for more.
|
253 |
|
254 | ```js
|
255 | jose.JWE.encrypt(
|
256 | 'eyJhbGciOiJFUzI1NiJ9.eyJzdWIiOiJqb2huZG9lIn0.T_SYLQV3A5_kFDDVNuoadoURSEtuSOR-dG2CMmrP-ULK9xbIf2vYeiHOkvTrnqGlWEGBGxYtsP1VkXmNsi1uOw',
|
257 | publicKey,
|
258 | { kid: publicKey.kid }
|
259 | )
|
260 | ```
|
261 |
|
262 | #### JWE Decrypting
|
263 |
|
264 | Decrypt using the private key or a shared symmetrical secret. See the
|
265 | [documentation][documentation-jwe] for more.
|
266 |
|
267 | ```js
|
268 | jose.JWE.decrypt(
|
269 | 'eyJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiYWxnIjoiRUNESC1FUyIsImVwayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMjU2IiwieCI6IkVsUGhsN1ljTVZsWkhHM0daSkRoOVJhemNYYlN2VFNheUF6aTBINFFtRUEiLCJ5IjoiM0hDREJTRy12emd6cGtLWmJqMU05UzVuUEJrTDBBdFM4U29ORUxMWE1SayJ9fQ..FhmidRo0twvFA7jcfKFNJw.o112vgiG_qUL1JR5WHpsErcxxgaK_FAa7vCWJ--WulndLpdwdRXHd9k3aL_k8K67xoAThrt10d7dSY2TlPpHdYkw979u0V-C4TNrpzNkv5jpBjU6hHyKpoGZfEsiTD1ivHaFy3ZLCTS69kN_eVKsZGLVf_dkq6Sz6bWE4-ln_fuwukPyMvjTyaTreLjPLBZW.ocKwptCm4Zn437L5hWFnHg',
|
270 | privateKey
|
271 | )
|
272 | ```
|
273 |
|
274 | ## Detailed Support Matrix
|
275 |
|
276 | | JWK Key Types | Supported | `kty` value | `crv` values |
|
277 | | -- | -- | -- | -- |
|
278 | | RSA | ✓ | RSA ||
|
279 | | Elliptic Curve | ✓ | EC | P-256, secp256k1<sup>[1]</sup>, P-384, P-521 |
|
280 | | Octet Key Pair | ✓ | OKP | Ed25519, Ed448<sup>[1]</sup>, X25519<sup>[1]</sup>, X448<sup>[1]</sup> |
|
281 | | Octet sequence | ✓ | oct ||
|
282 |
|
283 | | Serialization | JWS Sign | JWS Verify | JWE Encrypt | JWE Decrypt |
|
284 | | -- | -- | -- | -- | -- |
|
285 | | Compact | ✓ | ✓ | ✓ | ✓ |
|
286 | | General JSON | ✓ | ✓ | ✓ | ✓ |
|
287 | | Flattened JSON | ✓ | ✓ | ✓ | ✓ |
|
288 |
|
289 | | JWS Algorithms | Supported ||
|
290 | | -- | -- | -- |
|
291 | | RSASSA-PKCS1-v1_5 | ✓ | RS256, RS384, RS512 |
|
292 | | RSASSA-PSS | ✓ | PS256, PS384, PS512 |
|
293 | | ECDSA | ✓ | ES256, ES256K<sup>[1]</sup>, ES384, ES512 |
|
294 | | Edwards-curve DSA | ✓ | EdDSA |
|
295 | | HMAC with SHA-2 | ✓ | HS256, HS384, HS512 |
|
296 | | Unsecured JWS | ✓ | none<sup>[2]</sup> |
|
297 |
|
298 | | JWE Key Management Algorithms | Supported ||
|
299 | | -- | -- | -- |
|
300 | | AES | ✓ | A128KW<sup>[1]</sup>, A192KW<sup>[1]</sup>, A256KW<sup>[1]</sup> |
|
301 | | AES GCM | ✓ | A128GCMKW, A192GCMKW, A256GCMKW |
|
302 | | Direct Key Agreement | ✓ | dir |
|
303 | | RSAES OAEP | ✓ | RSA-OAEP, RSA-OAEP-256<sup>[3]</sup> |
|
304 | | RSAES-PKCS1-v1_5 | ✓ | RSA1_5 |
|
305 | | PBES2 | ✓ | PBES2-HS256+A128KW<sup>[1]</sup>, PBES2-HS384+A192KW<sup>[1]</sup>, PBES2-HS512+A256KW<sup>[1]</sup> |
|
306 | | ECDH-ES (for all EC keys) | ✓ | ECDH-ES, ECDH-ES+A128KW<sup>[1]</sup>, ECDH-ES+A192KW<sup>[1]</sup>, ECDH-ES+A256KW<sup>[1]</sup> |
|
307 | | ECDH-ES (for OKP X25519) | ✓ <sup>via [plugin][plugin-x25519]</sup> | ECDH-ES, ECDH-ES+A128KW, ECDH-ES+A192KW, ECDH-ES+A256KW |
|
308 | | ECDH-ES (for OKP X448) | ✕ ||
|
309 | | (X)ChaCha | ✓ <sup>via [plugin][plugin-chacha]</sup> | C20PKW, XC20PKW, ECDH-ES+C20PKW, ECDH-ES+XC20PKW |
|
310 |
|
311 | | JWE Content Encryption Algorithms | Supported ||
|
312 | | -- | -- | -- |
|
313 | | AES GCM | ✓ | A128GCM, A192GCM, A256GCM |
|
314 | | AES_CBC_HMAC_SHA2 | ✓ | A128CBC-HS256, A192CBC-HS384, A256CBC-HS512 |
|
315 | | (X)ChaCha | ✓ <sup>via [plugin][plugin-chacha]</sup> | C20P, XC20P |
|
316 |
|
317 | | JWT profile validation | Supported | profile option value |
|
318 | | -- | -- | -- |
|
319 | | ID Token - [OpenID Connect Core 1.0][spec-oidc-id_token] | ✓ | `id_token` |
|
320 | | JWT Access Tokens [JWT Profile for OAuth 2.0 Access Tokens][draft-ietf-oauth-access-token-jwt] | ✓ | `at+JWT` |
|
321 | | Logout Token - [OpenID Connect Back-Channel Logout 1.0][spec-oidc-logout_token] | ✓ | `logout_token` |
|
322 | | JARM - [JWT Secured Authorization Response Mode for OAuth 2.0][draft-jarm] | ◯ ||
|
323 |
|
324 | Legend:
|
325 | - **✓** Implemented
|
326 | - **✕** Missing node crypto support / won't implement
|
327 | - **◯** TBD
|
328 |
|
329 | <sup>1</sup> Not supported in Electron due to Electron's use of BoringSSL
|
330 | <sup>2</sup> Unsecured JWS is [supported][documentation-none] for the JWS and JWT sign and verify
|
331 | operations but it is an entirely opt-in behaviour, downgrade attacks are prevented by the required
|
332 | use of a special `JWK.Key`-like object that cannot be instantiated through the key import API
|
333 | <sup>3</sup> RSA-OAEP-256 is only supported when Node.js >= 12.9.0 runtime is detected
|
334 |
|
335 | ## FAQ
|
336 |
|
337 | #### Semver?
|
338 |
|
339 | **Yes.** Everything that's either exported in the TypeScript definitions file or
|
340 | [documented][documentation] is subject to
|
341 | [Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html). The rest is to be considered
|
342 | private API and is subject to change between any versions.
|
343 |
|
344 | #### How do I use it outside of Node.js
|
345 |
|
346 | It is **only built for >=10.13.0 Node.js** environment - including `jose` in transpiled
|
347 | browser-environment targeted projects is not supported and may result in unexpected results.
|
348 |
|
349 | #### How is it different from [`jws`](https://github.com/brianloveswords/node-jws), [`jwa`](https://github.com/brianloveswords/node-jwa) or [`jsonwebtoken`](https://github.com/auth0/node-jsonwebtoken)?
|
350 |
|
351 | - it supports JWK Key Format for all four key types (oct, RSA, EC and OKP)
|
352 | - it is providing Key and KeyStore abstractions
|
353 | - there is JSON Web Encryption support
|
354 | - it supports all JWS / JWE Serialization Syntaxes
|
355 | - it supports the "crit" member validations to make sure extensions are handled correctly
|
356 | - it is not only validating the signatures, it is making sure the JWE/JWS is syntactically correct,
|
357 | e.g. not having duplicated header parameters between protected/unprotected or per-recipient
|
358 | headers
|
359 |
|
360 | #### How is it different from [`node-jose`][node-jose]
|
361 |
|
362 | `node-jose` is built to work in any javascript runtime, to be able to do that it packs a lot of
|
363 | backfill and javascript implementation code in the form of
|
364 | [`node-forge`](https://github.com/digitalbazaar/forge), this significantly increases the footprint
|
365 | of the module with dependencies that either aren't ever used or have native implementation available
|
366 | in Node.js already, those are often times faster and more reliable.
|
367 |
|
368 | #### What is the ultimate goal?
|
369 |
|
370 | - **No dependencies**, the moment JWK formatted keys are supported by node's `crypto` the direct
|
371 | dependency count will go down from 1 to 0. 🚀
|
372 | - Just the API one needs, having used other jose modules for 3+ years I only include what's useful
|
373 |
|
374 | #### Why? Just, why?
|
375 |
|
376 | I was using [`node-jose`][node-jose] for
|
377 | [`openid-client`](https://github.com/panva/node-openid-client) and
|
378 | [`oidc-provider`](https://github.com/panva/node-oidc-provider) and came to realize its shortcomings
|
379 | in terms of performance and API (not having well defined errors).
|
380 |
|
381 | + this was an amazing opportunity to learn JOSE as a whole
|
382 |
|
383 | [ask]: https://github.com/panva/jose/issues/new?labels=question&template=question.md&title=question%3A+
|
384 | [bug]: https://github.com/panva/jose/issues/new?labels=bug&template=bug-report.md&title=bug%3A+
|
385 | [documentation-jwe]: /docs/README.md#jwe-json-web-encryption
|
386 | [documentation-jwk]: /docs/README.md#jwk-json-web-key
|
387 | [documentation-jwks]: /docs/README.md#jwks-json-web-key-set
|
388 | [documentation-jws]: /docs/README.md#jws-json-web-signature
|
389 | [documentation-jwt]: /docs/README.md#jwt-json-web-token
|
390 | [documentation-none]: /docs/README.md#jwknone
|
391 | [documentation]: /docs/README.md
|
392 | [node-jose]: https://github.com/cisco/node-jose
|
393 | [security-vulnerability]: https://github.com/panva/jose/issues/new?template=security-vulnerability.md
|
394 | [spec-b64]: https://tools.ietf.org/html/rfc7797
|
395 | [spec-cookbook]: https://tools.ietf.org/html/rfc7520
|
396 | [spec-jwa]: https://tools.ietf.org/html/rfc7518
|
397 | [spec-jwe]: https://tools.ietf.org/html/rfc7516
|
398 | [spec-jwk]: https://tools.ietf.org/html/rfc7517
|
399 | [spec-jws]: https://tools.ietf.org/html/rfc7515
|
400 | [spec-jwt]: https://tools.ietf.org/html/rfc7519
|
401 | [spec-okp]: https://tools.ietf.org/html/rfc8037
|
402 | [draft-secp256k1]: https://tools.ietf.org/html/draft-ietf-cose-webauthn-algorithms-04
|
403 | [draft-ietf-oauth-access-token-jwt]: https://tools.ietf.org/html/draft-ietf-oauth-access-token-jwt
|
404 | [draft-jarm]: https://openid.net/specs/openid-financial-api-jarm.html
|
405 | [spec-thumbprint]: https://tools.ietf.org/html/rfc7638
|
406 | [spec-oidc-id_token]: https://openid.net/specs/openid-connect-core-1_0.html#IDToken
|
407 | [spec-oidc-logout_token]: https://openid.net/specs/openid-connect-backchannel-1_0.html#LogoutToken
|
408 | [oidc-token-hash]: https://www.npmjs.com/package/oidc-token-hash
|
409 | [suggest-feature]: https://github.com/panva/jose/issues/new?labels=enhancement&template=feature-request.md&title=proposal%3A+
|
410 | [support-sponsor]: https://github.com/sponsors/panva
|
411 | [sponsor-auth0]: https://auth0.com/overview?utm_source=GHsponsor&utm_medium=GHsponsor&utm_campaign=panva-jose&utm_content=auth
|
412 | [plugin-x25519]: https://github.com/panva/jose-x25519-ecdh
|
413 | [plugin-chacha]: https://github.com/panva/jose-chacha
|