在给定 JWT 标头的情况下选择 JWKS 中的键

Posted

技术标签:

【中文标题】在给定 JWT 标头的情况下选择 JWKS 中的键【英文标题】:Selecting a key in a JWKS given a JWT header 【发布时间】:2017-01-17 14:48:11 【问题描述】:

在给定 JWS (JWT) 标头的情况下,是否有在 JWKS 密钥库中选择签名验证密钥的标准方法?

我的目标是实现 OpenID Connect ID 令牌验证库,我正在尝试灵活并预测不同的配置,但我不确定如果密钥选择是特定于 IdP 的,这样做是否有意义。

我当前的算法遍历 JWKS 并过滤掉:

    如果 JWK 有“use”字段,如果“use”不等于“sig”则拒绝 如果 JWK 有“key_ops”字段,如果“key_ops”不包含“verify”则拒绝 如果 JWK 的“alg”字段与 JWS 标头值不同,则拒绝 如果 JWS 标头有“kid”字段,如果 JWK 没有或具有不同的值,则拒绝(注意相反的逻辑) 如果在这个阶段只剩下一个 JWK,我会使用那个。否则就是失败。

这种方法“足够标准”吗?

=== 编辑 ===

我发现 OpenID Connect 核心规范中有 Section 10.1 说:

当使用 RSA 或 ECDSA 签名时,JOSE 标头的 alg 标头参数值必须设置为 JSON Web 算法 [JWA] 中定义的适当算法。用于签署内容的私钥必须与发送者在其 JWK Set 文档中发布的用于签名验证的公钥相关联。如果引用的 JWK 集合文档中有多个键,则必须在 JOSE 标头中提供一个孩子值。各个密钥的密钥用法必须支持签名。

JWK“使用”是强制性的,所以我可以安全地要求它是“签名”。

如果 JWKS 中有多个密钥,则 JWT “kid”是必需的。这表明(尽管间接地)在这种情况下 JWT “kid” 和 “JWK” 孩子应该匹配。 "kid" 不需要是唯一的,所以你仍然需要额外的规则。

【问题讨论】:

4.可能是:“如果 JWS 标头具有“kid”字段,则如果 JWK 没有或具有不同的值,则拒绝(注意相反的逻辑)”即 JWS->JWK 好地方,干杯! 【参考方案1】:

这是一种可行的方法。我认为在第 5 阶段。如果在 JWS 中没有传输 kid(第 4 步),您可能会得到多个相同类型的有效密钥。您将遍历这些密钥并将它们一次一个地传递给验证函数,以查明是否有一个成功并因此用于对消息进行签名。

【讨论】:

【参考方案2】:

我在我的项目中使用了类似的方法。 看文件https://github.com/Spomky-Labs/jose/blob/master/src/Object/BaseJWKSet.php#L169的方法selectKey

简而言之,方法排序她根据参数键入并返回第一个。

【讨论】:

以上是关于在给定 JWT 标头的情况下选择 JWKS 中的键的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Dot Net Core 中使用 JWKS 验证 JWT 令牌

什么是jwks?刷新和访问令牌的 jwks 到底是什么?

如何为 spring oauth2 jwt 服务器生成正确的 jwks 端点?

使用 Azure API 管理从身份提供者缓存 JWKS 以验证 JWT

如何使用 JwtSecurityTokenHandler 和 JWKS 端点验证 JWT?

OpenID Connect JWT 令牌验证和后端 api 的使用策略 - jwks 还是会话?