Trying to convert JWT to JWE but facing some error

175 views Asked by At

I want to convert JWT into JWE but all my tries have failed. I am trying React JS. I also tried in Express JS but faced the same error. I have used Node-Jose for my tries.

const createJWE = async () => {
    // Payload to be included in the JWT
    const payload = {
        idToken: 'token',
    };

    try {
        // Sign the JWT
        const jwt = await jose.JWS.createSign({ format: 'compact' }, { key: rsaPublicKey }).update(JSON.stringify(payload)).final();

       // Encrypt the JWT to create a JWE
       const jwe = await jose.JWE.createEncrypt({ format: 'compact' }, { key: rsaPublicKey }).update(jwt).final();
        
       console.log(jwe);
   } catch (error) {
       console.error('JWE Creation Error:', error);
   }
}
createJWE();

The output

enter image description here

1

There are 1 answers

0
samthecodingman On

Based on the source for createSign(...), key in the second argument is expected to be a JWK, either as an object, or as a JSON string. So your error is derived from the value of rsaPublicKey being in the wrong format.

As the value used for key is a JWK object/string, it should look similar to:

{
  "kty": "RSA",
  "n": "qPfgaTEWEP3S9w0tgsicURfo-nLW09_0KfOPinhYZ4ouzU-3xC4pSlEp8Ut9FgL0AgqNslNaK34Kq-NZjO9DAQ==",
  "e": "AQAB"
}

Based on the error message, your rsaPublicKey probably contains the content of a PEM file (as the error complains the first character is a minus, but the second is not a number):

-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKj34GkxFhD90vcNLYLInFEX6Ppy1tPf
9Cnzj4p4WGeKLs1Pt8QuKUpRKfFLfRYC9AIKjbJTWit+CqvjWYzvQwECAwEAAQ==
-----END PUBLIC KEY-----

To import a key in this format, you need to bring the key in using keystore.add (from JWK.createKeyStore()) or JWK.asKey and specifying the format.

const publicKey = await jose.JWK.asKey(rsaPublicKey, "pem"); // "pem" derives the key type

// usage:
const jwe = await jose.JWE
  .createEncrypt({ format: 'compact' }, publicKey)
  .update(/* ... */)
  .final();

Ultimately you should be using a private key to sign instead.

const privateKey = await jose.JWK.asKey(rsaPrivateKey, "pem"); // "pem" derives the key type

// usage:
const jwe = await jose.JWE
  .createEncrypt({ format: 'compact' }, privateKey)
  .update(/* ... */)
  .final();

Note: Above keys were obtained from https://phpseclib.com/docs/rsa-keys