oauth-2.0 www.example.com如何http://jwt.io检索密钥伪装签名密钥?

jvlzgdj9  于 2022-10-31  发布在  其他
关注(0)|答案(4)|浏览(132)

我正在尝试使用Keycloak OAUTH服务器(7.0.11),它看起来运行得很好,但是我仍然对如何验证它生成的令牌感到困惑。例如,我生成了一个id_token并将其粘贴到http://jwt.io中,它显示了一个格式良好的有效负载和以下头部:

{
  "alg": "RS256",
  "typ": "JWT",
  "kid": "<my-key-id>"
}

它还显示“Signature Verified”,并以某种方式将有效的RSASHA 256公钥检索到jwt.io页面中的相应表单中。
我希望自己能够通过检查签名来验证令牌。我的理解是,我通过从keycloak服务器JWKS Certificate-Endpoint检索公共签名密钥来实现这一点:生成的对象包含一个密钥:

{
      "kid":"<matches-my-key-id-above>",
      "kty":"RSA",
      "alg":"RS256",
      "use":"sig",
...
      "x5c":["<snip>"],
...
}

很好,kid匹配,但是x5c中的值 * 不 * 匹配http://jwt.io显示的公钥,当我粘贴我的x5c值到它的位置时,表单说签名无效。根据https://www.rfc-editor.org/rfc/rfc7517,值应该已经是base64编码的(看起来我也是)。
不幸的是,我不能把范围缩小到一个很有针对性的问题。但是...

  • 为什么我的keycloak身份验证服务器没有报告验证令牌的密钥--特别是因为令牌中的kid与唯一的JWKS密钥匹配?
  • 如果我的头文件不包含任何jku来查询,http://jwt.io如何找到任何公钥来检查签名?

TIA各位。

hsgswve4

hsgswve41#

我发现了一个有趣的解释--但还不完全是答案--在Keycloak服务器领域服务器设置中,有一个公共密钥和一个证书。
公钥确实是验证我的访问令牌的正确值,以及jwt.io当我加载我的访问令牌时在www.example.com表单中显示的内容(仍然不知道它是如何检索的)。
证书是当我向证书端点/JWKS发出HTTP请求时返回的内容。
所以我不应该通过证书来验证我的访问令牌吗?或者有没有另一组参数可以用来通过证书而不是公钥来验证?

kmb7vmvb

kmb7vmvb2#

已解决:不久前已解决此问题,但忘记更新此主题:技巧是查询主发布者领域:https://<server>:<port>/auth/realms/<realm>,它 * 确实 * 返回域公钥:

{
  "realm": "testrealm",
  "public_key": "<THIS BIT HERE SNIPPED>",
  "token-service": "https://.../auth/realms/testrealm/protocol/openid-connect",
  "account-service": "https://.../auth/realms/testrealm/account",
  "tokens-not-before": 0
}

该公钥对所有令牌进行签名,而不是对领域JWKS端点返回的x509证书进行签名。

knpiaxh1

knpiaxh13#

我有一个描述这个过程的blog post,除了在将键粘贴到jwt.io之前用众所周知的分隔符(如下面这样的分隔符)将键括起来之外,您所做的一切听起来都是正确的。

-----BEGIN CERTIFICATE-----
token signing public key
-----END CERTIFICATE-----

当然,programmatic solutions使用的库可以自动执行这类操作。
Keycloak的密钥详细信息可能会略有不同,例如:

  • 开始/结束RSA密钥
a8jjtwal

a8jjtwal4#

jwt.io如何知道您的公钥的答案是,当您将公钥粘贴到jwt.io中时,在该页面上运行的javascript会获取并使用JWT中的iss字段

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

现在,由于您可能正在端口8080上运行本地keycloak,因此该页将在本地触发对以下URL的调用:

  • 本地主机:8080/领域/我的领域/已知的/开放ID配置 * 和 *

这些调用返回一个密钥数组,jwt.io中的页面处理这些数组,它根据jwt中定义的kid提取正确的密钥,并将该密钥的整个json部分放入解码页面的公钥部分。这就是它“知道”你的公钥的方式。
您可以尝试关闭您的本地keycloak服务器,将您的jwt粘贴到jwt.io中,然后意识到您的验证将失败。

相关问题