jwt.io 从哪里获取 JWT 令牌的 public 密钥?

Where does jwt.io get the public key from JWT token?

我正在通过 jwt.io(在调试器部分)解码 JWT 令牌以查看 Headers、有效负载。令人惊讶的是,它也得到了验证,我可以看到它(jwt.io 调试器)也能够检索 public 密钥。

所以我的问题是:JWT 令牌是否提供 public 密钥以及 JWT 令牌的一部分?

我正在粘贴其中的一部分(由于安全原因无法粘贴完整,将截断实际 JWT 令牌的一部分)

F3cy5jb21cL2V1LXdlc3QtMV9ZckVRYjY5Z1giLCJleHAiOjE2MDE2Mzg4OTMsImlhdCI6MTYwMTYzNTI5MywidmVyc2lvbiI6MiwianRpIjoiNmI2YmZiNmYtY2M0MS00N2Q5LWI0YzYtOTBmOGFmNWM2MjQ1IiwiY2xpZW50X2lkIjoiMTM0MWxxa3N1ZmUwbm1vaW9kdnRjc2t2cWIifQ.RtKfz54uBgSZ1gc4KRPjzL4dPe5AbH2YMJu-DDvIxBzgMjqT9q4ApGzcWYB62-MgDUf-F_hK0kF9eIwAi9fARhp 0HGGnyiuydW_our6zE3EphLvXQByTDY5xzOUuSvt7WbDZWeSfpHcjrBttRSJAPOsZ2gInafKjZgWKyGL4vJB9swEhOMSSpTQDGWKenJCyp4emhe8E4XGzYTo9WEb-Wqg6sI__LrusDNd917FaocPKBxA

解码消息(再次截断)

Headers

{
  "kid": "cJ0PzkBXPyjX7FM67jcOECIY=",
  "alg": "RS256"
}

有效负载:

{
  "sub": "13lqs0moiodvtcskvqb",  
  "token_use": "access",  
  "scope": "example.com/Manage",  
  "auth_time": 1601293,  
  "iss": "https://cognito.eu.amazonaws.com/",  
  "exp": 1601638,  
  "iat": 10353,  
  "version": 2,  
  "jti": "cc1-47d9-b6-5c6245",  
  "client_id": "nmodvtcb"  
}

在那里,可以看到Public键(截断)


-----BEGIN PUBLIC KEY-----
QEFAAOCAQ8AMIIBCxmf9bakWk
556KYmIZB+Sy1ftkkGa4qlUsmRvcG2Hll+7HBWp1ao6MVLskjdaaKg8iH1Iz4DKG
lgqT/ndwhoxvTBuvm0X2CZoNzZn4S8wDTr78m/S/YegZRhv6y58gkiKSEmbbC/g5
Bp+AF88NwBvLm1jdd
-----END PUBLIC KEY-----

jwt.io 中的调试器从哪里检索 public 密钥?我无法理解这一点。

令牌包含令牌的发行者(iss)和密钥id(kid),它标识了验证签名所需的public密钥 有了这些信息,jwt.io 可以找到 JWK 形式的 public 键(JSON Web Key) on a JWKS endpoint (/.well-known/jwks.json), to verify the token. A JWKS (JSON Web Key Set)包含一个 JWK 数组,link 显示了一个例子。

根据 cognito documentation,当您使用 Amazon 用户池对您的用户进行身份验证时,将使用此机制。

通过 jwks 端点提供密钥是一种标准机制,其他提供商也使用该机制,例如微软 Azure。

我自己也一直在努力理解这一点。如果您打开开发人员工具并在将令牌粘贴到调试器页面时看到 jwt.io 发出的请求,您会看到它发出了额外的请求。

在我看来,iss 是:

"iss": "http://localhost:8080/auth/realms/myrealm"

因此 jwt.io 添加了标准路径 /.well-known/openid-configuration 并向

发出了 XHR 请求
http://localhost:8080/auth/realms/myrealm/.well-known/openid-configuration

它在json中找到了很多信息,其中有jwks_uri

{
...
"jwks_uri": "http://localhost:8080/auth/realms/myrealm/protocol/openid-connect/certs",
...
}

然后对上述 url 发出了另一个 XHR 请求,响应是 jwks。 有了 public 密钥,jwt.io 就可以验证令牌。至少我是这么认为的。