djwt icon indicating copy to clipboard operation
djwt copied to clipboard

Unexpected change of JWT Key

Open so1ve opened this issue 1 year ago • 4 comments

Hi timonson! I have created a program that uses djwt and runs on deno deploy. Maybe because Deno Deploy is not running on a single server, the jwt key I created will change from time to time, resulting in unexpected jwt token invalidation. Tokens generated with the old key will be invalid after the key is updated.

export const jwtKey = await crypto.subtle.generateKey(
   { name: "HMAC", hash: "SHA-512" },
   true,
   ["sign", "verify"],
);

Not sure if there is any specific way to solve it.

so1ve avatar Jul 06 '22 12:07 so1ve

Does it work if you create a key only once in the deployed app?

timonson avatar Jul 06 '22 18:07 timonson

The Web Crypto API has methods for importing and exporting keys (see the mdn web docs for more info)

  1. Generate a key
const key = await crypto.subtle.generateKey(
  { name: "HMAC", hash: "SHA-512" },
  true,
  ["sign", "verify"],
);
  1. Create a JWT
const jwt = await create({ alg: "HS512", typ: "JWT" }, { foo: "bar" }, key);
  1. Export the key E.g. write this to a file which you can read later on— it's up to you how you persist this file, depending on your project.
let exportedKey = await crypto.subtle.exportKey("jwk", key)
  1. Reimport the key and confirm everything works
let reimportedKey = await crypto.subtle.importKey(
  "jwk", 
  exportedKey, 
  { name: "HMAC", hash: "SHA-512" }, true, ["sign", "verify"]);

  // Confirm everything works as expected

  console.log(await verify(jwt, reimportedKey))
  // {foo: 'bar'}

chrisyalamov avatar Jul 07 '22 15:07 chrisyalamov

Does it not work if you create a key only once in the whole deployed app?

Yes, I exported it in a file (jwt_key.ts):

export const jwtKey = await crypto.subtle.generateKey(
   { name: "HMAC", hash: "SHA-512" },
   true,
   ["sign", "verify"],
);

so1ve avatar Jul 07 '22 15:07 so1ve

The Web Crypto API has methods for importing and exporting keys (see the mdn web docs for more info)

  1. Generate a key
const key = await crypto.subtle.generateKey(
  { name: "HMAC", hash: "SHA-512" },
  true,
  ["sign", "verify"],
);
  1. Create a JWT
const jwt = await create({ alg: "HS512", typ: "JWT" }, { foo: "bar" }, key);
  1. Export the key E.g. write this to a file which you can read later on— it's up to you how you persist this file, depending on your project.
let exportedKey = await crypto.subtle.exportKey("jwk", key)
  1. Reimport the key and confirm everything works
let reimportedKey = await crypto.subtle.importKey(
  "jwk", 
  exportedKey, 
  { name: "HMAC", hash: "SHA-512" }, true, ["sign", "verify"]);

  // Confirm everything works as expected

  console.log(await verify(jwt, reimportedKey))
  // {foo: 'bar'}

thank you for your reply! However, how should I implement this?

so1ve avatar Jul 07 '22 15:07 so1ve

兄弟,找到解决办法没

youwei997 avatar Sep 19 '22 17:09 youwei997

兄弟,找到解决办法没

没呢

目前我的办法是 将JSON化后的JWT Key硬编码在环境变量里()

so1ve avatar Sep 23 '22 11:09 so1ve

Please talk in English guys! @so1ve wouldn't you agree that this a deno.com issue and not a djwt issue, if at all? Although, it might be that I have not fully understood the problem yet.

timonson avatar Sep 23 '22 11:09 timonson

I'm so sorry...it's actually a deno.com issue. https://github.com/denoland/deploy_feedback/issues/237

so1ve avatar Sep 23 '22 11:09 so1ve

Oh no problem at all. I was rather curious what the problem was. Thank you!

timonson avatar Sep 23 '22 11:09 timonson

I think this is caused by Deno Deploy being deployed on the edge server, which causes my program to run from scratch every time (including the part that generates the key).

so1ve avatar Sep 23 '22 11:09 so1ve