I am currently using jose for signing and encrypting JWTs, but I am facing an issue when trying to sign and then encrypt the entire JWT.
When it comes to signing my JWT, I utilize the following function:
const secretKey = process.env.JWT_SECRET;
const key = new TextEncoder().encode(secretKey);
export async function _encrypt(payload: any) {
return await new SignJWT(payload)
.setProtectedHeader({ alg: "HS256" })
.setIssuedAt()
.setExpirationTime("10 sec from now")
.sign(key);
}
For encryption, I use the following code snippet (which works when passing a JWT object):
const now = () => (Date.now() / 1000) | 0;
const alg = "dir";
const enc = "A256CBC-HS512";
...
sync function encrypt({
payload,
maxAge,
}: {
payload: JWTPayload;
maxAge: number;
}): Promise<string> {
const secret: Uint8Array = randomBytes(32);
const salt = randomBytes(16);
const encryptionSecret: Uint8Array = await hkdf(
"sha256",
secret,
salt,
"Generated Encryption Key",
32
);
return new EncryptJWT(payload)
.setProtectedHeader({ alg, enc })
.setIssuedAt()
.setExpirationTime(now() + maxAge)
.setJti(crypto.randomUUID())
.encrypt(encryptionSecret);
}
The problem arises because EncryptJWT only accepts a JWT object, as indicated by the error message in the console:
error TypeError: JWT Claims Set MUST be an object