我正在尝试为我的RESTful api使用JWT实现无状态身份验证。
AFAIK, JWT基本上是在REST调用期间作为HTTP头传递的加密字符串。
但是如果有窃听者看到请求并窃取令牌怎么办?然后他就能用我的身份伪造申请了?
实际上,这个问题适用于所有基于令牌的身份验证。
如何预防呢?像HTTPS这样的安全通道?
我正在尝试为我的RESTful api使用JWT实现无状态身份验证。
AFAIK, JWT基本上是在REST调用期间作为HTTP头传递的加密字符串。
但是如果有窃听者看到请求并窃取令牌怎么办?然后他就能用我的身份伪造申请了?
实际上,这个问题适用于所有基于令牌的身份验证。
如何预防呢?像HTTPS这样的安全通道?
当前回答
我是一个节点库express-stormpath的作者,该库相当深入地处理身份验证,因此我将在这里补充一些信息。
首先,jwt通常不是加密的。虽然有一种加密jwt的方法(参见:JWEs),但由于许多原因,这种方法在实践中并不常见。
接下来,任何形式的身份验证(是否使用jwt)都可能受到MitM攻击(中间人)的攻击。当攻击者在你通过互联网发出请求时可以查看你的网络流量时,就会发生这些攻击。这是你的ISP可以看到的,美国国家安全局,等等。
这就是SSL帮助防止的:通过加密您的网络流量从您的计算机->一些服务器认证时,监视您的网络流量的第三方无法看到您的令牌,密码,或任何类似的东西,除非他们以某种方式能够获得服务器的私有SSL密钥的副本(不太可能)。这就是SSL对于所有形式的身份验证都是强制性的原因。
但是,假设有人能够利用您的SSL并能够查看您的令牌:您问题的答案是YES,攻击者将能够使用该令牌来模拟您并向您的服务器发出请求。
这就是协议的用武之地。
jwt只是身份验证令牌的一个标准。它们几乎可以用于任何事情。jwt很酷的原因是您可以在其中嵌入额外的信息,并且可以验证没有人干扰它(签名)。
然而,jwt本身与“安全性”无关。从所有意图和目的来看,jwt或多或少与API密钥相同:只是用于对某个服务器进行身份验证的随机字符串。
使您的问题更有趣的是所使用的协议(很可能是OAuth2)。
OAuth2的工作方式是为客户端提供临时令牌(如jwt !),仅用于短时间的身份验证!
这个想法是,如果您的令牌被盗,攻击者只能在很短的时间内使用它。
使用OAuth2,您必须经常通过提供您的用户名/密码或API凭据来重新验证自己,然后以交换的方式获得令牌。
因为这个过程会时不时地发生,所以您的令牌会经常更改,这使得攻击者难以不断地冒充您而不会遇到很大的麻烦。
希望这有助于^^
其他回答
我们不能只添加请求生成这个JWT令牌的初始主机的ip作为声明的一部分吗?现在,当JWT被窃取并从另一台机器上使用时,当服务器验证这个令牌时,我们可以验证请求的机器ip是否与声明中的ip集匹配。这将不匹配,因此可以拒绝令牌。此外,如果用户试图通过将自己的ip设置为令牌来操作令牌,则令牌将被拒绝,因为令牌已被更改。
我是一个节点库express-stormpath的作者,该库相当深入地处理身份验证,因此我将在这里补充一些信息。
首先,jwt通常不是加密的。虽然有一种加密jwt的方法(参见:JWEs),但由于许多原因,这种方法在实践中并不常见。
接下来,任何形式的身份验证(是否使用jwt)都可能受到MitM攻击(中间人)的攻击。当攻击者在你通过互联网发出请求时可以查看你的网络流量时,就会发生这些攻击。这是你的ISP可以看到的,美国国家安全局,等等。
这就是SSL帮助防止的:通过加密您的网络流量从您的计算机->一些服务器认证时,监视您的网络流量的第三方无法看到您的令牌,密码,或任何类似的东西,除非他们以某种方式能够获得服务器的私有SSL密钥的副本(不太可能)。这就是SSL对于所有形式的身份验证都是强制性的原因。
但是,假设有人能够利用您的SSL并能够查看您的令牌:您问题的答案是YES,攻击者将能够使用该令牌来模拟您并向您的服务器发出请求。
这就是协议的用武之地。
jwt只是身份验证令牌的一个标准。它们几乎可以用于任何事情。jwt很酷的原因是您可以在其中嵌入额外的信息,并且可以验证没有人干扰它(签名)。
然而,jwt本身与“安全性”无关。从所有意图和目的来看,jwt或多或少与API密钥相同:只是用于对某个服务器进行身份验证的随机字符串。
使您的问题更有趣的是所使用的协议(很可能是OAuth2)。
OAuth2的工作方式是为客户端提供临时令牌(如jwt !),仅用于短时间的身份验证!
这个想法是,如果您的令牌被盗,攻击者只能在很短的时间内使用它。
使用OAuth2,您必须经常通过提供您的用户名/密码或API凭据来重新验证自己,然后以交换的方式获得令牌。
因为这个过程会时不时地发生,所以您的令牌会经常更改,这使得攻击者难以不断地冒充您而不会遇到很大的麻烦。
希望这有助于^^
一旦代币被盗,游戏就结束了。 然而,有一种方法可以使使用被盗的令牌变得更加困难。
查阅https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_for_Java_Cheat_Sheet.html#token-sidejacking。
基本上,您可以创建一个x字节长的十六进制指纹,将其原始值存储在令牌哈希中,例如使用SHA-512对指纹进行哈希,并将哈希后的指纹放在httponly安全cookie中。
现在,您不仅需要验证令牌的签名和过期日期,还需要验证cookie的存在,并确保原始指纹值匹配。
客户端应该使用用户密码哈希的一部分来加密http msg被客户端发送到服务器的时间。在创建散列的这一部分时,还应该使用一些服务器密钥加密到令牌中。
服务器可以解密http请求时间,并验证较短的时间延迟。
令牌将改变每个请求。
为了处理令牌被盗用的问题,您将每个JWT映射为有效ip列表。
例如,当用户登录一个特定的IP时,当你可以添加该IP为该JWT的有效IP时,当你从另一个IP(用户改变了互联网或JWT被盗,或任何原因)得到这个JWT的请求时,你可以根据你的用例做以下事情:
将CSRF令牌与用户令牌映射,如果它被窃取,那么它的CSRF令牌将不匹配,因为您可以使该用户令牌无效。 您可以向用户提供验证码,以验证他是否是有效用户。如果他输入验证码,然后将该IP添加到该JWT的有效列表中。 您可以注销该用户,然后重新请求登录。 您可以提醒用户您的IP已更改或从不同的位置请求。
您也可以在上述用例中使用5分钟的缓存,而不是每次都检查。
建议是否可以改进。