JWT的签名绕过与密钥混淆攻击详解
字数 2391 2025-12-05 17:58:37

JWT的签名绕过与密钥混淆攻击详解

描述
JSON Web Token (JWT) 是一种开放标准(RFC 7519),用于在网络应用间安全地传输声明信息。它通常用于身份验证和授权。JWT由三部分组成:头部(Header)、载荷(Payload)和签名(Signature),各部分用点号分隔。JWT的安全性依赖于签名的完整性验证。然而,如果实现或验证逻辑存在缺陷,攻击者可能通过签名绕过或密钥混淆等手段伪造有效令牌,从而提升权限或冒充其他用户。本知识点将深入解析JWT的签名绕过攻击(如"alg:none"攻击、弱密钥破解、密钥混淆等)的原理、步骤及防御措施。

解题过程
注意:以下过程基于攻击者视角分析漏洞,旨在帮助理解并防御此类攻击。实际操作需在授权环境中进行。

步骤1:理解JWT结构与签名机制

  1. JWT结构:

    • 头部:包含令牌类型(typ)和签名算法(alg),如HMAC SHA256(HS256)或RSA(RS256)。示例:{"alg":"HS256","typ":"JWT"},经Base64Url编码形成第一部分。
    • 载荷:包含声明(claims),如用户ID、过期时间等。示例:{"sub":"user123","exp":1625097600},经Base64Url编码形成第二部分。
    • 签名:对编码后的头部和载荷,使用密钥和指定算法生成签名,确保令牌未被篡改。
      最终令牌格式:Base64Url(Header).Base64Url(Payload).Signature
  2. 签名验证流程:

    • 服务器接收到JWT后,解码头部获取算法(alg)。
    • 使用预共享密钥(HS256)或公钥(RS256)重新计算签名。
    • 比较计算出的签名与令牌中的签名是否一致,不一致则拒绝令牌。

步骤2:识别JWT实现中的常见漏洞点
攻击者需先获取一个JWT(如通过登录或网络截获),然后分析其弱点:

  1. 算法指定漏洞:服务器可能依赖头部中的alg字段选择验证逻辑,而未强制使用预期算法。
  2. 密钥管理问题:使用默认密钥、弱密钥或密钥暴露。
  3. 验证逻辑缺陷:未验证签名、接受无签名令牌或混淆算法与密钥的对应关系。

步骤3:执行"alg:none"签名绕过攻击

  1. 原理:某些JWT库为支持无签名的令牌(用于调试),在alg为"none"时会跳过签名验证。如果服务器未禁用此算法,攻击者可伪造令牌。
  2. 步骤:
    a. 截获合法JWT,解码头部和载荷(可用在线工具如jwt.io)。
    b. 修改头部为{"alg":"none","typ":"JWT"},并移除签名部分。
    c. 将载荷修改为攻击内容(如将用户角色改为"admin")。
    d. 生成新令牌:Base64Url(新头部).Base64Url(新载荷).(签名部分留空)。
    e. 将新令牌发送给服务器,如果服务器接受,则绕过签名验证。
  3. 注意:需确保服务器不检查签名存在性。现代库多已修复,但老旧系统可能受影响。

步骤4:弱密钥破解攻击(针对HS256算法)

  1. 原理:HS256为对称加密,使用同一密钥签名和验证。如果密钥强度弱(如短字符串、常见单词),攻击者可暴力破解。
  2. 步骤:
    a. 获取JWT的头部和载荷(签名不需要)。
    b. 使用工具(如hashcat、jwt-tool)进行离线字典攻击:用候选密钥重新计算签名,与JWT中的签名比对。
    c. 常用字典包括:默认密钥("secret"、"password")、短数字、常见单词表。
    d. 破解后,用该密钥签名伪造令牌。
  3. 增强攻击:结合已知密钥列表(如GitHub泄露的密钥)或针对特定应用模式(如密钥为应用名)生成字典。

步骤5:密钥混淆攻击(Key Confusion)

  1. 原理:当服务器预期使用非对称算法(如RS256)时,公钥用于验证签名,私钥用于生成签名。如果服务器错误地将公钥用于HS256验证,攻击者可利用公钥作为HMAC密钥伪造令牌。
  2. 步骤:
    a. 获取服务器的公钥(可能通过证书端点、JS文件或公开信息)。
    b. 修改JWT头部,将alg从"RS256"改为"HS256"。
    c. 使用公钥作为HMAC密钥,重新计算签名。
    d. 发送伪造的令牌(算法为HS256,签名用公钥生成)。
    e. 如果服务器混淆算法,误用公钥验证HS256签名,则接受令牌。
  3. 关键:服务器必须存在验证逻辑缺陷——即使用头部中的alg值选择验证方式,而非强制使用配置的算法。

步骤6:其他进阶攻击手法

  1. 无效签名绕过:少数服务器仅检查签名格式而非有效性,或错误处理签名验证异常(如捕获异常后默认通过)。
  2. 时间攻击:利用签名验证的时间差异(时序攻击)推测密钥,但实际难度较高。
  3. 嵌套令牌攻击:针对JWS/JWE嵌套结构,通过解析不一致性绕过。
  4. 头部参数注入:篡改头部其他参数(如jwkkid)指向攻击者控制的密钥。

步骤7:防御措施

  1. 强制验证算法:服务器应忽略JWT头部的alg,强制使用预期算法(如只接受RS256)。
  2. 使用强密钥:HS256密钥需足够长且随机(如32字节);RS256私钥安全存储,公钥可分发。
  3. 禁用危险算法:明确禁用"none"算法及弱算法(如HS128)。
  4. 密钥管理:定期轮换密钥,避免硬编码或默认密钥。
  5. 完整验证:检查签名存在性、有效期、发行者等声明。
  6. 使用最新库:避免有漏洞的JWT库(如早期版本的python-jwt、node-jsonwebtoken)。
  7. 日志监控:记录令牌验证失败,检测异常攻击尝试。

总结
JWT签名绕过与密钥混淆攻击的核心在于利用验证逻辑的不严谨性。防御的关键是“不信任用户输入”——即使对JWT头部也应保持怀疑,并在服务器端实施严格算法控制和密钥管理。通过理解攻击步骤,开发者可更有效地加固身份验证机制。

JWT的签名绕过与密钥混淆攻击详解 描述 JSON Web Token (JWT) 是一种开放标准(RFC 7519),用于在网络应用间安全地传输声明信息。它通常用于身份验证和授权。JWT由三部分组成:头部(Header)、载荷(Payload)和签名(Signature),各部分用点号分隔。JWT的安全性依赖于签名的完整性验证。然而,如果实现或验证逻辑存在缺陷,攻击者可能通过签名绕过或密钥混淆等手段伪造有效令牌,从而提升权限或冒充其他用户。本知识点将深入解析JWT的签名绕过攻击(如"alg:none"攻击、弱密钥破解、密钥混淆等)的原理、步骤及防御措施。 解题过程 注意:以下过程基于攻击者视角分析漏洞,旨在帮助理解并防御此类攻击。实际操作需在授权环境中进行。 步骤1:理解JWT结构与签名机制 JWT结构: 头部:包含令牌类型(typ)和签名算法(alg),如HMAC SHA256(HS256)或RSA(RS256)。示例: {"alg":"HS256","typ":"JWT"} ,经Base64Url编码形成第一部分。 载荷:包含声明(claims),如用户ID、过期时间等。示例: {"sub":"user123","exp":1625097600} ,经Base64Url编码形成第二部分。 签名:对编码后的头部和载荷,使用密钥和指定算法生成签名,确保令牌未被篡改。 最终令牌格式: Base64Url(Header).Base64Url(Payload).Signature 。 签名验证流程: 服务器接收到JWT后,解码头部获取算法(alg)。 使用预共享密钥(HS256)或公钥(RS256)重新计算签名。 比较计算出的签名与令牌中的签名是否一致,不一致则拒绝令牌。 步骤2:识别JWT实现中的常见漏洞点 攻击者需先获取一个JWT(如通过登录或网络截获),然后分析其弱点: 算法指定漏洞:服务器可能依赖头部中的 alg 字段选择验证逻辑,而未强制使用预期算法。 密钥管理问题:使用默认密钥、弱密钥或密钥暴露。 验证逻辑缺陷:未验证签名、接受无签名令牌或混淆算法与密钥的对应关系。 步骤3:执行"alg:none"签名绕过攻击 原理:某些JWT库为支持无签名的令牌(用于调试),在 alg 为"none"时会跳过签名验证。如果服务器未禁用此算法,攻击者可伪造令牌。 步骤: a. 截获合法JWT,解码头部和载荷(可用在线工具如jwt.io)。 b. 修改头部为 {"alg":"none","typ":"JWT"} ,并移除签名部分。 c. 将载荷修改为攻击内容(如将用户角色改为"admin")。 d. 生成新令牌: Base64Url(新头部).Base64Url(新载荷). (签名部分留空)。 e. 将新令牌发送给服务器,如果服务器接受,则绕过签名验证。 注意:需确保服务器不检查签名存在性。现代库多已修复,但老旧系统可能受影响。 步骤4:弱密钥破解攻击(针对HS256算法) 原理:HS256为对称加密,使用同一密钥签名和验证。如果密钥强度弱(如短字符串、常见单词),攻击者可暴力破解。 步骤: a. 获取JWT的头部和载荷(签名不需要)。 b. 使用工具(如hashcat、jwt-tool)进行离线字典攻击:用候选密钥重新计算签名,与JWT中的签名比对。 c. 常用字典包括:默认密钥("secret"、"password")、短数字、常见单词表。 d. 破解后,用该密钥签名伪造令牌。 增强攻击:结合已知密钥列表(如GitHub泄露的密钥)或针对特定应用模式(如密钥为应用名)生成字典。 步骤5:密钥混淆攻击(Key Confusion) 原理:当服务器预期使用非对称算法(如RS256)时,公钥用于验证签名,私钥用于生成签名。如果服务器错误地将公钥用于HS256验证,攻击者可利用公钥作为HMAC密钥伪造令牌。 步骤: a. 获取服务器的公钥(可能通过证书端点、JS文件或公开信息)。 b. 修改JWT头部,将 alg 从"RS256"改为"HS256"。 c. 使用公钥作为HMAC密钥,重新计算签名。 d. 发送伪造的令牌(算法为HS256,签名用公钥生成)。 e. 如果服务器混淆算法,误用公钥验证HS256签名,则接受令牌。 关键:服务器必须存在验证逻辑缺陷——即使用头部中的 alg 值选择验证方式,而非强制使用配置的算法。 步骤6:其他进阶攻击手法 无效签名绕过:少数服务器仅检查签名格式而非有效性,或错误处理签名验证异常(如捕获异常后默认通过)。 时间攻击:利用签名验证的时间差异(时序攻击)推测密钥,但实际难度较高。 嵌套令牌攻击:针对JWS/JWE嵌套结构,通过解析不一致性绕过。 头部参数注入:篡改头部其他参数(如 jwk 、 kid )指向攻击者控制的密钥。 步骤7:防御措施 强制验证算法:服务器应忽略JWT头部的 alg ,强制使用预期算法(如只接受RS256)。 使用强密钥:HS256密钥需足够长且随机(如32字节);RS256私钥安全存储,公钥可分发。 禁用危险算法:明确禁用"none"算法及弱算法(如HS128)。 密钥管理:定期轮换密钥,避免硬编码或默认密钥。 完整验证:检查签名存在性、有效期、发行者等声明。 使用最新库:避免有漏洞的JWT库(如早期版本的python-jwt、node-jsonwebtoken)。 日志监控:记录令牌验证失败,检测异常攻击尝试。 总结 JWT签名绕过与密钥混淆攻击的核心在于利用验证逻辑的不严谨性。防御的关键是“不信任用户输入”——即使对JWT头部也应保持怀疑,并在服务器端实施严格算法控制和密钥管理。通过理解攻击步骤,开发者可更有效地加固身份验证机制。