我不明白为什么存在JWS不受保护的标头。
对于某些上下文:JWS未受保护的标头包含不受完整性保护的参数,并且只能使用带有JSON序列化的每个签名。
如果它们可以用作顶级标题,我可以看到为什么有人想要包含一个可变参数(不会改变签名)。但事实并非如此。
任何人都可以想到用例或知道为什么它们会包含在规范中吗?
谢谢!
答案 0 :(得分:4)
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。
假设Mallory用alg = RS256和keyId = XXX1设计了一个标题。现在Alice尝试验证签名并找到:
因此,爱丽丝拒绝了JWT。
假设Mallory用alg = HS256和keyId = ZZ3设计了一个标题。现在,Alice尝试验证签名并发现密钥未知,并拒绝JWT。
算法在任何情况下都不需要是签名材料的一部分。没有任何情况下,未受保护的标头会导致漏洞或违反完整性。
最初的问题是:未受保护的JWT标题的目的是什么?
简而言之,未受保护的JWS标头的目的是允许传输一些可用作提示的元数据到接收器。像alg(算法)和kid(密钥ID)。 Florent建议将数据填充到未受保护的标题中可能会提高效率。这不是一个好理由。以下是关键点:未受保护的标头中的声明是提示,不可依赖或信任。
一个更有趣的问题是:受保护的JWS标头的目的是什么?为什么有一个标志“标题”和“有效载荷”的条款?对于JWS Protected Header,标头和有效负载将连接在一起,并且结果将被签名。假设头是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