Pix*_*ach 252 security jwt express-jwt
我爱JWT.合作真的很有趣.我的问题是:如果我得到JWT并且我可以解码有效载荷,那么它是如何安全的?我不能只是从标题中获取令牌,解码并更改有效负载中的用户信息,并使用相同的正确编码密码将其发回?
我知道他们必须是安全的,但我真的很想了解这些技术.我错过了什么?谢谢!
Mis*_*sch 327
JWT可以是签名,加密或两者兼而有之.如果令牌已签名但未加密,则每个人都可以读取令牌的内容,但是当您不知道私钥时,您无法更改它.否则,接收方将注意到签名将不再匹配.
回答你的评论:我不确定我是否以正确的方式理解你的评论.只是为了确定:你知道并理解数字签名吗?我将简要解释一个变体(HMAC,它是对称的,但还有很多其他变体).
让我们假设Alice想要向Bob发送JWT.他们都知道一些共同的秘密.马洛里不知道这个秘密,但想干涉和改变JWT.为了防止这种情况,Alice计算Hash(payload + secret)
并将其作为签名附加.
收到消息时,Bob还可以计算Hash(payload + secret)
以检查签名是否匹配.但是,如果Mallory在内容中有所改变,她就无法计算匹配的签名(这将是Hash(newContent + secret)
).她不知道这个秘密,也无法找到它.这意味着如果她改变某些东西,签名将不再匹配,Bob将不再接受JWT.
我们假设,我向另一个人发送消息{"id":1}
并签名Hash(content + secret)
.(+只是这里的连接).我使用SHA256 Hash函数,我得到的签名是:330e7b0775561c6e95797d4dd306a150046e239986f0a1373230fda0235bda8c
.现在轮到你了:扮演Mallory的角色并尝试签署消息{"id":2}
.你不能,因为你不知道我使用了哪个秘密.如果我认为收件人知道秘密,他可以计算任何邮件的签名并检查它是否正确.
Lor*_*ord 127
让我们从头开始讨论:
JWT 是一种非常现代、简单和安全的方法,它扩展了 Json Web 令牌。Json Web Tokens 是一种无状态的身份验证解决方案。因此不需要在服务器上存储任何会话状态,这对于 RESTful API 来说当然是完美的。Restful API 应该始终是无状态的,使用 JWT 进行身份验证的最广泛使用的替代方法是仅使用会话将用户的登录状态存储在服务器上。但是当然没有遵循 RESTful API 应该是无状态的原则,这就是像 JWT 这样的解决方案变得流行和有效的原因。
所以现在让我们知道身份验证实际上是如何与 Json Web Tokens 一起工作的。假设我们的数据库中已经有一个注册用户。因此,用户的客户端首先使用用户名和密码发出 post 请求,然后应用程序检查用户是否存在以及密码是否正确,然后应用程序将为该用户生成唯一的 Json Web Token。
令牌使用创建的秘密字符串被存储在服务器上。接下来,服务器然后将该 JWT 发送回客户端,客户端将其存储在 cookie 或本地存储中。
就像这样,用户通过身份验证并基本上登录到我们的应用程序,而不会在服务器上留下任何状态。
所以服务器实际上并不知道哪个用户实际登录了,但是当然,用户知道他已经登录了,因为他有一个有效的 Json Web Token,这有点像访问应用程序受保护部分的护照。
再说一次,只是为了确保你有这个想法。用户在取回他唯一的有效 Json Web 令牌后立即登录,该令牌未保存在服务器上的任何位置。所以这个过程是完全无状态的。
然后,每次用户想要访问受保护的路线时,例如他的用户配置文件数据。他将他的 Json Web 令牌与请求一起发送,因此这有点像出示他的护照以访问该路线。
一旦请求到达服务器,我们的应用程序就会验证 Json Web Token 是否真的有效,以及用户是否真的是他所说的那个人,那么请求的数据将被发送到客户端,如果不是,那么就会有是一个错误,告诉用户他不被允许访问该资源。
所有这些通信都必须通过 https 进行,因此安全加密 Http 以防止任何人可以访问密码或 Json Web 令牌。只有这样,我们才有一个真正安全的系统。
所以 Json Web Token 看起来像这个截图的左边部分,它是从 jwt.io 的 JWT 调试器中截取的。所以本质上,它是一个由三部分组成的编码字符串。标头、有效载荷和签名 现在标头只是关于令牌本身的一些元数据,有效载荷是我们可以编码到令牌中的数据,任何我们真正想要的数据。所以我们想要在这里编码的数据越多,JWT 就越大。无论如何,这两部分只是将被编码但未加密的纯文本。
所以任何人都可以解码和阅读它们,我们不能在这里存储任何敏感数据。但这根本不是问题,因为在第三部分,所以在签名中,事情才真正变得有趣。签名是使用标头、有效负载和保存在服务器上的秘密创建的。
然后整个过程称为签署 Json Web Token。签名算法采用标头、有效载荷和秘密来创建唯一的签名。所以只有这些数据加上秘密才能创建这个签名,好吗?然后与标头和有效负载一起,这些签名形成 JWT,然后将其发送到客户端。
一旦服务器收到 JWT 以授予对受保护路由的访问权限,它需要对其进行验证以确定用户是否真的是他所声称的人。换句话说,它将验证是否没有人更改令牌的标头和有效载荷数据。同样,此验证步骤将检查是否没有第三方实际更改 Json Web 令牌的标头或有效负载。
那么,这种验证实际上是如何工作的呢?嗯,它实际上很简单。收到 JWT 后,验证将获取其标头和有效载荷,并与仍保存在服务器上的机密一起,基本上创建一个测试签名。
但是最初创建 JWT 时生成的原始签名仍在令牌中,对吗?这就是这个验证的关键。因为现在我们要做的就是将测试签名与原始签名进行比较。如果测试签名与原始签名相同,则说明payload和header没有被修改。
因为如果它们被修改了,那么测试签名就必须不同。因此,在没有更改数据的情况下,我们可以对用户进行身份验证。当然,如果两个签名实际上不同,那么这意味着有人篡改了数据。通常通过尝试更改有效负载。但是,操纵有效载荷的第三方当然无权访问秘密,因此他们无法签署 JWT。所以原始签名永远不会对应于被操纵的数据。因此,在这种情况下,验证将始终失败。这是使整个系统工作的关键。正是这种魔力使 JWT 如此简单,但又极其强大。
ale*_*emb 116
您可以转到jwt.io
,粘贴您的令牌并阅读内容.这对最初的很多人来说都很不利.
简短的回答是JWT不关心加密.它关心验证.也就是说,它总能得到"让这个令牌的内容被操纵"的答案?这意味着用户操纵JWT令牌是徒劳的,因为服务器将知道并忽略令牌.在向客户端发出令牌时,服务器会根据有效负载添加签名.稍后它会验证有效负载和匹配签名.
逻辑问题是不加密内容的动机是什么?
最简单的原因是因为它假设这在很大程度上是一个已解决的问题.例如,如果处理像Web浏览器这样的客户端,您可以将JWT令牌存储在一个cookie中secure
(无法通过Javascript读取,无法通过HTTP读取)并通过加密通道与服务器通信( HTTPS).一旦您知道服务器和客户端之间有安全通道,就可以安全地交换JWT或其他任何您想要的东西.
这样可以保持简单.一个简单的实现使得采用更容易,但它也让每个层都做它最擅长的事情(让HTTPS处理加密).
JWT并不意味着存储敏感数据.一旦服务器收到JWT令牌并对其进行验证,就可以在其自己的数据库中查找用户ID,以获取该用户的其他信息(如权限,邮政地址等).这使JWT的尺寸变小,避免了无意中的信息泄漏,因为每个人都知道不要在JWT中保留敏感数据.
它与饼干本身的工作方式并无太大差别.Cookie通常包含未加密的有效负载.如果您使用HTTPS,那么一切都很好.如果您不是,那么建议您自己加密敏感cookie.不这样做意味着可能发生中间人攻击 - 代理服务器或ISP读取cookie,然后假装是你,然后重放它们.出于类似的原因,JWT应始终通过HTTPS等安全层进行交换.
Bat*_*ses 16
需要注意的是,JWT 用于授权而不是身份验证。
因此,只有在服务器通过指定凭据对您进行身份验证后,才会为您创建 JWT。创建 JWT 后,所有未来与服务器的交互都可以使用 JWT。因此,JWT 告诉服务器该用户已通过身份验证,如果他具有该角色,就让他访问特定资源。
JWT 有效负载中的信息对每个人都是可见的。可能存在“中间人”攻击,并且 JWT 的内容可能会被更改。因此,我们不应该在有效负载中传递任何敏感信息,例如密码。如果我们想让有效负载数据更安全,我们可以对其进行加密。如果有效负载被篡改,服务器将识别它。
因此,假设用户已通过身份验证并获得了 JWT。生成的 JWT 具有指定Admin角色的声明。签名也是通过以下方式生成的
此 JWT 现在已被篡改,假设角色更改为超级管理员
,那么当服务器收到此令牌时,它将再次使用密钥(只有服务器拥有)和有效负载生成签名。它与 JWT 中的签名不匹配。这样服务器就会知道JWT已经被篡改了。
转自我的博客文章 - JWT 结构和安全性
Thi*_*ark 15
json Web令牌(JWT)中的内容本身并不安全,但有一个用于验证令牌真实性的内置功能.JWT是由句点分隔的三个哈希.第三是签名.在公钥/私钥系统中,发行者使用私钥对令牌签名进行签名,该私钥只能通过其对应的公钥进行验证.
理解发行者和验证者之间的区别非常重要.令牌的接收者负责验证它.
在Web应用程序中安全地使用JWT有两个关键步骤:1)通过加密通道发送它们,以及2)在收到签名后立即验证签名.公钥加密的非对称性使得JWT签名验证成为可能.公钥验证JWT是否由其匹配的私钥签名.没有其他密钥组合可以执行此验证,从而防止模拟尝试.按照这两个步骤,我们可以保证数学上确定JWT的真实性.
更多阅读:公钥如何验证签名?
小智 6
我会用一个例子来解释这一点。
假设我向你借了 10 美元,然后我给了你一张有我签名的借据。每当您或其他人将这个借据还给我时,我都会偿还您,我会检查签名以确保那是我的。
我不能保证你不把这个借条的内容给任何人看,甚至不给第三人,我只关心这个借条是我签的,当有人给我看这个借条让我看的时候付钱。
JWT 的工作方式完全相同,服务器只能确保收到的令牌是自己发出的。
您需要其他措施来确保其安全,例如使用 HTTPS 传输加密、确保存储令牌的本地存储是安全的、设置源。