auth0 / node-jsonwebtoken

JsonWebToken implementation for node.js http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html
MIT License
17.64k stars 1.22k forks source link

parsing RSA keys is wrong #893

Open its-dibo opened 1 year ago

its-dibo commented 1 year ago

when passing an RSA key to jwt.verify(token, secretOrPublicKey, {algoriths: ['RS256'] }), it is being parsed wrongly.

when passing a public key it is parsed as { type: "secret" }, and when passing a private key it is parsed as { type: "public" }

pixtron commented 1 year ago

This library internaly uses node's crypto.createPublicKey(). When you pass your privateKey createPublicKey derives the public key from the privateKey. Therefore {type: 'public'} is correct.

For the other case where you get {type: 'secret'}, i assume you stored your public key in PEM Format and either are missing -----BEGIN PUBLIC KEY----- / -----END PUBLIC KEY----- or there are whitespaces/indentations.

You can always re export the public key from your private key. You can store and pass the key in jwk or pem format.

const { createPublicKey } = require('node:crypto');

const publicKey = createPublicKey(privateKey);

const publicJwk = publicKey.export({type: 'spki', format: 'jwk'});
const publicPem = publicKey.export({type: 'spki', format: 'pem'});

console.log(publicJwk);
console.log(publicPem);
zailaib commented 1 year ago

// node 18

const crypto = require('crypto');
const jwt = require('jsonwebtoken');
const pem2jwk = require('pem-jwk').pem2jwk

const { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', {
    modulusLength: 2048,
    privateKeyEncoding: {
        type: 'pkcs8',
        format: 'pem'
    },
    publicKeyEncoding: {
        type: 'spki',
        format: 'pem'
    },
});

const aTmpJwk = pem2jwk(publicKey);

module.exports = aTmpJwk;

const payload = { sub: 'user123', role: 'admin' };
const token = jwt.sign(payload, privateKey, { algorithm: 'RS256' });

console.log("token=", token);

jwt.verify(token, publicKey, function (err, user) {
    console.log("=====")
    console.log(err)
    console.log(user) // user info from the token
    console.log("=====")
});