JWT public 密钥与私钥签名验证——有什么区别?

JWT public key vs private key signature validation -- what is the difference?

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

在幕后,它使用此方法构建 public 密钥 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 文件的 modulus 和指数生成私钥 (RSA) 并将其用于验证有何不同? (例如,参见此 library

此外,这里还有一个演示功能,它从 mod 和指数(取自 )

生成 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 签名,为什么它们都存在?它们之间的权衡是什么?一个比另一个更安全吗?我应该用哪个来验证最充分?

使用 RSA 非对称密钥对,JWT 用私钥签名并用 public 验证。您无法使用私钥验证数字签名

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

但是任何人都不能用模数和指数来构建私钥。他需要私有的 RSA 元素,这些元素必须保密,这样就没有人可以为您签名。