2

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

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

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

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

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

=== 编辑 ===

我发现OpenID Connect 核心规范的第 10.1 节说:

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

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

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

4

2 回答 2

0

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

于 2016-09-12T14:12:59.373 回答
0

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

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

于 2016-09-10T09:37:21.243 回答