前言:
之前有碰到过好几次,没想着整理,最近在重新补基础就一起写了。
一、JWT
简介
JSON Web Token(JSON Web令牌):通过JSON形式作为Web应用中的令牌,用于在各方之间安全地将信息作为JSON对象传输。并且在传输过程中可以对数据进行加密、签名等处理。
结构
这里推荐一个平台https://jwt.io/。利用这个平台可以快速查看jwt的头部和payload
jwt的结构分为三个部分
1 | 头部(Header): eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 |
三个部分利用.
拼接在一起类似于xxxx.xxxx.xxxx
格式,上面三个部分拼接在一起:
1 | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IlRHMXUifQ.E6_aosK_r4woX4_yxoxoSjA7L-vvwjqPSmRxAaNnjEo |
头部(Header)
头部包含两部分信息:
声明token类型typ。
声明加密的算法alg,通常直接使用HMAC、SHA256、RSA。(如果“alg”字段设为“ None”,那么JWT的第三部分会被置空,这样任何token都是有效的。这样就可以无需secret伪造token进行随意访问)
将头部进行base64加密就构成了第一部分
有效载荷(payload)
payload有三部分组成
1、注册声明(一般实战中才会有)
1 | iss: jwt签发者 |
2、公共声明
可以添加任何信息,一般会添加用户的一些信息,但是不建议添加敏感信息。(这部分无需secret就可以解密出来了)
3、私有声明
由发行者和消费者之间私有使用的声明,不会被共享给其他发行者或消费者。这些声明主要用于在特定应用场景下传递一些特定的信息,仅限于发行者和消费者之间使用.
1 | { |
签证(Signature)
需要知道header、payload、secret、alg才能得到签证
以HMAC SHA256算法为例
1 | var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload); |
通过HMAC SHA256算法结合secret进行加盐签名(私钥加密),其中header和payload将通过base64UrlEncode()
方法进行base64加密,然后通过字符串拼接"."
生成新字符串,最终生成JWT的第三部分。
二、JWT伪造
一般secret都不会给到客户端,所以如果需要伪造jwt的话,就需要利用一个工具jwt-cracker来获取secret。
jwt-cracker下载后进行配置
npm install --global jwt-cracker
下面随便给出一个JWT令牌
1 | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IlRHMXUifQ.E6_aosK_r4woX4_yxoxoSjA7L-vvwjqPSmRxAaNnjEo |
首先就是放入到jwt.io平台查看头部和payload
可以看到是存在secret的,所以无法直接伪造。
jwt-cracker
利用jwt-cracker进行爆破
1 | jwt-cracker -t <token> [-a <alphabet>] [--max <maxLength>] [-d <dictionaryFilePath>] [-f] |
具体使用
1 | jwt-cracker -t eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IlRHMXUifQ.E6_aosK_r4woX4_yxoxoSjA7L-vvwjqPSmRxAaNnjEo |
可以看到爆破出的secret为SYSA
jwt.io
由于我的jwt.io在浏览器中有点问题,所以自己在本地部署了一个
1 | // 下载 |
伪造jwt
1 | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIn0.9avq5ApZ-XZul2kbon8z2cB6Y4bNru_0nnIZfJ1mO50 |