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

Authentication JWT公钥与私钥签名验证——有什么区别?,authentication,rsa,jwt,digital-signature,auth0,Authentication,Rsa,Jwt,Digital Signature,Auth0,我正在使用这个库,从auth0 jwks.json文件中获取JWT密钥,以验证我的应用程序在身份验证后检索的id_令牌实际上来自我的身份验证提供程序 在引擎盖下,它使用此方法构建公钥PEM export function certToPEM(cert) { cert = cert.match(/.{1,64}/g).join('\n'); cert = `-----BEGIN CERTIFICATE-----\n${cert}\n-----END CERTIFICATE-----\n`;

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

在引擎盖下,它使用此方法构建公钥PEM

export function certToPEM(cert) {
  cert = cert.match(/.{1,64}/g).join('\n');
  cert = `-----BEGIN CERTIFICATE-----\n${cert}\n-----END CERTIFICATE-----\n`;
  return cert;
}
(使用.jwks文件中的x50c作为参数)

然后我结合使用它来验证JWT(id_令牌)是否有效

这种验证方法与从jwks.json文件的模和指数生成私钥(RSA)并将其用于验证有何不同?(如示例所示)

此外,这里还有一个函数作为演示,它可以从mod和指数(取自)生成PEM


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

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

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


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

只有公钥(已配置)用于签名验证。在后台,两个库都需要计算散列并验证散列签名。在验证正确完成之前,没有理由一个人比另一个人更安全。@gusto2-我仍然感到困惑。如果只使用公钥,为什么在上的交互式调试器允许使用我上面描述的两种方法(公钥和私钥)进行JWT签名验证?您无法使用私钥验证数字签名。不清楚你在问什么谢谢你佩德罗。从OpenId流的角度来看,jwk/s的所有不同字段是如何与此相关的,您有任何链接到这些信息吗?也就是x50c的来源。我想扩展我的知识和理解。OpenIdConnect或Oauth2与JWK(JsonWebKey)无关。JWK是一种表示此RFC中定义的加密密钥的格式。Auth0的概念似乎是一个JSON对象,它表示一组JWK。
x5c
属性是包含公钥的X509证书
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;
  };