RS256
employs digital signatures to provide Integrity, Authenticity, and Non-repudiation for the generated token. However, it does not guarantee Confidentiality.
If you wish to utilize JWE (JSON Web Encryption) with JWT, it is possible. Since you act as both the issuer and recipient of the token, it is recommended to opt for symmetric encryption. Asymmetric crypto may not be suitable because anyone possessing the public key could encrypt the data, posing a threat to the authenticity of the producer of the JWE.
To achieve Integrity, Authenticity, and Confidentiality, you will need an implementation or library that supports JWE formatted JWTs. For example:
npm install jose@4
For encryption, refer to EncryptJWT
import * as crypto from 'crypto'
import { EncryptJWT } from 'jose'
const secretKey = crypto.randomBytes(32) // insert your own 32-byte secret as a Buffer
const jwt = await new EncryptJWT({ 'urn:example:claim': true })
.setProtectedHeader({ alg: 'dir', enc: 'A256GCM' })
.setIssuedAt()
.setIssuer('urn:example:issuer')
.setAudience('urn:example:audience')
.setExpirationTime('2h')
.encrypt(secretKey)
This process results in a JWE-formatted JWT that cannot have its payload decrypted without knowledge of the secretKey
.
eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0..Wz7DdwAPlbq4cYxn.OMfWJTMuyfLcdN4g541KfcDFKaL5y2bBaFIxuC_-mVa7YLE4M7bVfiO9R2umvpD_acGj5l3gvxulcRnHzBMeRpm4qgbJuWVdA1fYUOguDs1h2xtesZ_9iZUEtcu3hEJ1wVM46ad-9dPebe_VaWwe4XVU5GM.7lDflVFg_Qm3N88xX8Dy1A
To decrypt and verify the JWT Claim Set, use jwtDecrypt
import { jwtDecrypt } from 'jose'
const { payload, protectedHeader } = await jwtDecrypt(jwt, secretKey, {
issuer: 'urn:example:issuer',
audience: 'urn:example:audience'
})