为什么在JWT头部发送算法

6
在JWT令牌中,我们在头部发送用于签名JWT的算法类型,该类型只是base64编码。任何人都可以轻松了解该算法。例如:
{ "alg":"HS256" }

为什么我们要将它发送给客户端,而客户端并不需要知道它。不发送算法会更安全吗?

算法不在客户端,而是在令牌中。它允许令牌自我描述如何验证其签名。 - Joe
@Joe 如果令牌只能用于授权单个服务,并且该服务知道使用哪种算法签署了令牌,那么将其放入令牌中向客户端公开有何意义?任何客户端都可以解码JWT并检查算法。 - Klaycon
这个问题可能在Security SE上能得到更好的答案。 - Klaycon
2个回答

3
HS256是一种签名算法,因此客户端(如您所描述的)可以在没有验证签名的情况下读取令牌的内容(除非内容被单独加密)。
确实有一个很好的观点,即如果令牌的接收者需要它,那么没有理由在令牌中发送副本。事实上,JWT的一个批评是算法包含在标头中,这导致了实现标准的库中的各种漏洞,特别是因为它包括一个none签名算法选项,如果接收者只使用JWT标头中的信息,则允许令牌的发送者完全绕过验证(有关更多信息,请参见此文章)。这也详细说明了由于弱类型签名密钥而导致的另一个漏洞。
现在通常建议令牌的验证器指定它期望使用的算法(因为在许多情况下这将是已知的),而不是依赖JWT标头中的信息。
因此,问题不在于公开有关使用的算法的信息(算法应足够强大,以使其无关紧要),而在于接收到无效算法信息,该信息可用于欺骗令牌的接收者,使其相信它是有效的,而实际上是伪造的。

2
我们为什么要将它发送给客户端?
显而易见,学究式的原因就是标准要求这样做: RFC 7515 4.1.1 此头参数必须存在,并且必须被实现理解和处理。
虽然我无法确定这一点,因为我找不到任何关于IETF会议的记录,但我相信由于历史先例,该算法是必需的。这些标准不是一夜之间自己出现的,以我们今天所知道的形式出现。相反,它们是从XML dsig技术演变而来,其中算法作为嵌入式公钥的一部分特别发送。
不发送算法更安全吗?
要求实现根据客户端输入更改行为是值得质疑的。alg头是由客户端提供的,这意味着即使它是有效的,也可以用来欺骗实现进入失败模式。在JWT标准化后不久,就利用允许客户端指示算法选择的漏洞,发生了两个关键漏洞
这是一个设计缺陷还是一个实现缺陷一直存在争议。
底线是,JOSE家族(JWTJWSJWEJWKJWA)允许实现者和用户混合和匹配加密算法,这提供了大量的用例能力。不幸的是,这也意味着用户应该非常挑剔他们的JWT库对客户端提供的算法的处理。
如果您正在寻找其他不具有这种异常(奇怪?)要求的承载令牌类型选项,请查看:

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接