在给定 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 令牌
如何为 spring oauth2 jwt 服务器生成正确的 jwks 端点?
使用 Azure API 管理从身份提供者缓存 JWKS 以验证 JWT