JWT 原理与设计上的缺陷及利用(基础篇)
字数 2238 2025-08-11 22:57:12

JSON Web Token (JWT) 原理与安全实践

1. JWT 基本概念

JSON Web Token (JWT) 是一个开放标准 (RFC 7519),定义了一种紧凑且自包含的方式,用于在各方之间以 JSON 对象的形式安全传输信息。JWT 可以被验证和信任,因为它是数字签名的。

主要特点:

  • 紧凑:JWT 数据体积小,可通过 URL、POST 参数或 HTTP 头部发送
  • 自包含:负载中包含所有必要信息,避免了多次查询数据库
  • 可签名:可使用 HMAC 算法或 RSA/ECDSA 公钥/私钥对进行签名

2. JWT 与传统 Session 认证对比

基于 Session 的认证流程:

  1. 用户提供用户名和密码进行认证
  2. 服务器验证后创建 session 并保存用户身份数据
  3. 服务器生成 session_id 放入 Cookie 返回给用户
  4. 用户后续请求携带 Cookie,服务器通过 session_id 识别用户

Session 认证的缺点

  • 服务器需保存大量 session,增加开销
  • 扩展性差,不适用于分布式站点的单点登录(SSO)
  • 易受 CSRF 攻击

基于 JWT 的认证流程:

  1. 用户通过 POST 请求发送用户名和密码
  2. 服务器验证后生成包含用户标识的 JWT 对象
  3. 服务器使用 secret 对 JWT 签名并发送给用户
  4. 用户后续请求携带 JWT(通常放在 HTTP 头的 Authorization 字段)

JWT 优势

  • 无状态,服务器不需要存储 session
  • 适合分布式系统和跨域认证
  • 减少数据库查询

3. JWT 结构解析

JWT 由三部分组成,以点(.)分隔:Header.Payload.Signature

3.1 Header (头部)

示例:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

Base64URL 解码后:

{
  "alg": "HS256",
  "typ": "JWT"
}

Header 参数

  • alg:签名算法(默认 HMAC SHA256,简写 HS256)
  • typ:令牌类型(固定为 JWT)

3.2 Payload (负载)

示例:eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ

Base64URL 解码后:

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

标准声明字段(可选)

  • iss (issuer):签发人
  • exp (expiration time):过期时间
  • sub (subject):主题(JWT 面向的用户)
  • aud (audience):受众(接收 JWT 的一方)
  • nbf (Not Before):生效时间
  • iat (Issued At):签发时间(Unix 时间戳)
  • jti (JWT ID):唯一标识,用于防止重放攻击

Base64URL 编码特点

  • 去掉填充的 =
  • + 替换为 -
  • / 替换为 _

3.3 Signature (签名)

示例:SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

签名计算方式

HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secret
)

签名用于验证消息在传递过程中未被篡改,只有持有 secret 的一方才能生成有效签名。

4. JWT 的安全问题与防护

4.1 JWT 的固有缺点

  • 无法在使用过程中废止某个 token(除非服务器部署额外逻辑)
  • 一旦签发,在到期前始终有效
  • 默认不加密,负载信息可能泄露

4.2 安全建议

  1. 使用 HTTPS 传输 JWT
  2. 设置较短的有效期
  3. 重要权限操作时重新认证用户
  4. 避免在负载中存储敏感信息

4.3 常见攻击方式及防御

攻击1:未经验证的签名绕过

漏洞原理:后端未验证 JWT 签名,攻击者可修改 Payload 实现越权

利用步骤

  1. 获取普通用户的 JWT
  2. 修改 Payload 中的用户身份字段(如 sub 改为 administrator
  3. 使用修改后的 JWT 访问特权功能

防御措施

  • 服务端必须验证 JWT 签名
  • 使用强密钥保护签名

攻击2:弱密钥爆破

漏洞原理:使用弱密钥或常见密钥签名 JWT,可被暴力破解

利用步骤

  1. 获取目标 JWT
  2. 使用 hashcat 等工具爆破 secret:
    hashcat -a 0 -m 16500 <JWT_token> <dictionary_file>
    
  3. 获取 secret 后生成管理员 JWT

防御措施

  • 使用足够长且随机的密钥(至少 256 位)
  • 定期更换密钥
  • 避免使用常见词汇作为密钥

5. JWT 安全实践指南

5.1 开发实践

  • 始终验证签名
  • 检查过期时间(exp
  • 验证签发者(iss)和受众(aud
  • 使用适当的算法(避免 none 算法)

5.2 密钥管理

  • 密钥长度至少 256 位
  • 定期轮换密钥
  • 不同环境使用不同密钥
  • 密钥安全存储(不在代码中硬编码)

5.3 传输安全

  • 优先放在 Authorization 头中
  • 避免放在 URL 中
  • 必须使用 HTTPS

5.4 失效处理

  • 设置合理的短有效期
  • 实现黑名单机制(针对需要提前失效的场景)
  • 敏感操作要求重新认证

6. 总结

JWT 是一种强大的无状态认证机制,但必须正确实现才能确保安全。开发者需要:

  1. 充分理解 JWT 的结构和工作原理
  2. 实现完整的验证逻辑(签名、过期时间等)
  3. 遵循安全最佳实践(密钥管理、传输安全等)
  4. 定期进行安全审计和测试

通过合理的设计和实现,JWT 可以成为构建安全、可扩展的分布式认证系统的有力工具。

JSON Web Token (JWT) 原理与安全实践 1. JWT 基本概念 JSON Web Token (JWT) 是一个开放标准 (RFC 7519),定义了一种紧凑且自包含的方式,用于在各方之间以 JSON 对象的形式安全传输信息。JWT 可以被验证和信任,因为它是数字签名的。 主要特点: 紧凑:JWT 数据体积小,可通过 URL、POST 参数或 HTTP 头部发送 自包含:负载中包含所有必要信息,避免了多次查询数据库 可签名:可使用 HMAC 算法或 RSA/ECDSA 公钥/私钥对进行签名 2. JWT 与传统 Session 认证对比 基于 Session 的认证流程: 用户提供用户名和密码进行认证 服务器验证后创建 session 并保存用户身份数据 服务器生成 session_ id 放入 Cookie 返回给用户 用户后续请求携带 Cookie,服务器通过 session_ id 识别用户 Session 认证的缺点 : 服务器需保存大量 session,增加开销 扩展性差,不适用于分布式站点的单点登录(SSO) 易受 CSRF 攻击 基于 JWT 的认证流程: 用户通过 POST 请求发送用户名和密码 服务器验证后生成包含用户标识的 JWT 对象 服务器使用 secret 对 JWT 签名并发送给用户 用户后续请求携带 JWT(通常放在 HTTP 头的 Authorization 字段) JWT 优势 : 无状态,服务器不需要存储 session 适合分布式系统和跨域认证 减少数据库查询 3. JWT 结构解析 JWT 由三部分组成,以点(.)分隔: Header.Payload.Signature 3.1 Header (头部) 示例: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 Base64URL 解码后: Header 参数 : alg :签名算法(默认 HMAC SHA256,简写 HS256) typ :令牌类型(固定为 JWT) 3.2 Payload (负载) 示例: eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ Base64URL 解码后: 标准声明字段(可选) : iss (issuer):签发人 exp (expiration time):过期时间 sub (subject):主题(JWT 面向的用户) aud (audience):受众(接收 JWT 的一方) nbf (Not Before):生效时间 iat (Issued At):签发时间(Unix 时间戳) jti (JWT ID):唯一标识,用于防止重放攻击 Base64URL 编码特点 : 去掉填充的 = + 替换为 - / 替换为 _ 3.3 Signature (签名) 示例: SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c 签名计算方式 : 签名用于验证消息在传递过程中未被篡改,只有持有 secret 的一方才能生成有效签名。 4. JWT 的安全问题与防护 4.1 JWT 的固有缺点 无法在使用过程中废止某个 token(除非服务器部署额外逻辑) 一旦签发,在到期前始终有效 默认不加密,负载信息可能泄露 4.2 安全建议 使用 HTTPS 传输 JWT 设置较短的有效期 重要权限操作时重新认证用户 避免在负载中存储敏感信息 4.3 常见攻击方式及防御 攻击1:未经验证的签名绕过 漏洞原理 :后端未验证 JWT 签名,攻击者可修改 Payload 实现越权 利用步骤 : 获取普通用户的 JWT 修改 Payload 中的用户身份字段(如 sub 改为 administrator ) 使用修改后的 JWT 访问特权功能 防御措施 : 服务端必须验证 JWT 签名 使用强密钥保护签名 攻击2:弱密钥爆破 漏洞原理 :使用弱密钥或常见密钥签名 JWT,可被暴力破解 利用步骤 : 获取目标 JWT 使用 hashcat 等工具爆破 secret: 获取 secret 后生成管理员 JWT 防御措施 : 使用足够长且随机的密钥(至少 256 位) 定期更换密钥 避免使用常见词汇作为密钥 5. JWT 安全实践指南 5.1 开发实践 始终验证签名 检查过期时间( exp ) 验证签发者( iss )和受众( aud ) 使用适当的算法(避免 none 算法) 5.2 密钥管理 密钥长度至少 256 位 定期轮换密钥 不同环境使用不同密钥 密钥安全存储(不在代码中硬编码) 5.3 传输安全 优先放在 Authorization 头中 避免放在 URL 中 必须使用 HTTPS 5.4 失效处理 设置合理的短有效期 实现黑名单机制(针对需要提前失效的场景) 敏感操作要求重新认证 6. 总结 JWT 是一种强大的无状态认证机制,但必须正确实现才能确保安全。开发者需要: 充分理解 JWT 的结构和工作原理 实现完整的验证逻辑(签名、过期时间等) 遵循安全最佳实践(密钥管理、传输安全等) 定期进行安全审计和测试 通过合理的设计和实现,JWT 可以成为构建安全、可扩展的分布式认证系统的有力工具。