JSON Web Token (JWT) 攻击技巧
字数 1700 2025-08-29 08:32:18

JSON Web Token (JWT) 攻击技巧详解

1. JWT 概述

JSON Web Token (JWT) 是一种轻量级的业务流程管理规范,用于在用户和服务器之间安全可靠地传递信息。它通常用于实现前端和后端的解耦,并与 Restful API 一起构建身份验证机制。

JWT 工作流程

  1. 用户提交凭证(如用户名/密码)
  2. 服务器验证凭证
  3. 验证通过后,服务器返回包含 JWT 的响应
  4. 后续请求中,客户端在 Authorization 头中添加 JWT(格式为 Authorization: jwt <token>
  5. 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 算法,即不进行签名验证。攻击步骤:

  1. 修改头部中的 algnone
  2. 删除签名部分(只保留 header.payload.
  3. 提交给服务器

示例代码:

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(非对称→对称)

攻击步骤:

  1. 获取服务器的 RSA 公钥
  2. 修改头部中的 algRS256 改为 HS256
  3. 使用 RSA 公钥作为 HMAC 密钥对 JWT 进行签名
  4. 服务器会使用公钥作为 HMAC 密钥来验证签名

示例代码:

import jwt

public = open('public.pem', 'r').read()
print(jwt.encode({"data": "test"}, key=public, algorithm='HS256'))

防御措施

  • 在验证签名时强制使用预期的算法
  • 不要将公钥与对称算法混合使用

3.4 破解 HS256 密钥

如果 HS256 使用的密钥强度较弱,攻击者可以进行暴力破解。

破解方法:

  1. 收集有效的 JWT
  2. 使用字典或暴力攻击尝试不同密钥
  3. 当解码不抛出异常时,说明找到了正确密钥

示例代码:

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. 防御建议

  1. 验证算法:在服务器端明确指定接受的算法,拒绝任何非预期的算法
  2. 密钥管理
    • 对 HS256 使用强密钥
    • 对 RS256 妥善保管私钥
  3. 信息最小化:不要在 JWT 中存储敏感信息
  4. 设置合理有效期:使用 exp 声明设置短期有效的 JWT
  5. 使用 HTTPS:防止 JWT 在传输过程中被窃取
  6. 实施令牌撤销机制:对于敏感操作,提供令牌撤销能力

5. 参考工具

  1. jwt.io - JWT 调试和验证工具
  2. PyJWT - Python 的 JWT 库
  3. John the Ripper - 可用于暴力破解弱密钥
  4. jwt_tool - 专门的 JWT 测试工具

6. 总结

JWT 作为一种广泛使用的身份验证机制,如果配置不当会带来严重的安全风险。安全人员应充分了解 JWT 的各种攻击技术,并在实现时采取相应的防御措施。特别要注意算法选择、密钥管理和信息保护等关键方面。

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(当服务器使用多个密钥时) 示例解码后: 2.2 有效载荷(Payload) 包含用户数据(声明),如用户 ID、用户名等。 示例解码后: 2.3 签名(Signature) 用于验证消息在传输过程中未被篡改。签名算法通常为: RS256(RSA 非对称加密,使用私钥签名,公钥验证) HS256(HMAC SHA256 对称加密,使用密钥签名和验证) 3. JWT 攻击技术 3.1 敏感信息泄露 由于有效载荷是 Base64 编码的明文,如果其中包含敏感信息(如密码、密钥等),攻击者可以直接解码获取这些信息。 防御措施 :不要在 JWT 中存储敏感信息。 3.2 将签名算法改为 none 一些 JWT 库支持 none 算法,即不进行签名验证。攻击步骤: 修改头部中的 alg 为 none 删除签名部分(只保留 header.payload. ) 提交给服务器 示例代码: 防御措施 :禁用 none 算法支持,或明确拒绝没有签名的 JWT。 3.3 将 RS256 算法改为 HS256(非对称→对称) 攻击步骤: 获取服务器的 RSA 公钥 修改头部中的 alg 从 RS256 改为 HS256 使用 RSA 公钥作为 HMAC 密钥对 JWT 进行签名 服务器会使用公钥作为 HMAC 密钥来验证签名 示例代码: 防御措施 : 在验证签名时强制使用预期的算法 不要将公钥与对称算法混合使用 3.4 破解 HS256 密钥 如果 HS256 使用的密钥强度较弱,攻击者可以进行暴力破解。 破解方法: 收集有效的 JWT 使用字典或暴力攻击尝试不同密钥 当解码不抛出异常时,说明找到了正确密钥 示例代码: 防御措施 : 使用足够长且复杂的 HS256 密钥 定期更换密钥 考虑使用 RS256 等非对称算法替代 HS256 4. 防御建议 验证算法 :在服务器端明确指定接受的算法,拒绝任何非预期的算法 密钥管理 : 对 HS256 使用强密钥 对 RS256 妥善保管私钥 信息最小化 :不要在 JWT 中存储敏感信息 设置合理有效期 :使用 exp 声明设置短期有效的 JWT 使用 HTTPS :防止 JWT 在传输过程中被窃取 实施令牌撤销机制 :对于敏感操作,提供令牌撤销能力 5. 参考工具 jwt.io - JWT 调试和验证工具 PyJWT - Python 的 JWT 库 John the Ripper - 可用于暴力破解弱密钥 jwt_ tool - 专门的 JWT 测试工具 6. 总结 JWT 作为一种广泛使用的身份验证机制,如果配置不当会带来严重的安全风险。安全人员应充分了解 JWT 的各种攻击技术,并在实现时采取相应的防御措施。特别要注意算法选择、密钥管理和信息保护等关键方面。