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-configuration
到Issuer
。语法和.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"
Issuer
由 iss
声明表示。如果您取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 是如何知道我的公钥的?的主要内容,如果未能解决你的问题,请参考以下文章