Security 如果你能解码JWT,它们的安全性如何?
如果我得到一个密码,并且我可以解码有效载荷,那怎么安全呢?难道我不能从报头中取出令牌,解码并更改有效负载中的用户信息,然后用相同的正确编码秘密将其发送回去吗Security 如果你能解码JWT,它们的安全性如何?,security,jwt,express-jwt,Security,Jwt,Express Jwt,如果我得到一个密码,并且我可以解码有效载荷,那怎么安全呢?难道我不能从报头中取出令牌,解码并更改有效负载中的用户信息,然后用相同的正确编码秘密将其发送回去吗 我知道它们必须是安全的,但我真的很想了解这些技术。我遗漏了什么?JWTs可以是签名的,也可以是加密的,或者两者都可以。如果令牌已签名但未加密,则每个人都可以读取其内容,但如果您不知道私钥,则无法更改它。否则,接收者将注意到签名不再匹配 回答你的评论:我不确定我是否正确理解你的评论。可以肯定的是:你知道并理解数字签名吗?我将简要解释一个变体(
我知道它们必须是安全的,但我真的很想了解这些技术。我遗漏了什么?JWTs可以是签名的,也可以是加密的,或者两者都可以。如果令牌已签名但未加密,则每个人都可以读取其内容,但如果您不知道私钥,则无法更改它。否则,接收者将注意到签名不再匹配 回答你的评论:我不确定我是否正确理解你的评论。可以肯定的是:你知道并理解数字签名吗?我将简要解释一个变体(HMAC,它是对称的,但还有许多其他变体) 假设Alice想给Bob发送JWT。他们都知道一些共同的秘密。马洛里不知道这个秘密,但想干涉并改变JWT。为了防止这种情况发生,Alice计算
散列(有效载荷+机密)
,并将其作为签名附加
在接收消息时,Bob还可以计算散列(有效负载+机密)
以检查签名是否匹配。
但是,如果Mallory更改了内容中的某些内容,她将无法计算匹配的签名(这将是散列(newContent+secret)
)。她不知道这个秘密,也没有办法找到它。
这意味着如果她改变了什么,签名将不再匹配,Bob将不再接受JWT
让我们假设,我向另一个人发送消息{“id”:1}
,并用Hash(content+secret)
签名。(+在这里只是串联)。我使用SHA256散列函数,得到的签名是:330e7b0775561c6e95797d4dd306a150046e239986f0a133230fda0235bda8c
。现在轮到你了:扮演马洛里的角色,试着在消息上签名{“id”:2}
。你不能,因为你不知道我用了哪个秘密。如果我认为收件人知道秘密,他可以计算任何邮件的签名并检查其是否正确。您可以转到,粘贴您的令牌并阅读内容。起初,这对很多人来说是不和谐的
简而言之,JWT并不关心加密。它关心验证。也就是说,它总能得到“这个令牌的内容是否被操纵”的答案?这意味着用户对JWT令牌的操作是徒劳的,因为服务器将知道并忽略该令牌。服务器在向客户机发出令牌时根据有效负载添加签名。稍后,它将验证有效负载和匹配的签名
逻辑问题是,不关注加密内容的动机是什么
httpOnly
(Javascript无法读取),并通过加密通道(HTTPS)与服务器对话。一旦您知道服务器和客户端之间有一个安全通道,您就可以安全地交换JWT或任何您想要的东西
这与cookies本身的工作原理没有太大区别。Cookie通常包含未加密的有效负载。如果您使用HTTPS,那么一切都很好。如果您没有,那么建议您自己加密敏感cookie。不这样做意味着中间人攻击是可能的——代理服务器或ISP读取cookies,然后在以后假装是你的情况下重放它们。出于类似的原因,JWT应该始终通过HTTPS之类的安全层进行交换。json web令牌(JWT)中的内容并非天生安全,但有一个用于验证令牌真实性的内置功能。JWT是由句点分隔的三个散列。第三是签名。在公钥/私钥系统中,颁发者使用私钥对令牌签名进行签名,私钥只能通过其相应的公钥进行验证 理解颁发者和验证者之间的区别很重要。令牌的接收方负责验证令牌 在web应用程序中安全使用JWT有两个关键步骤:1)通过加密通道发送,2)在收到签名后立即验证签名。公钥密码的非对称性使得JWT签名验证成为可能。公钥验证JWT是否由其匹配的私钥签名。没有其他密钥组合可以执行此验证,因此阻止了模拟尝试。遵循这两个步骤,我们可以在数学上确定JWT的真实性
更多阅读:只有服务器上的JWT私钥才能解密加密的JWT。知道私钥的人将能够解密加密的JWT
将私钥隐藏在服务器中的安全位置,并且永远不要告诉任何人私钥。我建议使用jwt.io中没有的特殊算法对JWE进行解密 参考链接: 这个答案可能太晚了,或者你已经找到了答案,但我还是觉得这会有帮助
jwt.generate('PBES2-HS512+A256KW', 'A256GCM', payload, pwd, (error, token) => {
jwt.parse(token).verify(pwd, (error, parsedToken) => {
// other statements
});
});