The answer by Florent 让我不满意。
关于使用 JWT 签署文档哈希的示例......断言是算法和 keyID 将是需要“保护”的“敏感数据”。我想他的意思是“签名”。但是不需要对算法和keyID签名。
示例
假设 Bob 创建了一个签名的 JWT,其中包含一个断言 alg=HS256 和 keyid=XXXX1 的不受保护的标头。此 JWT 旨在传输给 Alice。
案例一
假设 Mallory 截获 Bob 发送的签名 JWT。 Mallory 然后创建一个新的不受保护的标头,断言 alg=None。
接收者 (Alice) 现在负责验证有效负载上的签名。爱丽丝一定不能满足于“没有签名”;事实上Alice must not rely on a client (sender) assertion to determine which signing algorithm is acceptable for her。因此,Alice 拒绝了带有人为的“无签名”标头的 JWT。
案例2
假设 Mallory 设计了一个带有 alg=RS256 和 keyId=XXX1 的标头。现在 Alice 尝试验证签名并发现:
因此 Alice 拒绝了 JWT。
案例3
假设 Mallory 设计了一个带有 alg=HS256 和 keyId=ZZ3 的标头。现在 Alice 尝试验证签名并发现密钥未知,并拒绝 JWT。
在任何情况下,算法都不需要成为签名材料的一部分。没有不受保护的标头会导致漏洞或违反完整性的情况。
回到最初的问题
最初的问题是:未受保护的 JWT 标头的目的是什么?
简而言之,未受保护的 JWS 标头的目的是允许传输一些可用作接收者提示的元数据。像 alg(算法)和 Kid(密钥 ID)。 Florent 建议将数据填充到未受保护的标头中可能会提高效率。这不是一个很好的理由。这是关键点:未受保护的标头中的声明是提示,不可依赖或信任。
一个更有趣的问题是:受保护的 JWS 标头的目的是什么?为什么有一个同时签署“标题”和“有效载荷”的条款?在 JWS 受保护的标头的情况下,标头和有效负载将连接起来,并对结果进行签名。假设标头是 JSON,有效负载是 JSON,此时标头和有效负载之间没有语义区别。那么,为什么要规定要在标头上签名呢?
可以只依靠带有不受保护的标头的 JWS。如果需要完整性保护声明,请将它们放入有效负载中。如果需要提示,请将它们放在未受保护的标题中。签署有效载荷而不是标头。很简单。
这是有效的,并且是有效的。但它假定有效负载是 JSON。 JWT 是这样,但并非所有 JWS 都是如此。 RFC 7515, which defines JWS,不需要签名的有效负载是 JSON。想象一下,有效载荷是医学扫描的数字图像。这不是 JSON。不能简单地“附加要求”。因此,JWS 允许使用受保护的标头,以便可以对(非 JSON)有效负载和任意声明进行签名并检查完整性。
在负载为非 JSON 且标头受保护的情况下,无法在 JWS 中包含“额外的非签名标头”。如果需要发送一些需要完整性检查的数据和一些简单的“提示”,那么实际上只有一个容器:受保护的标头。并且提示会与真实声明一起签署。
只需将 JSON 散列包裹在要签名的数据周围,就可以避免使用这种受保护的标头技巧。例如:
{
"image" : "qw93u9839839...base64-encoded image data..."
}
在这样做之后,可以向这个 JSON 包装器添加声明。
{
"image" : "qw93u9839839...base64-encoded image data..."
"author" : "Whatever"
}
然后这些声明将被签名并受到完整性保护。
但在二进制数据的情况下,将其编码为字符串以允许封装到 JSON 中可能会使数据显着膨胀。带有非 JSON 有效负载的 JWS 可以避免这种情况。
HTH