Auth0 Home Blog Docs

What are the tradeoffs between verifying JWT using public key versus RSA (mod and exponentB64)

jwt
jwks
jwt-validation
rsa

#1

Hello I am using this great library to fetch from my auth0 jwks.json in order to verify that the id_token retrieved after Authentication is coming from Auth0: https://github.com/auth0/node-jwks-rsa

Under the hood it uses this method to build a public key PEM which it then uses in combination with https://github.com/auth0/node-jsonwebtoken to verify that the JWT(id_token) is valid:

export function certToPEM(cert) {
  cert = cert.match(/.{1,64}/g).join('\n');
  cert = `-----BEGIN CERTIFICATE-----\n${cert}\n-----END CERTIFICATE-----\n`;
  return cert;
}

(Using the x50c argument from the .jwks file).

I’m wondering how doing this is different from an alternate verification process of generating a private key(RSA) from a modulus and exponent within the jwk and using it for verification instead. This library seems to allow for it: https://github.com/tracker1/node-rsa-pem-from-mod-exp

Additionally here is function to generate a PEM from a mod and exponent (taken from http://stackoverflow.com/questions/18835132/xml-to-pem-in-node-js)

export function rsaPublicKeyToPEM(modulusB64, exponentB64) {
    const modulus = new Buffer(modulusB64, 'base64');
    const exponent = new Buffer(exponentB64, 'base64');
    const modulusHex = prepadSigned(modulus.toString('hex'));
    const exponentHex = prepadSigned(exponent.toString('hex'));
    const modlen = modulusHex.length / 2;
    const explen = exponentHex.length / 2;
  
    const encodedModlen = encodeLengthHex(modlen);
    const encodedExplen = encodeLengthHex(explen);
    const encodedPubkey = '30' +
      encodeLengthHex(modlen + explen + encodedModlen.length / 2 + encodedExplen.length / 2 + 2) +
      '02' + encodedModlen + modulusHex +
      '02' + encodedExplen + exponentHex;
  
    const der = new Buffer(encodedPubkey, 'hex')
      .toString('base64');
  
    let pem = `-----BEGIN RSA PUBLIC KEY-----\n`;
    pem += `${der.match(/.{1,64}/g).join('\n')}`;
    pem += `\n-----END RSA PUBLIC KEY-----\n`;
  
    return pem;
  };

If both of these verification methods are the same why do they both exist? What are the tradeoffs between them? Is one more secure than the other?


#2