How to extract the public key from jwk returns from identity server 4 in nodejs?

I am using jose npm packege.

var http = require('http');
var { default: parseJwk } = require('jose/jwk/parse');

http.get('http://hostname/.well-known/openid-configuration/jwks', (resp) => {
    let data = '';

    // A chunk of data has been received.
    resp.on('data', (chunk) => {
        data += chunk;
    });
    resp.on('end', () => {
        parseJwk(JSON.parse(data).keys[0])
            .then(rsaPublicKey => {
                /// how to extract public key here
                res.send({ raw: JSON.parse(data), parsed: rsaPublicKey });
            }, err => {
                res.status(500).json(err);
            });
        // res.send({raw: JSON.parse(data), parsed: ''});
        // console.log(JSON.parse(data));
    });

}).on("error", (err) => {
    console.log("Error: " + err.message);
    res.status(500).json(err);
});

JWK token sample:

{
    alg:'RS256'
    e:'AQAB'
    kid:'MKYnjQ_a1EfAdUkVD7ToVA'
    kty:'RSA'
    n:'01ixZ7ujifVsulyKYKF9Wat_fZRzjkOPG3CL4Iw-Ntxjb6mJUSdTBsV7yYjXjI3yFOqr0loCwfHZb40EE1A7hPNzK3etbAA2SIZa365ZJjv7qJobeCgZjvJnr5UvL-xEBAEzS3vS4u9KmI0-AF243SxtmQxrpkfqTl-cL4wDMmkffGBFlAigufR80NXR5sTejEHAQzjCTPR1518ssNX9OM8t1QHGxGwtp5OUZDSx0DZuCGuvHfEk5eYIEqNfhNEtZnvPmEEqrv6Adweaf4XI2kSrFlBfVjE2DXzeTvy8Kd9wSw6jE8gj-mfo9CcYKpLSqZrxUSetz0RfAnK2sLF1OQ'
    use:'sig'
}

In above code how to extract the public key to verify the jwt?

Answer

In most libraries I’ve used, you need to translate from a JWK format to PEM format before verification. This can get quite low level and it is usually advisable to use a library. Here is a class of mine with some sample usage and the below library:

Even better, the JWKS-RSA library is useful since it caches the JWKS key to prevent redundant downloads:

import jwksClient, {SigningKey} from 'jwks-rsa';

private async _downloadJwksKeyForKeyIdentifier(tokenKeyIdentifier: string): Promise<string> {

    return new Promise<string>((resolve, reject) => {

        const client = jwksClient({
            jwksUri: this._oauthConfig.jwksEndpoint,
        });

        client.getSigningKey(tokenKeyIdentifier, (err: any, key: SigningKey) => {

            if (err) {
                return reject(err);
            }

            return resolve(key.getPublicKey());
        });
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *