JSON Web Token (JWT) 攻击技巧
字数 1700 2025-08-29 08:32:18
JSON Web Token (JWT) 攻击技巧详解
1. JWT 概述
JSON Web Token (JWT) 是一种轻量级的业务流程管理规范,用于在用户和服务器之间安全可靠地传递信息。它通常用于实现前端和后端的解耦,并与 Restful API 一起构建身份验证机制。
JWT 工作流程
- 用户提交凭证(如用户名/密码)
- 服务器验证凭证
- 验证通过后,服务器返回包含 JWT 的响应
- 后续请求中,客户端在
Authorization头中添加 JWT(格式为Authorization: jwt <token>) - JWT 通常存储在客户端的本地存储(LocalStorage)中
2. JWT 结构
JWT 由三部分组成,用点号(.)分隔:
- 头部(Header)
- 有效载荷(Payload)
- 签名(Signature)
格式:base64UrlEncode(header).base64UrlEncode(payload).signature
2.1 头部(Header)
包含 JWT 的配置信息,通常包括:
alg:签名算法(如 HS256、RS256)typ:令牌类型(通常为 "JWT")kid:密钥 ID(当服务器使用多个密钥时)
示例解码后:
{
"kid": "keys/3c3c2ea1c3f113f649dc9389dd71b851",
"typ": "JWT",
"alg": "RS256"
}
2.2 有效载荷(Payload)
包含用户数据(声明),如用户 ID、用户名等。
示例解码后:
{
"sub": "dubhe123"
}
2.3 签名(Signature)
用于验证消息在传输过程中未被篡改。签名算法通常为:
- RS256(RSA 非对称加密,使用私钥签名,公钥验证)
- HS256(HMAC SHA256 对称加密,使用密钥签名和验证)
3. JWT 攻击技术
3.1 敏感信息泄露
由于有效载荷是 Base64 编码的明文,如果其中包含敏感信息(如密码、密钥等),攻击者可以直接解码获取这些信息。
防御措施:不要在 JWT 中存储敏感信息。
3.2 将签名算法改为 none
一些 JWT 库支持 none 算法,即不进行签名验证。攻击步骤:
- 修改头部中的
alg为none - 删除签名部分(只保留
header.payload.) - 提交给服务器
示例代码:
import base64
def b64urlencode(data):
return base64.b64encode(data).replace('+', '-').replace('/', '_').replace('=', '')
print(b64urlencode('{"typ":"JWT","alg":"none"}') +
'.' +
b64urlencode('{"data":"test"}') +
'.')
防御措施:禁用 none 算法支持,或明确拒绝没有签名的 JWT。
3.3 将 RS256 算法改为 HS256(非对称→对称)
攻击步骤:
- 获取服务器的 RSA 公钥
- 修改头部中的
alg从RS256改为HS256 - 使用 RSA 公钥作为 HMAC 密钥对 JWT 进行签名
- 服务器会使用公钥作为 HMAC 密钥来验证签名
示例代码:
import jwt
public = open('public.pem', 'r').read()
print(jwt.encode({"data": "test"}, key=public, algorithm='HS256'))
防御措施:
- 在验证签名时强制使用预期的算法
- 不要将公钥与对称算法混合使用
3.4 破解 HS256 密钥
如果 HS256 使用的密钥强度较弱,攻击者可以进行暴力破解。
破解方法:
- 收集有效的 JWT
- 使用字典或暴力攻击尝试不同密钥
- 当解码不抛出异常时,说明找到了正确密钥
示例代码:
import jwt
# 已知的有效 JWT 和解码后的内容
valid_jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzb21lIjoicGF5bG9hZCJ9.4twFt5NiznN84AWoo1d7KO1T_yoc0Z6XOpOVswacPZg"
known_payload = {"some": "payload"}
# 尝试破解密钥
possible_keys = ["secret", "password", "123456", ...]
for key in possible_keys:
try:
decoded = jwt.decode(valid_jwt, key, algorithms=['HS256'])
if decoded == known_payload:
print(f"Found key: {key}")
break
except:
continue
防御措施:
- 使用足够长且复杂的 HS256 密钥
- 定期更换密钥
- 考虑使用 RS256 等非对称算法替代 HS256
4. 防御建议
- 验证算法:在服务器端明确指定接受的算法,拒绝任何非预期的算法
- 密钥管理:
- 对 HS256 使用强密钥
- 对 RS256 妥善保管私钥
- 信息最小化:不要在 JWT 中存储敏感信息
- 设置合理有效期:使用
exp声明设置短期有效的 JWT - 使用 HTTPS:防止 JWT 在传输过程中被窃取
- 实施令牌撤销机制:对于敏感操作,提供令牌撤销能力
5. 参考工具
6. 总结
JWT 作为一种广泛使用的身份验证机制,如果配置不当会带来严重的安全风险。安全人员应充分了解 JWT 的各种攻击技术,并在实现时采取相应的防御措施。特别要注意算法选择、密钥管理和信息保护等关键方面。