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

Posted

技术标签:

【中文标题】jwt.io 从哪里获取 JWT 令牌的公钥?【英文标题】:Where does jwt.io get the public key from JWT token? 【发布时间】:2021-01-25 13:11:11 【问题描述】:

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

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

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

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

解码消息(再次截断)

标题


  "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"  

在那里,可以看到公钥(截断)


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

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

【问题讨论】:

我认为您不需要密钥来解码 JWT 令牌。它们都遵循行业标准RFC 7519,任何人都可以解码。由于您没有在令牌中传递任何敏感信息,因此这不是风险(除非您让它被知道如何使用它登录您的帐户的人窃取)。有很多解码器可以做同样的事情jwt-decode、jwt-auth等。 密钥当然不是用来解码token的,而是用来验证签名的。令牌本身只是 base64url 编码的。 【参考方案1】:

令牌包含令牌的颁发者(iss)和密钥id(kid),它标识了验证签名所需的公钥 使用此信息,jwt.io 可以在 JWKS 端点 (/.well-known/jwks.json) 上以 JWK (JSON Web Key) 的形式找到公钥,以验证令牌。 JWKS (JSON Web Key Set) 包含一个 JWK 数组,链接显示了一个示例。

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

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

【讨论】:

所以如果我理解正确的话,它来自“kid”和“iss”,它会获取公钥来验证 JWT 令牌的签名吗? Cognito 是否必须在令牌中提供这些详细信息?如果可能的话,你能详细说明一下吗?【参考方案2】:

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

在我看来,问题是:

"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。 拥有该公钥,jwt.io 可以验证令牌。至少我认为是这样的。

【讨论】:

哈哈哈。是的,这正是发生的事情。为此 +1

以上是关于jwt.io 从哪里获取 JWT 令牌的公钥?的主要内容,如果未能解决你的问题,请参考以下文章

JWT.io 是如何知道我的公钥的?

如何使用 jwt.io 手动验证从自定义授权服务器获得的令牌?

使用 .NET Core 中的公共安全密钥配置 JWT Bearer 令牌验证

编程实践Go 实现 JWT以及将其用作中间件的方式

使用 jsonwebtoken 库生成的 JWT 令牌在 jwt.io 中提供了无效签名

如何验证在 jwt.io 上使用 Keycloak 身份验证提供程序创建的 HS256 签名 JWT 令牌