代码之家  ›  专栏  ›  技术社区  ›  Osama Xäwãñz

是否可以编辑JWT令牌?

  •  0
  • Osama Xäwãñz  · 技术社区  · 7 年前

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

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

    0 回复  |  直到 6 年前
        1
  •  378
  •   HDJEMAI    6 年前

    JWTs可以是签名的、加密的,也可以两者兼有。如果令牌已签名,但未加密,则每个人都可以读取其内容,但当您不知道私钥时,则无法更改它。否则,接收者将注意到签名不再匹配。

    回答你的评论:我不确定我是否理解你的评论的正确方式。只是确定一下:你知道并理解数字签名吗?我只简单地解释一个变体(HMAC,它是对称的,但是还有很多其他变体)。

    假设爱丽丝想给鲍勃寄一张JWT。他们都知道一些共同的秘密。马洛里不知道这个秘密,但想干涉和改变JWT。为了防止这种情况,爱丽丝计算了一下 Hash(payload + secret) 并附加此作为签名。

    当接收到消息时,Bob还可以计算 散列(负载+机密) 检查签名是否匹配。 但是,如果Mallory更改了内容中的某些内容,她将无法计算匹配的签名(这将是 Hash(newContent + secret) ). 她不知道这个秘密,也没有办法知道。 这意味着如果她改变了什么,签名将不再匹配,鲍勃将不再接受JWT。

    假设,我给另一个人发信息 {"id":1} 在上面签上 Hash(content + secret) . (+在这里只是连接)。我使用SHA256散列函数,得到的签名是: 330e7b0775561c6e95797d4dd306a150046e239986f0a1373230fda0235bda8c . 现在轮到你了:扮演马洛里的角色,试着在留言上签名 {"id":2} . 你不能因为你不知道我用了哪个秘密。如果我假设收件人知道这个秘密,他可以计算出任何消息的签名并检查它是否正确。

        2
  •  131
  •   Carsten Führmann    6 年前

    你可以去 jwt.io ,粘贴标记并读取内容。一开始这对很多人来说都是刺耳的。

    简而言之,JWT并不关心加密。它关心验证。也就是说,它总能得到“操纵此令牌内容”的答案?这意味着用户对JWT令牌的操作是徒劳的,因为服务器将知道并忽略该令牌。当向客户机颁发令牌时,服务器根据负载添加签名。稍后它将验证有效负载和匹配的签名。

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

    1. 最简单的原因是,它假设这是一个解决了大部分问题。例如,如果处理像web浏览器这样的客户机,则可以将JWT令牌存储在 secure (不通过HTTP传输,仅通过HTTPS)和 httpOnly (Javascript无法读取)并通过加密通道(HTTPS)与服务器对话。一旦你知道你在服务器和客户端之间有一个安全的通道,你就可以安全地交换JWT或任何你想要的东西。

    2. 这让事情变得简单。一个简单的实现使采用变得更容易,但它也让每一层做它最擅长的事情(让HTTPS处理加密)。

    3. JWT不是用来存储敏感数据的。一旦服务器接收到JWT令牌并对其进行验证,它就可以在自己的数据库中查找该用户的其他信息(如权限、邮政地址等)。这使得JWT的大小更小,避免了无意中的信息泄漏,因为每个人都知道不要在JWT中保留敏感数据。

    这和饼干本身的工作原理没有太大区别。Cookies通常包含未加密的有效载荷。如果你使用的是HTTPS,那么一切都很好。如果你不这样做,那么最好自己加密敏感的cookie。不这样做将意味着中间人攻击是可能的——代理服务器或ISP读取cookies,然后在以后假装成您时重放它们。出于类似的原因,JWT应该总是在像HTTPS这样的安全层上进行交换。

        3
  •  16
  •   Community Mohan Dere    9 年前

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

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

    在web应用程序中安全地使用JWT有两个关键步骤:1)通过加密的通道发送它们,2)在接收到签名后立即验证它。公钥密码的非对称性使得JWT签名验证成为可能。公钥验证JWT是否由其匹配的私钥签名。没有其他密钥组合可以执行此验证,从而阻止模拟尝试。按照这两个步骤,我们可以用数学上的确定性来保证JWT的真实性。

    更多阅读: How does a public key verify a signature?

        4
  •  1
  •   sdfdsf sdf    8 年前

    只有JWT的私有密钥(位于服务器上)才能解密加密的JWT。那些知道私有密钥的人将能够解密加密的JWT。

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

        5
  •  0
  •   Nirojan Selvanathan    7 年前

    对于像我这样负担不起昂贵的数据库查询的人来说,保留敏感数据(用户priveledges等)的一个选择是,在生成JWT时,您可以加密这些数据并将其附加到JWT令牌。(将加密密钥保留在后端)

    当您想读取敏感信息时,可以将JWT令牌发送到后端并对其进行解密,然后将信息取回。这样,您就不必通过JWT令牌在前端执行DB查找或将敏感信息裸露出来

        6
  •  -1
  •   Mithun Shreevatsa    7 年前

    我建议在研究JWE时使用特殊算法,这在智威汤逊解密

    参考链接: https://www.npmjs.com/package/node-webtokens

    jwt.generate('PBES2-HS512+A256KW', 'A256GCM', payload, pwd, (error, token) => {
      jwt.parse(token).verify(pwd, (error, parsedToken) => {
        // other statements
      });
    });
    

    这个答案可能太晚了,或者你可能已经找到了路,但是,我仍然觉得这对你和其他人都有帮助。

    我创建了一个简单的示例: https://github.com/hansiemithun/jwe-example