为啥在 JWT Token 中包含 Header 和 Payload?
Posted
技术标签:
【中文标题】为啥在 JWT Token 中包含 Header 和 Payload?【英文标题】:Why Include Header and Payload in JWT Token?为什么在 JWT Token 中包含 Header 和 Payload? 【发布时间】:2020-08-20 18:22:52 【问题描述】:我确定我在这里遗漏了一些非常简单的东西,但我刚刚开始学习用于身份验证的 JWT 令牌,据我了解,JWT 令牌的结构是:
Base64UrlEncode(Header) + '.' + Base64UrlEncode(Payload) + '.' + CreateSignature(Header, Payload, Secret_Key)
我的理解是您将其发送给客户端,它允许客户端在需要时将其发送回服务器。此时您解密签名以确保它没有被您的私钥篡改。
我感到困惑的部分是为什么您需要Base64UrlEncode(Header) + '.' + Base64UrlEncode(Payload) + '.'
的第一部分,那么它很容易转换回纯文本?
由于您将在服务器上对其进行解密,难道您不能只传递签名,使用您的密钥解密并读取有效负载,而其他人无法做到吗?
这似乎更安全,因为第一部分可以很容易地转换回纯文本,并向攻击者提供存储在有效负载中的信息,例如token expiration
、userId
等。
我错过了什么?
【问题讨论】:
【参考方案1】:签名不包含有效负载。签名可以像 jwt 的哈希 (SHA256) 的消息验证码 (HMAC) 一样简单。因此,如果您只发送签名,它将作为普通的旧会话 id 工作,并且服务器仍然必须存储状态,从而否定 jwt 的任何好处。
你是对的,默认情况下 jwt 是不加密的。虽然使用 base64 编码,但从安全角度来看,它只是纯文本,不应包含敏感(秘密)信息。签名提供的唯一保护是,当服务器接收到它时,它可以通过检查签名来确保 jwt 中的信息在客户端没有被更改。
未加密的令牌允许客户端检查其内容并找出例如到期时间、何时必须获取新令牌或登录用户的 ID。拥有 jwt 的用户无论如何都会拥有这种信息,而其他人不应该拥有 jwt,因为他们可以使用它进行身份验证来冒充用户。
但是,在特殊情况下,您可能仍希望包含您希望在服务器上接收回但又不想透露给客户端的敏感信息(即机密)。为此,您可以使用加密的 jwt (jwe)。缺点是这个令牌对客户端来说是不透明的,您可能必须实现应用程序端点来检索所有必要的信息。
【讨论】:
谢谢你,加博尔。我仍然感到困惑的部分是我知道拥有未加密的数据允许客户端拥有一些信息,但对我来说似乎更可怕的部分是这将由客户端存储,如果黑客甚至收到一个过期的令牌,他们可能会有诸如用户名或用户名之类的信息。我只是不明白为什么您甚至会费心将其作为安全令牌的一部分包含在内,而不仅仅是拥有一个来回传递的完全加密的令牌(我猜您提到的就是 JWE)。我只是没有得到好处。 就像我说的,我只是不明白为什么它会成为 JWT 约定的一部分,而不是仅仅加密最后一部分并制作前两部分,至少,选择而不是约定。但是,真的,非常感谢你的澄清!!! 单页 javascript 应用程序通常受益于拥有纯文本数据,因为它们可以节省到服务器的往返时间以获取例如令牌生命周期或用户 ID。如果不使用它,您实际上可以选择加密的 jwt,这不仅仅是最后一部分,因为最后一部分只是一个可能的固定长度消息身份验证代码(或签名,取决于选择的算法)。与此相反,在加密的 jwt 中,整个 jwt(实际数据)都是加密的。 所以是的,你是对的,如果客户端不需要来自 jwt 的任何数据(不是典型情况),那么加密的 jwt 可能更安全。然而,反对什么? jwt 中包含的典型数据并不是很敏感,例如在大多数应用程序中与实际用户共享用户 ID 是可以的。另一方面,加密会耗费资源——事实上相当多。此外,这将始终通过 https 发送 - 攻击者甚至无法轻松访问过期的 jwt,从而限制了风险。 完全同意。我想这似乎违反直觉,但我确实知道黑客获得 JWT 是一件坏事,无论如何 :) 非常感谢您的时间和解释!以上是关于为啥在 JWT Token 中包含 Header 和 Payload?的主要内容,如果未能解决你的问题,请参考以下文章