JWT技术——基于token的鉴权机制

  1. JWT技术——基于token的鉴权机制
  2. 1.基本流程
  3. 2.与session的区别
  4. 3.弊端
  5. 4.JWT长什么样?
  6. 5.构成
    1. 5.1header
    2. 5.2playload
    3. 5.3signature
  7. 6.攻击思路

今天挖洞 问了jwt技术

JWT技术——基于token的鉴权机制

1.基本流程

JWT技术(基于token的鉴权机制)

流程上是这样的:

用户使用用户名密码来请求服务器

服务器进行验证用户的信息

服务器通过验证后生成一个token发送给用户

客户端存储token,并在每次请求时附送上这个token值

服务端验证token值,并返回数据

2.与session的区别

JWT和Session技术的根本区别在于,Session是把访问者信息存储在服务器端的,而JWT是把信息存储在客户端。

3.弊端

JWT方式,每次请求都要带上token,服务器每次都要解密出token的信息,这会让服务器有一些计算压力。而且,如果客户端的信息比较多,每次HTTP请求携带的数据就比较多。还有一点,JWT在客户端的存储,不能包含敏感信息,否则很容易被泄露,而且不建议在客户端存储会变动的信息,否则可能出现一致性问题。

4.JWT长什么样?

JWT是由三段信息(header.payload.signature)构成的,将这三段信息文本用英文句号链接一起就构成了JWT字符串。例如:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

可以在 https://jwt.io/ 这个网站,把token解析出来。

5.构成

JWT的构成

第一部分我们称它为头部(header),

第二部分我们称其为承载(payload, 类似于飞机上承载的物品),

第三部分是签证(signature)。

5.1header

完整的头部就像下面这样的JSON:

{undefined

 'typ': 'JWT',

 'alg': 'HS256'

}

即声明 类型 和 加密的算法。然后将头部进行base64加密,就构成了header部分。

5.2playload

承载就是存放有效信息的地方。这个名字像是指飞机上承载的货品,这些有效信息包含三个部分声明(Claims)

标准中注册的声明

公共的声明

私有的声明

标准中注册的声明 (建议但不强制使用) :

iss: jwt签发者

sub: jwt所面向的用户

aud: 接收jwt的一方

exp: jwt的过期时间,这个过期时间必须要大于签发时间

nbf: 定义在什么时间之前,该jwt都是不可用的.

iat: jwt的签发时间

jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。

5.3signature

signature是一个签证信息,它会用到前面的header、payload信息,以及一个密匙(secret)。

即,这个部分需要 base64加密后的header 和 base64加密后的payload,使用 英文句号 连接组成的字符串,然后通过header中声明的加密方式,进行加盐secret组合加密,然后就构成了jwt的第三部分signature。

6.攻击思路

1.token的存储一般有两种方式,一种是存在localStorage中,二是存在cookie中,这两种存储方式都有问题,存在localStorage中有很大的安全隐患,容易造成XSS攻击,因为跨站脚本可以读取localStorage里面的信息,如果存在cookie中,又容易造成CSRF攻击,这个是由于Cookie存储的安全性造成的(可以使用XSRF Token来解决这个问题)。

2.失效和刷新问题,token肯定要有失效时间,而且如果用户一直处于活跃状态,则要考虑能自动刷新token。

3.重放攻击,由于每次都传输token,如果这个token被窃取,那么可以在任何一个地方使用。特别的,如果这个token过期时间很长的话,那么它就相当于一个在很长时间内有效的钥匙。(可以考虑每次请求都重新生成一个token并存储一段时间防重放,但是这样又会遇到存储问题和并发刷新的问题,参见:https://zhuanlan.zhihu.com/p/22693223)

JWT攻击手册:如何入侵你的Token - Bypass - 博客园 (cnblogs.com)


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。后续可能会有评论区,不过也可以在github联系我。