基本概念
JWT的全称是Json Web Token。它遵循JSON格式,将用户信息加密到token里,服务器不保存任何用户信息,只保存密钥信息,通过使用特定加密算法验证token,通过token验证用户身份。基于token的身份验证可以替代传统的cookie+session身份验证方法。
jwt由三个部分组成
header.payload.signature |
首先看 header
alg
指定了token加密使用的算法(最常用的为HMAC和RSA算法
HMAC:对称
RSA:非对称
HASH: 压缩
MAC: 带密钥的hash
HMAC: MAC的一种
{ |
payload
相关的数据:
{ |
signature
,保护token完整性
signature = HMAC-SHA256(base64urlEncode(header) + '.' + base64urlEncode(payload), secret_key) |
pyjwt
(注意是必须 pip install pyjwt
In [1]: import jwt |
可以看到并不需要key也可以直接解密,有点像flask 的session
解密
In [4]: print(jwt.decode(encoded_jwt, 'key', algorithms=['HS256'])) |
攻击方式
空加密算法
JWT支持使用空加密算法,可以在header中指定alg为None
pyjwt生成空加密算法的jwt
In [10]: encoded_jwt = jwt.encode({'user_name': 'admin'}, 'key', headers={"alg":"None", "typ":"jwt"}) |
修改加密算法RSA为HMAC(未尝试)
理论:
一个Web应用,在JWT传输过程中使用RSA算法,密钥pem
对JWT token进行签名,公钥pub
对签名进行验证。
通常情况下密钥pem
是无法获取到的,但是公钥pub
却可以很容易通过某些途径读取到,这时,将JWT的加密算法修改为HMAC
{ |
同时使用公钥pub作为密钥,这样服务端接收到的数据就会用HMAC的方式来验证了
爆破密钥
c-jwt-cracker了解一下
修改kid参数
用来指定私钥位置,也可以修改?
{ |
任意文件读取?(有点骚)
{ |
SQL注入
{ |
命令注入
"/path/to/key_file|whoami" |