JWT公钥与私钥签名验证 - 有什么区别?

时间:2017-10-29 11:53:01

标签: authentication rsa jwt digital-signature auth0

我正在使用这个库node-jwks-rsa从我的auth0 jwks.json文件中获取JWT密钥,以验证我的应用程序在验证实际来自我的身份验证提供程序后检索到的id_token。

在幕后,它使用此方法构建公钥PEM

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

(使用x50c作为.jwks文件中的参数)。

然后我与jsonwebtoken结合使用来验证JWT(id_token)是否有效。

这种验证方法与jwks.json文件的模数和指数生成私钥(RSA)并使用它进行验证有何不同? (例如见library

此外,此处还可以作为演示,从mod和exponent(取自http://stackoverflow.com/questions/18835132/xml-to-pem-in-node-js)生成PEM

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;
  };

前面提到的jsonwebtoken库可以使用其中任何一个验证JWT - 但为什么?如果这两种验证方法都可以验证JWT签名,为什么它们都存在?他们之间的权衡是什么?一个比另一个更安全吗?我应该用哪个来充分验证?

1 个答案:

答案 0 :(得分:2)

使用RSA不对称密钥对,JWT使用私钥签名并向公众验证。您无法使用私钥验证数字签名

模数和指数是公钥的组成部分,您可以使用它来构建PEM格式的公钥,这是以DER二进制格式编码的公钥(模数和指数)的base64表示。您可以使用PEM,DER或模数和指数,因为它包含相同的信息

但任何人都无法使用模数和指数构建私钥。他需要私人RSA元素,这些元素必须保密,以便没有人可以为你签名。