最近碰到一个站,返回的用户信息是jwt生成的值,用jwt.io
可以直接解密,刚准备用脚本进行批量遍历的时候,发现总是有报错,所以写这篇文章记录一下
众所周知,jwt的值分为三部分,分别用.
连接,在jwt.io
中也可以很好的区分
通常用于声明类型、加密算法
正常的写法是
{
'alg':'HS384'
}
然后把头部内容进行base64编码,就生成了第一部分
所以基本ey
开头的都可以尝试jwt解密
和上面一样,都是json转为字符串后,进行base64编码,完成后,和前面一个用.
进行拼接
这部分则是对第二部分完成后拼接成功的值,进行加密加盐,接着进行base64编码,以此来防止恶意用户构造token来进行身份伪造
介绍完jwt
后,回到问题上,我遇到的报错是这个
jwt.exceptions.DecodeError: Not enough segments
于是继续往上看,是哪部分引起的这个问题
signing_input, crypto_segment = jwt.rsplit(b'.', 1)
ValueError: not enough values to unpack (expected 2, got 1)
很明显,是分割的时候出现了问题,结合上面的原理,我去查看了数据包返回的内容
{"data":"eyxxxxxxxxxx","code":"0"}
返回的内容确实没有.
,所以引起了api_jws.py
这个文件里180行,对字符串进行分割的失败操作,实际上jwt.io
中解密也确实只有header
这部分的内容
结合上面的内容,我们知道jwt
分为三个部分,而python中的jwt.decode()
解码出来的内容是payload部分,所以我们构造语句,前后进行拼接,确保原本在header
的内容放置在payload
中
user_token="eee."+user_data["data"]+".eee" #前后随意填充,确保讲user_data内容放置在payload处
result=jwt.decode(user_token,'',False,algorithm='HS384') #False,不做验证
print(result)
那最后,可能就会有人(指我自己)会杠一下,说“你前面自己都说了这玩意base64编码的,那你为什么不直接base64decode呢,非得jwt”
那我只能
“你说得对,我是沙口”
我脚本写完后才后知后觉的发现了这个问题T T