JWT中的"秘密"应该是什么?

Pea*_*Gen 20 java rest secret-key jwt

我将把JWT应用到我使用Java-Jersey开发的REST API中.我正在为JWT使用这个库 - https://github.com/auth0/java-jwt

关于JWT - Secret,我几乎没有问题

  1. Secret必须是独一无二的吗?
  2. 我应该使用用户密码的哈希版本来保密吗?(然后它不是唯一的)这是因为当用户更改他的密码时,他的令牌将自动无效.

rua*_*akh 21

  1. Secret必须是独一无二的吗?

它应该是您的应用程序所独有的 - 毕竟它需要是一个秘密 - 但它对于每个令牌都不是唯一的.相反,您应该在任何给定时间拥有相对较少数量的密钥(例如,通常只有一个密钥,但是当您从一个密钥旋转到下一个密钥时,您有两个密钥的短暂周期).

  1. 我应该使用用户密码的哈希版本来保密吗?

不,有两个原因:

  1. 假设您的用户拥有相对不安全的密码,例如GoPackers123.在您的秘密中使用密码意味着有人可以轻松测试给定的潜在密码,看它是否产生正确的签名; 而且,更重要的是,他们可以轻松测试大量潜在密码,看看是否有任何密码给出了正确的签名.这是一次离线攻击,所以你永远不会知道它发生了.
  2. 这将要求您将所有用户的密码哈希值分发给需要保密的每个系统.如果您的用户数量不仅仅是微不足道,那么这对您的秘密分发机制来说可能会成为一个相当严重的负担.

  • @PeakGen:您不会与用户共享机密,因此您不需要为不同的用户设置不同的机密。但是您确实需要经常更改密钥;您可以*为每个人*使用一把钥匙,但不能*永远*使用一把钥匙。 (2认同)
  • @PeakGen:单独的问题应该单独发布,但简而言之:不,这不正常。你的代币应该包括像 `exp` 和 `sub` 这样的声明来限制生命周期和区分用户;所以没有两个令牌应该是相同的。 (2认同)

cas*_*lin 10

JWT和java-jwt库支持签名的对称非对称算法:

  • 如果您选择HS256等对称算法,您将只能使用一个密钥来签名和验证签名.

  • 如果您考虑非对称算法(如RS256),您将拥有私钥和公钥.保持私钥在服务器上安全并使用它来签署令牌.使用公钥验证签名(也可以与需要验证签名的人共享).

永远不要共享用于签署令牌的密钥!

并且没有什么可以阻止您使用一组不同的密钥来签署您的令牌.在这种情况下,kidheader参数可用于指示用于对令牌进行签名的密钥.该声明应该带有密钥标识符,而不是密钥本身.

有关索赔的更多详细信息,请参阅此答案kid.

  • @PeakGen问题应该是:_哪个是最适合我的应用程序的?_答案将是:_这取决于您的要求_。如果要允许客户端验证签名,请使用RS256。否则,请坚持使用HS256。此[answer](http://stackoverflow.com/q/39239051/1426227)可能会有所帮助。 (2认同)

Joc*_*fer 2

使用 RSA256,即私钥/公钥对(不需要“秘密”)。这样您就可以保持私钥的秘密和安全(它仅用于签署令牌),并且您可以使用公钥来验证签名是否正确。

您可以将公钥提供给需要验证令牌签名是否正确的任何人或任何服务。