JWT 解析工具
解码和验证 JSON Web Token,查看 Header、Payload 和 Signature
示例 JWT
什么是 JWT?
JWT (JSON Web Token) 是一种开放标准 (RFC 7519),用于在各方之间安全地传输信息。JWT 由三部分组成,用点号分隔:Header(头部)包含令牌类型和签名算法,Payload(载荷)包含声明数据,Signature(签名)用于验证令牌完整性。JWT 常用于身份认证和信息交换场景。 安全相关结果不能孤立判断,还要结合密钥、使用场景、算法选择和可信来源一起评估。
使用方法
如何使用
- 将 JWT 粘贴到输入框中,工具会自动解析并显示 Header 和 Payload 内容
- 点击彩色标签可复制对应的 Base64 编码部分
- 在签名验证区域输入密钥以验证签名是否正确(支持 HS256/HS384/HS512 算法)
- 关键信息区域显示常见声明的解码值,过期状态以颜色区分。
安全提示
- 此工具在浏览器中本地运行,Token 不会发送到任何服务器
- JWT 仅对数据进行编码和签名,并非加密,任何人都可解码查看内容。
- 请勿在 JWT 中存储敏感信息(如密码、信用卡号等)
- 生产环境中请始终使用 HTTPS 传输 JWT
使用场景
技术原理
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。