赵泠 2025-07-22 13:25 采纳率: 97.9%
浏览 1
已采纳

JWT面试题:如何防范JWT令牌篡改和重放攻击?

在使用JWT(JSON Web Token)进行用户身份认证时,令牌的完整性和安全性至关重要。常见的安全威胁包括令牌篡改和重放攻击。请简述JWT是如何防止令牌被篡改的,并说明在实际应用中如何防范重放攻击?这两种攻击方式的本质区别是什么?JWT本身是否具备防重放机制?如果未做额外处理会带来什么风险?
  • 写回答

1条回答 默认 最新

  • Qianwei Cheng 2025-07-22 13:26
    关注

    一、JWT 如何防止令牌被篡改

    JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在网络应用环境间安全地传递声明(claims)。为了防止令牌被篡改,JWT 采用了数字签名机制。

    JWT 的结构分为三部分:

    1. Header(头部)
    2. Payload(载荷)
    3. Signature(签名)

    其中,签名部分是通过将 Header 和 Payload 使用 Header 中指定的算法(如 HMACSHA256)和密钥进行加密生成的。

    示例签名生成过程(伪代码):

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

    当客户端收到 JWT 后,服务端在每次验证时都会重新计算签名并与 JWT 中的签名比对。如果一致,则说明令牌未被篡改;否则,认为令牌已被修改,应拒绝请求。

    二、重放攻击及防范措施

    重放攻击(Replay Attack)是指攻击者截获合法用户发送的 JWT,并在之后的时间重复使用该令牌发起请求,从而冒充用户执行操作。

    JWT 本身 不具备防重放机制,因此在实际应用中需要额外措施来防范。

    常见的防范策略包括:

    • 使用短生命周期令牌:通过设置较短的过期时间(如 15 分钟),降低令牌被截获后被滥用的风险。
    • 结合刷新令牌机制:使用一个长期有效的刷新令牌(refresh token)来换取新的访问令牌(access token),刷新令牌通常存储在 HttpOnly Cookie 中,防止 XSS 截获。
    • 记录已使用令牌(黑名单机制):将已使用过的 JWT 加入黑名单,并在每次请求时检查令牌是否在黑名单中。黑名单可使用 Redis 等内存数据库实现。
    • 添加唯一标识符(nonce):在 JWT 的 payload 中加入一次性使用的随机字符串(nonce),服务器端记录该 nonce 并在后续请求中拒绝重复使用。

    三、篡改攻击与重放攻击的本质区别

    两种攻击方式的核心区别在于攻击目标和实现方式不同:

    攻击类型攻击目标攻击方式防护机制
    篡改攻击修改 JWT 内容(如用户角色)攻击者尝试修改 payload 或 header 并伪造签名签名验证机制
    重放攻击重复使用合法令牌攻击者直接使用截获的完整 JWT 发起请求黑名单、nonce、短生命周期、刷新令牌机制

    四、JWT 是否具备防重放机制?未做额外处理的风险

    JWT 本身 不提供防重放机制。它是一个无状态的认证方案,仅保证令牌内容的完整性与来源真实性。

    若未做额外处理,可能带来以下风险:

    • 用户身份被冒用:攻击者可在令牌有效期内反复使用截获的 JWT,执行非法操作。
    • 权限被非法提升:若令牌中包含权限字段,攻击者可尝试通过重放攻击获取更高权限。
    • 业务数据被非法访问或修改:攻击者可模拟用户访问敏感接口,造成数据泄露或篡改。
    • 系统审计失效:由于无法区分真实请求与重放请求,日志和审计系统将失去准确性。

    五、JWT 安全实践建议流程图

    以下是一个 JWT 安全认证流程的 Mermaid 图表示意:

    graph TD A[用户登录] --> B{验证凭据} B -- 成功 --> C[生成JWT + Refresh Token] C --> D[返回给客户端] D --> E[客户端存储Refresh Token] E --> F[发送JWT到API请求头] F --> G{验证JWT签名} G -- 有效 --> H{是否在黑名单中} H -- 是 --> I[拒绝请求] H -- 否 --> J[处理请求] G -- 无效 --> I J --> K[响应结果] K --> L[JWT即将过期] L --> M[使用Refresh Token请求新JWT] M --> N{验证Refresh Token} N -- 成功 --> O[生成新JWT] O --> P[返回新JWT] P --> Q[客户端更新JWT]
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已采纳回答 10月23日
  • 创建了问题 7月22日