Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Implementing JWE encryption for a JWS signed token in Node.JS with Jose 4.11

I have difficulty manipulating the Jose Node.JS documentation to chain the creation of a JWS and JWE. I cannot find the proper constructor for encryption. It looks like I can only encrypt a basic payload not a signed JWS.

Here is the code sample I try to fix to get something that would look like

const jws = await createJWS("myUserId");
const jwe = await encryptAsJWE(jws);

with the following methods

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

export const createJWS = async (userId) => {
  const payload = {
  }

  payload['urn:userId'] = userId

  // importing key from base64 encrypted secret key for signing...
  const secretPkcs8Base64 = process.env.SMART_PRIVATE_KEY
  const key = new NodeRSA()
  key.importKey(Buffer.from(secretPkcs8Base64, 'base64'), 'pkcs8-private-der')
  const privateKey = key.exportKey('pkcs8')
  const ecPrivateKey = await jose.importPKCS8(privateKey, 'ES256')

  const assertion = await new jose.SignJWT(payload)
    .setProtectedHeader({ alg: 'RS256' })
    .setIssuer('demolive')
    .setExpirationTime('5m')
    .sign(ecPrivateKey)

  return assertion
}

export const encryptAsJWE = async (jws) => {

  // importing key similar to createJWS key import
  const idzPublicKey = process.env.IDZ_PUBLIC_KEY //my public key for encryption
  ...
  const pkcs8PublicKey = await jose.importSPKI(..., 'ES256')

 
  // how to pass a signed JWS as parameter?
  const jwe = await new jose.CompactEncrypt(jws)
                     .encrypt(pkcs8PublicKey)
  return jwe
}

>Solution :

The input to the CompactEncrypt constructor needs to be a Uint8Array, so just wrapping the jws like so (new TextEncoder().encode(jws)) will allow you to move forward.

Moving forward then:

You are also missing the JWE protected header, given you likely use an EC key (based on the rest of your code) you should a) choose an appropriate EC-based JWE Key Management Algorithm (e.g. ECDH-ES) and put that as the public key import algorithm, then proceed to call .setProtectedHeader({ alg: 'ECDH-ES', alg: 'A128CBC-HS256' }) on the constructed object before calling encrypt.

Here’s a full working example https://github.com/panva/jose/issues/112#issue-746919790 using a different combination of algorithms but it out to help you get the gist of it.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading