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 元素,这些元素必须保密,这样就没有人可以为您签名。
我正在使用这个库 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 和指数(取自 )
生成 PEMexport 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 元素,这些元素必须保密,这样就没有人可以为您签名。