ToolAct工具行动

JWT 解析工具

解码和验证 JSON Web Token,查看 Header、Payload 和 Signature

JWT Token

示例 JWT

什么是 JWT?

JWT (JSON Web Token) 是一种开放标准 (RFC 7519),用于在各方之间安全地传输信息。JWT 由三部分组成,用点号分隔:Header(头部)包含令牌类型和签名算法,Payload(载荷)包含声明数据,Signature(签名)用于验证令牌完整性。JWT 常用于身份认证和信息交换场景。 安全相关结果不能孤立判断,还要结合密钥、使用场景、算法选择和可信来源一起评估。

使用方法

如何使用

  1. 将 JWT 粘贴到输入框中,工具会自动解析并显示 Header 和 Payload 内容
  2. 点击彩色标签可复制对应的 Base64 编码部分
  3. 在签名验证区域输入密钥以验证签名是否正确(支持 HS256/HS384/HS512 算法)
  4. 关键信息区域显示常见声明的解码值,过期状态以颜色区分。

安全提示

  • 此工具在浏览器中本地运行,Token 不会发送到任何服务器
  • JWT 仅对数据进行编码和签名,并非加密,任何人都可解码查看内容。
  • 请勿在 JWT 中存储敏感信息(如密码、信用卡号等)
  • 生产环境中请始终使用 HTTPS 传输 JWT

使用场景

认证调试时阅读令牌内容粘贴三段式 JWT (Header.Payload.Signature),分别查看 Base64URL 解码后的头部和载荷,与签名段独立。iss、aud、sub、iat、nbf、exp 等标准声明会同时显示 Unix 秒数和可读日期,方便排查登录和会话问题。令牌始终留在浏览器标签页内。
在本地校验 HMAC 签名对于 HS256、HS384 和 HS512 令牌,输入共享密钥即可对 header_b64 + '.' + payload_b64 重新计算 HMAC-SHA256/384/512,并与签名段对比。在跨环境比对、排查密钥轮换或确认令牌未被篡改时非常实用。粘贴的密钥仅用于本地 HMAC 计算,不会发送到服务器。
分享日志前检查过期时间和声明详情工具会高亮已过期的令牌(exp < 当前时间),并显示 nbf / iat 的边界信息,因此「签名正确但尚未生效」的令牌也会被标出。可以复制原始部分或格式化后的 JSON。由于解码和 HMAC 验证都在浏览器中完成,敏感的 Bearer 令牌无需发送到外部解码服务即可检查。
查看公钥签名 token(本地不验证签名)粘贴 RS256、PS256 或 ES256 签名的 token,可以查看解码后的 header 与 payload。本工具仅在本地验证 HMAC(HS256/HS384/HS512)签名,RSA / RSA-PSS / ECDSA 的签名验证必须在持有对应公钥的服务端进行(通常通过发行方的 JWKS 端点加载)。适合在排查 OAuth 回调时,仅用本地标签页查看 token 声明的内容。
发现算法混淆和缺失 exp 声明解码视图会并列显示 header.alg 和标准声明,让以下情况一目了然:令牌声称 HS256 但服务端期望 RS256(经典的算法替换攻击)、alg 为 none、或 exp、nbf、iat 缺失。在令牌到达可能静默降级校验的认证库之前,先在浏览器中捕获这些不匹配。

技术原理

JWT (JSON Web Token, RFC 7519) 由三部分组成——Header.Payload.Signature——用英文句点 '.' 连接。 Header:描述令牌类型和签名算法,例如 {"alg":"HS256","typ":"JWT"}。alg 决定 Signature 的计算方式,常见的有 HS256 (HMAC-SHA256)、RS256 (RSA-SHA256)、ES256 (ECDSA-SHA256) 和 none(无签名——生产环境禁止使用)。 Payload:也称为 claims,是一组 JSON 字段。RFC 7519 定义了 7 个标准注册声明:iss(签发者)、sub(主题,通常是用户 ID)、aud(受众)、exp(过期时间)、nbf(生效时间)、iat(签发时间)和 jti(唯一标识)。开发者可以在此基础上添加任意私有字段,如 userId、role、tenant 等。 Signature:将 Header 和 Payload 进行 Base64URL 编码后用句点连接,然后使用 alg 指定的算法和密钥进行签名。HS256 使用 HMAC-SHA256(secret, header_b64 + '.' + payload_b64);RS256 使用 RSA 私钥签名。接收方用相同的方式重新计算签名并验证是否匹配。 Base64URL 与标准 Base64 的区别:'+' 变为 '-','/' 变为 '_',末尾的 '=' 填充被丢弃,这样编码结果可以直接放在 URL 路径和查询字符串中而不会触发百分号编码。需要注意的是 Base64URL 仅是一种编码方式,不提供加密或安全性,任何人都能解码并读取 Payload 内容。 安全边界:JWT 只保证「未被篡改」,不保证「内容是敏感的」。一个常见的错误是将用户手机号、身份证号或密码哈希放入 Payload,这些信息对所有人可见。

  • 三段式结构:Header.Payload.Signature,每段均 Base64URL 编码;签名为 HMAC(secret, header_b64 + '.' + payload_b64) 或 RSA(privateKey, 同一输入)。
  • Base64URL 将 '+' 换为 '-','/' 换为 '_',并丢弃末尾的 '=' 填充,因此编码结果可以直接放在 URL 中(不会触发百分号编码)。
  • 本工具仅在本地验证 HMAC 系列签名(HS256/HS384/HS512)。RS256、ES256 等非对称算法需要发行方 JWKS 端点提供的公钥,签名验证必须在持有公钥的服务端完成——页面仍可解码 header 与 payload,但无法验证签名。
  • 标准声明:iss(签发者)、sub(主题)、aud(受众)、exp(过期时间,Unix 秒级时间戳)、nbf(生效时间)、iat(签发时间)、jti(JWT ID,防重放)。
  • alg=none 攻击:必须严格校验 alg 字段并拒绝 none 算法,否则攻击者可伪造任意令牌;同时还需防止算法替换攻击(用公钥作为密钥验证 HS256 令牌)。
  • JWT 不是加密的:Payload 是明文 Base64URL 编码,而非加密;对机密内容应使用 JWE (JSON Web Encryption),但实际做法通常是将敏感数据保存在后端,通过 sub 字段引用。

示例

标准 HS256 Token

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkphbmUgRG9lIiwiaWF0IjoxNzA1MzEyODAwLCJleHAiOjE3MDUzMTY0MDB9.znHapMygT8K8YZN4K8zM1sV3bKlQ5pY3xE2gR4wN1vM

Header:  {"alg":"HS256","typ":"JWT"}
Payload: {"sub":"1234567890","name":"Jane Doe","iat":1705312800,"exp":1705316400}
RFC: RFC 7519 第 3 节定义了注册声明名(sub、iat、exp)

已过期的 Token

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyLTEyMyIsImV4cCI6MTYwMDAwMDAwMH0.OxQ0fUKW0z4mK0xJ4vF0uF7eZB9wK3yF8pL2nQ6tX1k

Header:  {"alg":"HS256","typ":"JWT"}
Payload: {"sub":"user-123","exp":1600000000}
状态:已过期(exp < 当前时间)
说明:exp 声明使用 NumericDate(自 Unix 纪元起的秒数,详见 RFC 7519 第 2 节)

包含自定义声明的用户信息 Token

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyLTQ1NiIsIm5hbWUiOiJBbGljZSIsInJvbGUiOiJhZG1pbiIsInRlbmFudCI6ImFjbWUiLCJpYXQiOjE3MDUzMTI4MDAsImV4cCI6MTcwNTMxNjQwMCwiYXVkIjoiYXBpLmV4YW1wbGUuY29tIn0.7Hk2L9oP3qR1mN4vK8xJ2wE5yT6sB0fA9cZ1dG3hI4U

Header:  {"alg":"HS256","typ":"JWT"}
Payload: {"sub":"user-456","name":"Alice","role":"admin","tenant":"acme","iat":1705312800,"exp":1705316400,"aud":"api.example.com"}
说明:role、tenant 属于私有声明,未在 RFC 7519 中定义

JWT 实现安全检查清单

1. 切勿在 payload 中存放敏感信息——JWT 只是编码,并未加密
2. HS256 使用足够强度的密钥(至少 256 位 / 32 个随机字符)
3. 多服务架构下优先选用 RS256/ES256,便于公钥验签
4. 校验 alg 头部,拒绝 'none' 或非预期算法
5. 信任 Token 前先校验 exp、nbf、iat 时间戳
6. 校验 aud 与本服务一致,避免 Token 被跨应用复用
7. 存放在 HttpOnly Cookie 中,避免 localStorage 被 XSS 利用

RFC: RFC 8725(JWT 最佳实践)涵盖了上述安全要点

常见问题

JWT 由哪三部分组成?

头部、载荷和签名,三者用点分隔。头部声明签名算法和 token 类型;载荷承载声明,如 sub、iss、aud、iat、exp 以及任意自定义数据;签名让验证方确认 token 未被篡改。头部和载荷是 Base64URL 编码的 JSON——只是签名,不是加密。

JWT 是加密的吗?

不是——常见的 JWS 格式 JWT 仅签名而未加密。任何截获到 token 的人都能 Base64URL 解码头部和载荷,看到包括用户 ID、邮箱、角色在内的所有声明。请把 JWT 内容视为公开信息,绝不要把密码或机密放进载荷。JWE(加密 JWT)虽然存在,但远不如 JWS 常用。

各标准声明分别表示什么?

iss = 签发方;sub = 主题(通常是用户 ID);aud = 受众(预期接收方);exp = 过期时间(Unix 秒);nbf = 生效时间;iat = 签发时间;jti = 用于吊销的唯一 token ID。它们在 RFC 7519 中定义。可自由添加自定义声明——建议加上厂商前缀以避免命名冲突。

如何验证 JWT?

读取头部的 alg,使用对应密钥(HS256 用共享密钥,RS256/ES256 用从签发方 JWKS 端点获取的公钥),对编码后的 header.payload 重新计算签名并比对。然后检查 exp、nbf、iss 和 aud。如果 alg 是 'none',或与服务端预期不一致,应直接拒绝。 本工具仅在本地验证 HS256/HS384/HS512 共享密钥签名;RS256/ES256 的签名校验必须在持有公钥的服务端完成。

验证是在浏览器中完成的吗?

是的。页面在本地解析 JWT,并使用浏览器内执行的 JavaScript HMAC 验证 HS256/HS384/HS512 签名。Token 不会发送到我们的服务器,但请记住 JWT 本身设计用于在 URL 与 HTTP 头中传递——任何被复制的 JWT 都有可能出现在日志中。

为什么 alg=none 危险?

RFC 7519 允许 alg=none 表示无签名 token。存在漏洞的验证器可能会接受这种没有签名的 token,攻击者就能伪造任意载荷。现代库默认拒绝 alg=none;如果你自己实现验证,请在代码中硬编码预期算法,而不是信任头部。

JWT 能多大?

协议没有上限,但 JWT 通常会出现在 HTTP 头部(Authorization: Bearer ...)中,许多服务器把头部上限设在 8 KB 左右。把过多声明塞进 JWT 会让每次请求都变胖。如果需要存大量会话状态,请使用服务端会话,并在 JWT 中只放一个小的引用 token。