如果我有一个JWT,我可以解码有效载荷,这是安全的吗?难道我不能从报头中获取令牌,解码并更改有效负载中的用户信息,然后用相同的正确编码的秘密将其发送回来吗?

我知道它们一定很安全,但我真的很想了解这些技术。我错过了什么?


当前回答

我不是密码学专家,因此(我希望)我的回答可以帮助那些既不是密码学专家的人。

在编程中使用密码学有两种可能的方式:

签署/验证 加密/解密

当我们希望确保数据来自可信来源时,我们使用签名。 当我们想要保护数据时,我们使用加密。

签名/验证使用非对称算法,即我们使用一个密钥(私有)进行签名,而数据接收者使用另一个(公共)密钥进行验证。

对称算法使用相同的密钥对数据进行加密和解密。

加密可以使用对称和非对称算法。 相对简单的文章主题

以上是常识,以下是我的观点。

当JWT用于简单的客户端到服务器标识时,不需要签名或非对称加密。JWT可以使用AES加密,这是快速和超级安全的。如果服务器可以解密它,这意味着服务器是加密它的人。

总结:未加密的JWT是不安全的。在没有第三方参与的情况下,可以使用对称加密来代替签名。

其他回答

只有服务器上的JWT的privateKey才能解密加密的JWT。那些知道privateKey的人将能够解密加密的JWT。

将私钥隐藏在服务器的安全位置,并且永远不要告诉任何人私钥。

我会用一个例子来解释。

假设我向你借了10美元,然后我给了你一张有我签名的借条。无论何时你或其他人把这张借条拿回来给我,我都会还你的,我会检查签名,确保那是我的。

我不能保证你不把这张借条的内容给任何人看,甚至给第三人看,我只关心这张借条是我签名的,当有人把这张借条给我看并让我支付的时候。

JWT的工作方式是完全相同的,服务器只能确保接收到的令牌是由自己发出的。

您需要其他措施来确保其安全,例如使用HTTPS传输时进行加密,确保存储令牌的本地存储是安全的,设置起源。

json web令牌(JWT)中的内容本质上并不安全,但有一个内置的功能用于验证令牌的真实性。JWT是用句点分隔的三个散列。第三个是签名。在公钥/私钥系统中,颁发者使用私钥签署令牌签名,该私钥只能由其对应的公钥验证。

理解发布者和验证者之间的区别是很重要的。令牌的接收者负责验证它。

There are two critical steps in using JWT securely in a web application: 1) send them over an encrypted channel, and 2) verify the signature immediately upon receiving it. The asymmetric nature of public key cryptography makes JWT signature verification possible. A public key verifies a JWT was signed by its matching private key. No other combination of keys can do this verification, thus preventing impersonation attempts. Follow these two steps and we can guarantee with mathematical certainty the authenticity of a JWT.

更多阅读:公钥如何验证签名?

结构和安全性

It is important to note that JWT are used for authorization and not authentication. So a JWT will be created for you only after you have been authenticated by the server by may be specifying the credentials. Once JWT has been created for all future interactions with server JWT can be used. So JWT tells that server that this user has been authenticated, let him access the particular resource if he has the role. Information in the payload of the JWT is visible to everyone. There can be a "Man in the Middle" attack and the contents of the JWT can be changed. So we should not pass any sensitive information like passwords in the payload. We can encrypt the payload data if we want to make it more secure. If Payload is tampered with server will recognize it. So suppose a user has been authenticated and provided with a JWT. Generated JWT has a claim specifying role of Admin. Also the Signature is generated with

这个JWT现在被篡改了,假设 角色修改为超级管理员 然后,当服务器接收到这个令牌时,它将再次使用秘密密钥(只有服务器拥有)和有效负载生成签名。与签名不符 在JWT。这样服务器就知道JWT被篡改了。

你可以去jwt。Io,粘贴您的令牌并读取内容。一开始,这对很多人来说是不和谐的。

简而言之,智威汤逊并不关心加密问题。它关心验证。也就是说,它总是可以得到“这个令牌的内容是否已被操纵”的答案?这意味着用户对JWT令牌的操作是无效的,因为服务器将知道并忽略令牌。服务器在向客户端发出令牌时根据有效负载添加签名。随后,它验证有效载荷和匹配签名。

合乎逻辑的问题是,它不关心加密内容的动机是什么?

The simplest reason is because it assumes this is a solved problem for the most part. If dealing with a client like the web browser for example, you can store the JWT tokens in a cookie that is secure (is not transmitted via HTTP, only via HTTPS) and httpOnly (can't be read by Javascript) and talks to the server over an encrypted channel (HTTPS). Once you know you have a secure channel between the server and client you can securely exchange JWT or whatever else you want. This keeps thing simple. A simple implementation makes adoption easier but it also lets each layer do what it does best (let HTTPS handle encryption). JWT isn't meant to store sensitive data. Once the server receives the JWT token and validates it, it is free to lookup the user ID in its own database for additional information for that user (like permissions, postal address, etc). This keeps JWT small in size and avoids inadvertent information leakage because everyone knows not to keep sensitive data in JWT.

这与cookie本身的工作方式没有太大区别。cookie通常包含未加密的有效载荷。如果你使用的是HTTPS,那么一切都很好。如果不是,建议对敏感cookie本身进行加密。如果不这样做,就可能会受到中间人攻击——代理服务器或ISP读取cookie,然后假装是你,重新播放它们。出于类似的原因,JWT应该始终通过HTTPS之类的安全层进行交换。