您什么时候使用不受保护的JWS标头?

mar*_*rkw 5 jwt json-web-token jose json-web-signature

我不明白为什么存在JWS不受保护的头文件.

对于某些上下文:JWS未受保护的头包含不受完整性保护的参数,并且只能使用带有JSON序列化的每个签名.

如果它们可以用作顶级标题,我可以看到为什么有人想要包含一个可变参数(这不会改变签名).然而,这种情况并非如此.

任何人都可以想到一个用例或知道为什么它们被包含在规范中?

谢谢!

JWS Spec

Che*_*eso 6

弗洛朗的回答让我不满意。

关于使用 JWT 对文档的哈希进行签名的示例......断言是算法和 keyID 将是需要“保护”的“敏感数据”。我想他的意思是“签名”。但是不需要对算法和 keyID 进行签名。

例子

假设 Bob 创建了一个签名的 JWT,其中包含一个声明 alg=HS256 和 keyid=XXXX1 的不受保护的标头。此 JWT 旨在传输给 Alice。

情况1

假设 Mallory 拦截了 Bob 发送的签名 JWT。Mallory 然后创建一个新的不受保护的标头,断言 alg=None。

接收者(Alice)现在负责验证有效载荷上的签名。Alice一定不能满足于“没有签名”;事实上,Alice 不能依赖客户端(发送者)断言来确定她可以接受哪种签名算法。因此,Alice 拒绝带有人为的“无签名”标头的 JWT。

案例二

假设 Mallory 设计了一个带有 alg=RS256 和 keyId=XXX1 的标头。现在 Alice 尝试验证签名并找到:

  • 算法不合规
  • 为该算法指定的密钥不存在

因此 Alice 拒绝了 JWT。

案例3

假设 Mallory 设计了一个带有 alg=HS256 和 keyId=ZZ3 的标头。现在 Alice 尝试验证签名并发现密钥未知,并拒绝了 JWT。

在任何情况下,算法都不需要成为签名材料的一部分。不存在未受保护的标头导致漏洞或完整性破坏的情况。

回到最初的问题

最初的问题是:未受保护的 JWT 标头的目的是什么?

简而言之,不受保护的 JWS 标头的目的是允许传输某些元数据,这些元数据可用作对接收者的提示。像alg(算法)和kid(密钥ID)。Florent 建议将数据填充到不受保护的标头中可以提高效率。这不是一个很好的理由。这里是关键点:未受保护的标头中的声明是提示,不可依赖或信任。

一个更有趣的问题是:受保护的 JWS 标头的目的是什么?为什么要同时签署“标头”和“有效载荷”?对于 JWS 受保护的标头,标头和有效负载连接在一起,并对结果进行签名。假设header是JSON,payload是JSON,此时header和payload之间没有语义区别。那么为什么要在标题上签名呢?

一个人可以依靠带有不受保护的标头的 JWS。如果需要完整性保护声明,请将它们放入有效负载中。如果需要提示,请将它们放在不受保护的标题中。签署有效载荷而不是标头。简单的。

这有效,并且有效。但它假定有效负载是 JSON。JWT 是这样,但并非所有 JWS 都如此。 定义 JWS 的 RFC 7515不要求签名的有效负载为 JSON。想象一下,有效载荷是医学扫描的数字图像。它不是 JSON。人们不能简单地“附加声明”。因此 JWS 允许受保护的标头,这样(非 JSON)有效负载和任意声明可以被签名和完整性检查。

在负载为非 JSON 且标头受保护的情况下,无法将“额外的非签名标头”包含到 JWS 中。如果需要发送一些需要完整性检查的数据和一些只是“提示”的数据,那么实际上只有一个容器:受保护的标头。提示与真实声明一起签名。

只需在要签名的数据周围包装一个 JSON 散列,就可以避免使用这种受保护的标头技巧。例如:

{
   "image" : "qw93u9839839...base64-encoded image data..."
}
Run Code Online (Sandbox Code Playgroud)

这样做之后,就可以向这个 JSON 包装器添加声明。

{
   "image" : "qw93u9839839...base64-encoded image data..."
   "author" : "Whatever"
}
Run Code Online (Sandbox Code Playgroud)

然后将签署这些声明并保护其完整性。

但在二进制数据的情况下,将其编码为字符串以允许封装到 JSON 中可能会显着增加数据。具有非 JSON 负载的 JWS 避免了这种情况。

HTH