为什么AWS Cognito对JWT使用多个公钥? [英] Why does AWS Cognito use multiple public keys for JWTs?
本文介绍了为什么AWS Cognito对JWT使用多个公钥?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
JSON包含2个密钥。我为池创建的所有用户似乎只使用其中一个键。
每个用户池有多个密钥的原因是什么?
推荐答案
Amazon Cognito为每个用户池生成两对RSA加密密钥。其中一个私钥用于对令牌进行签名。
这大概是出于安全原因。从有限的反复试验可以看出,一个用于加密id令牌,另一个用于加密访问令牌。或者其目的可能是支持密钥轮换(正如@Michael-sqlbot所建议的那样)。
一旦您理解了为什么(或不理解),问题就变成了如何处理这两个键。
再次参考文档,要验证JWT签名,您需要:
- 解码ID令牌
- 比较本地密钥ID(KID)和公共KID
- 使用公钥通过您的JWT库验证签名。
必须执行步骤1和2才能确定使用了哪个RSA加密密钥来加密您的JWT。
import jsonwebtoken from 'jsonwebtoken'
import jwkToPem from 'jwk-to-pem'
const jsonWebKeys = [ // from https://cognito-idp.us-west-2.amazonaws.com/<UserPoolId>/.well-known/jwks.json
{
"alg": "RS256",
"e": "AQAB",
"kid": "ABCDEFGHIJKLMNOPabc/1A2B3CZ5x6y7MA56Cy+6ubf=",
"kty": "RSA",
"n": "...",
"use": "sig"
},
{
"alg": "RS256",
"e": "AQAB",
"kid": "XYZAAAAAAAAAAAAAAA/1A2B3CZ5x6y7MA56Cy+6abc=",
"kty": "RSA",
"n": "...",
"use": "sig"
}
]
function validateToken(token) {
const header = decodeTokenHeader(token) // {"kid":"XYZAAAAAAAAAAAAAAA/1A2B3CZ5x6y7MA56Cy+6abc=", "alg": "RS256"}
const jsonWebKey = getJsonWebKeyWithKID(header.kid)
verifyJsonWebTokenSignature(token, jsonWebKey, function(err, decodedToken) {
if (err) {
console.error(err)
} else {
console.log(decodedToken)
}
})
}
function decodeTokenHeader(token) {
const [headerEncoded] = token.split('.')[0]
const buff = new Buffer(headerEncoded, 'base64')
const text = buff.toString('ascii')
return JSON.parse(text)
}
func getJsonWebKeyWithKID(kid) {
for (let jwk of jsonWebKeys) {
if (jwk.kid == kid) {
return jwk
}
}
return null
}
function verifyJsonWebTokenSignature(token, jsonWebKey, clbk) {
const pem = jwkToPem(jsonWebKey)
jsonwebtoken.verify(token, pem, { algorithms: ['RS256'] }, function(err, decodedToken) {
return clbk(err, decodedToken)
})
}
validateToken('xxxxxxxxx.XXXXXXXX.xxxxxxxx')
这篇关于为什么AWS Cognito对JWT使用多个公钥?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文