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

Posted

技术标签:

【中文标题】JWT.io 是如何知道我的公钥的?【英文标题】:How does JWT.io already know my public key? 【发布时间】:2019-11-26 20:24:11 【问题描述】:

我的 JSON 网络令牌 (JWT):

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6InU0T2ZORlBId0VCb3NIanRyYXVPYlY4NExuWSIsImtpZCI6InU0T2ZORlBId0VCb3NIanRyYXVPYlY4NExuWSJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuYXp1cmUuY29tLyIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzcyZjk4OGJmLTg2ZjEtNDFhZi05MWFiLTJkN2NkMDExZGI0Ny8iLCJpYXQiOjE1NjM0MDY2NjQsIm5iZiI6MTU2MzQwNjY2NCwiZXhwIjoxNTYzNDEwNTY0LCJhaW8iOiI0MkZnWUJCdGZ6U3I3YnIvcDR0cWVxZGwvMndOQmdBPSIsImFwcGlkIjoiZjFmNmQ1NWUtY2YyYy00MjJkLWIxODYtODQ4NjI0ZGI5NWU4IiwiYXBwaWRhY3IiOiIyIiwiaWRwIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvNzJmOTg4YmYtODZmMS00MWFmLTkxYWItMmQ3Y2QwMTFkYjQ3LyIsIm9pZCI6ImRmOWRmZjhkLWJjYjUtNGIxNy04Y2VjLTRiZTFhMDFmOTIxMiIsInN1YiI6ImRmOWRmZjhkLWJjYjUtNGIxNy04Y2VjLTRiZTFhMDFmOTIxMiIsInRpZCI6IjcyZjk4OGJmLTg2ZjEtNDFhZi05MWFiLTJkN2NkMDExZGI0NyIsInV0aSI6ImhpMDEtOFlSdUVtTExjeE05TDN6QUEiLCJ2ZXIiOiIxLjAifQ.kwfGrWiQwqhJpZfryW9D1hHDC2AC6tUT16OXkmlIeyxTMqY0gdO0U3KClYczDzMs6kpXc5sQOBaTrBQgERnfKf1nqrHoDmHzaKmY20LKByMopH9uhcPF3lkDNW--dfruNHywF6DZ4cLtgSWcZOBs_BAwQqy1i5Hja7WNf5InyhyscXjUdntIz9rK599IzvD8MwkgYViMEXATNNh2CvEqRp-AZxVjCP_cI6h9Lx3j8__9xRIoWIwnv_rqHGcPpg6hJMfUJMtlLjJaBo0h0veCCZj-fUORidN7EPHNSw9IJF29-nGhw6rmkcD7F8q6WpK8dUfiYGk_QxOCRTw9gpkKKA

当我将此令牌粘贴到jwt.io 时,它会自动填写一个公钥,并说令牌上的签名已经过验证。它是如何知道公钥的?

【问题讨论】:

【参考方案1】:

来自智威汤逊最佳实践(RFC 8725):

确定发行者拥有的密钥的方法是应用程序- 具体的。例如,OpenID Connect 颁发者值 是 https 引用 JSON 元数据文档的 URL,其中包含 一个 jwks_uri 值,它是一个 https URL,发行者的密钥来自该 URL 被检索为 JWK 集 (RFC 7517)。同样的机制被 ietf-oauth-discovery。其他应用程序可能使用不同的 将密钥绑定到发行者的方法。

OpenID Connect (OIDC) 提供程序元数据位置记录在 OIDC Discovery 规范中

支持发现的 OpenID 提供者必须制作 JSON 文档 在连接字符串形成的路径上可用 /.well-known/openid-configurationIssuer。语法和 .well-known 的语义在 RFC 5785 中定义并应用 到Issuer 值,当它不包含路径组件时。

您的令牌的有效负载是


  "aud": "https://management.azure.com/",
  "iss": "https://sts.windows.net/72f988bf-86f1-41af-91ab-2d7cd011db47/",
  "iat": 1563406664,
  "nbf": 1563406664,
  "exp": 1563410564,
  "aio": "42FgYBBtfzSr7br/p4tqeqdl/2wNBgA=",
  "appid": "f1f6d55e-cf2c-422d-b186-848624db95e8",
  "appidacr": "2",
  "idp": "https://sts.windows.net/72f988bf-86f1-41af-91ab-2d7cd011db47/",
  "oid": "df9dff8d-bcb5-4b17-8cec-4be1a01f9212",
  "sub": "df9dff8d-bcb5-4b17-8cec-4be1a01f9212",
  "tid": "72f988bf-86f1-41af-91ab-2d7cd011db47",
  "uti": "hi01-8YRuEmLLcxM9L3zAA",
  "ver": "1.0"

Issueriss 声明表示。如果您取iss 的值,将/.well-known/openid-configuration 附加到它,然后将resulting URL 弹出到您的浏览器中,您将看到OIDC Provider 元数据。此元数据文档中的一个键是 jwks_uri,它指向另一个具有 JSON Web 键集的文档。后者是一组 JSON Web Keys (JWK)。 JWK 是加密密钥的 JSON 表示。为了识别集合中所需的 JWK,使用了来自相关令牌的声明 x5t(X.509 证书的 SHA-1 指纹)和/或 kid(密钥 ID/别名/名称)。

jwt.io 通过基于iss 声明提取 OIDC 元数据,成功地在整个序列的第一步作弊。如果 JWT 是由不支持 OpenID Connect 和/或未实现所有这些相关规范的服务发布的,jwt.io 将无法找到验证签名的密钥。

【讨论】:

谢谢!我正在尝试在 C++ 中实现一些东西来验证某些 JWT 令牌,这会有所帮助。 答案的最后一行包含重要信息:“如果 JWT 是由不使用 OpenID Connect 和/或未实现所有这些相关规范(OIDC 规范)的服务发布的, jwt.io 不会找到验证签名的密钥。”

以上是关于JWT.io 是如何知道我的公钥的?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 JWT.IO 网站创建 RS256 JWT?

在 C# 中使用 RS256(非对称)验证 JWT

使用 RS256 生成的 JWT 可以被 jwt.io 网站解码吗?

如何生成与 JWT.IO 网站相同的签名?

在 JWT.IO 中验证签名

如何保护 JWT 令牌