2

I use the crypto core-module in node.js to generate an EC-key-pair.

I then use this key-pair to sign and verify JWT's.

I would expect the signing/verification to only work when using an EC-algorithm.

However it seems to be working with any algorithm except HMAC.

From my understanding, this shouldn't be possible.

Can anyone explain this to me?

Thank you for reading my question.

const crypto = require('crypto')
const jwt = require('jsonwebtoken')

const keyPair = crypto.generateKeyPairSync('ec', {
  namedCurve: 'secp256k1',
  publicKeyEncoding: {
    type: 'spki',
    format: 'pem'
  },
  privateKeyEncoding: {
    type: 'pkcs8',
    format: 'pem'
  }
})

const token = jwt.sign({}, keyPair.privateKey, {
  algorithm: 'ES256' // I expect this to work, but it seems to be also working with e.g. "RS256" or "PS512", which I don't understand.
})

const verify = jwt.verify(token, keyPair.publicKey)
dandan
  • 115
  • 5

1 Answers1

0

This made me curious too, so I tried to dig up sources. If you follow what happens during signing a jwt, you will eventually get to this:

function createKeySigner(bits) {
 return function sign(thing, privateKey) {
    checkIsPrivateKey(privateKey);
    thing = normalizeInput(thing);
    // Even though we are specifying "RSA" here, this works with ECDSA
    // keys as well.
    var signer = crypto.createSign('RSA-SHA' + bits);
    var sig = (signer.update(thing), signer.sign(privateKey, 'base64'));
    return fromBase64(sig);
  }
}

This doesn't answer why though. So digging deeper, crypto is implemented in C, and I think this is the relevant part. If I understand correctly, the reason it works mostly comes down to the fact that it is just read as a string/buffer.

Gabor Lengyel
  • 14,129
  • 4
  • 32
  • 59