0x001 什么是JWT?
JSON Web Token(JSON Web令牌)是一种跨域验证身份的方案。JWT不加密传输的数据,但能够通过数字签名来验证数据未被篡改。
JWT组成
JWT分为三部分,头部(Header),声明(Claims),签名(Signature),三个部分以英文句号.隔开。JWT的内容以Base64URL进行了编码。
头部(Header)
{
"alg":"HS256",
"typ":"JWT"
}
# alg
是说明这个JWT的签名使用的算法的参数,常见值用HS256(默认),HS512等,也可以为None。HS256表示HMAC SHA256。
# typ
说明这个token的类型为JWT
声明(Claims)
{
"exp": 1416471934,
"user_name": "user",
"scope": [
"read",
"write"
],
"authorities": [
"ROLE_ADMIN",
"ROLE_USER"
],
"jti": "9bc92a44-0b1a-4c5e-be70-da52075b9a84",
"client_id": "my-client-with-secret"
}
# JWT固定参数有:
# iss:发行人
# exp:到期时间
# sub:主题
# aud:用户
# nbf:在此之前不可用
# iat:发布时间
# jti:JWT ID用于标识该JWT
签名(Signature)
服务器有一个不会发送给客户端的密码(secret),用头部中指定的算法对头部和声明的内容用此密码进行加密,生成的字符串就是JWT的签名。
使用jwt登录时的验证过程
1、用户端登录,用户名和密码在请求中被发往服务器
2、(确认登录信息正确后)服务器生成JSON头部和声明,将登录信息写入JSON的声明中(通常不应写入密码,因为JWT是不加密的),并用secret用指定算法进行加密,生成该用户的JWT。此时,服务器并没有保存登录状态信息。
3、服务器将JWT(通过响应)返回给客户端
4、用户下次会话时,客户端会自动将JWT写在HTTP请求头部的Authorization字段中
5、服务器对JWT进行验证,若验证成功,则确认此用户的登录状态
6、服务器返回响应
0x002 如何攻击
攻击的两种方式:
- 有密钥
- 无密钥
无密钥攻击
从上面我们可以知道签名是根据头部中的alg
加密算法进行加密生成的,而alg
参数是可控的,我们可以将它改为none
,也就是不使用签名。签名主要用于验证 token
是否有效,是否被篡改。
在HTTP传输过程中,Base64编码中的"=","+","/"等特殊符号通过URL解码通常容易产生歧义,因此产生了与URL兼容的Base64 URL编码
修改后生成的token
,后面别忘记加点
ewogICJhbGciOiAibm9uZSIsCiAgInR5cCI6ICJKV1QiCn0.ewogICJzdWIiOiAiMTIzNDU2Nzg5MCIsCiAgIm5hbWUiOiAiSm9obiBEb2UiLAogICJpYXQiOiAxNTE2MjM5MDIyCn0.
如果生命中有可以修改的相关参数,修改后生成token,带着新生成且没有签名的token
请求即可。
这里注意一下 我们修改alg
的加密值为none
是否可以验证成功,取决于后端是否根据该值进行的验证。
未完待续。。。。。。