JWT 解码与编码 — 解码、验证和签名 JSON Web Token

解码 JWT 的头部和载荷,用通俗语言显示过期时间,验证 HS、RS、PS 和 ES 签名,或签发新令牌。任何数据都不会离开浏览器。

头部
{
  "alg": "HS256",
  "typ": "JWT"
}
载荷
{
  "sub": "user_42",
  "name": "Ada Lovelace",
  "role": "admin",
  "iat": 1757320000,
  "exp": 1788856000
}
声明
sub主题user_42
nameAda Lovelace
roleadmin
iat签发时间1757320000
exp过期时间1788856000

示例令牌使用密钥 demo-secret-do-not-use 签名。

解码从不检查签名:任何人都能读取 JWT,只有签名能证明是谁签发的。HS* 令牌需要共享密钥;RS*、PS*、ES* 和 EdDSA 需要签发者的公钥(PEM、证书、JWK,或其 /.well-known/jwks.json 中的 JWKS,按 kid 匹配)。不要把生产环境的密钥或私钥粘贴到任何网页中,包括本页;请使用测试密钥。

令牌和密钥通过 WebCrypto 在你的浏览器中处理,绝不会发送到任何地方;尽管如此,粘贴的生产环境令牌或密钥仍应视为凭据。 浏览全部免费工具.

发现问题,或者觉得哪里可以更好?每条消息我们都会阅读,并尽快修复。

这款免费的 JWT 解码器可以显示 JSON Web Token 的头部、载荷和声明,把 exp、iat 和 nbf 转换为可读的日期并明确给出有效或已过期的判定,还能验证签名(HMAC 用密钥验证,RSA、RSA-PSS、ECDSA 和 Ed25519 用公钥、证书或 JWK 验证),并提供一个可以签发测试令牌的编码器。一切都在你的浏览器中完成——这一点对这个工具来说比大多数工具都重要:粘贴进来的令牌往往是有效的凭证,不应发送到任何人的服务器上,包括我们的。

JWT 由三段以点分隔的 Base64URL 组成:说明算法的头部、包含声明的载荷,以及签名。前两段只是编码而非加密,任何人都能读取;签名才是证明令牌由谁签发、未被篡改的依据。因此,能解码不等于可信,页面会始终清楚地体现这一区别。

使用方法

  1. 粘贴令牌。即使带有 Authorization 头中开头的“Bearer ”也没关系,会被自动去掉。
  2. 查看状态行:还有多久有效、从何时起已过期,或尚未生效。
  3. 检查载荷和声明表。时间类声明会以本地日期显示,并附上原始的 Unix 秒数。
  4. 要验证签名,输入密钥后点击“验证”:HS256/384/512 使用共享密钥;RS、PS、ES 和 EdDSA 令牌则使用签发方的公钥,可以是 PEM、证书、JWK 或整个 JWKS(按令牌的 kid 选择密钥)。
  5. 要创建令牌,切换到“编码并签名”,选择算法,编辑头部和载荷 JSON,输入密钥或粘贴 PKCS#8 私钥(也可以生成测试密钥对)。签名后,在解码器中打开它进行验证。
  6. 如果需要用于 bug 报告或测试数据,可以把载荷或头部复制为格式化的 JSON。

常见问题

在这里粘贴真实令牌安全吗?

令牌在你浏览器中用 JavaScript 解码,从不传输;即使断开网络,页面也能继续工作。话虽如此,请像对待密码一样对待生产环境的令牌:不要把它粘贴到任何你不信任的页面上,能用短期有效的测试令牌时尽量用测试令牌。

为什么不需要密钥就能读取载荷?

因为 JWT 是签名而不是加密的。载荷是经过 Base64URL 编码的 JSON,任何人都能解码。只有创建或验证签名时才需要密钥(或私钥)。除非使用加密版本 JWE(本工具不解码 JWE),否则不要把敏感数据放进 JWT 载荷。

exp、iat 和 nbf 是什么意思?

它们都是以秒为单位的 Unix 时间戳。exp 是令牌的过期时间;iat 是签发时间;nbf(not before)是最早生效的时间。验证方必须拒绝 exp 之后或 nbf 之前的令牌。这里的状态行会用当前时间同时套用这两条规则。

如何验证 RS256 或 ES256 令牌?

你需要签发方的公钥,而绝不是私钥。身份提供商会在 https://issuer/.well-known/jwks.json 这样的地址以 JWKS 形式发布公钥(Auth0、Okta、Cognito、Azure AD 和 Google 都是如此)。粘贴整个 JWKS,就会使用 kid 与令牌头部匹配的那把密钥;也可以粘贴单个 JWK、PEM 公钥(BEGIN PUBLIC KEY)或 X.509 证书。页面本身不会发起任何请求,所以请从浏览器中复制 JWKS。

可以在这里创建并签名 JWT 吗?

可以。“编码并签名”接收头部和载荷 JSON,用 HS256/384/512 加密钥签名,或用 RS、PS、ES、EdDSA 加 PKCS#8 PEM 格式(BEGIN PRIVATE KEY)的私钥签名。较旧的 BEGIN RSA PRIVATE KEY 文件是 PKCS#1 格式,可用 openssl pkcs8 -topk8 -nocrypt -in key.pem 转换。请只使用测试密钥:粘贴到任何网页上的生产签名密钥都应视为已泄露。

“alg: none”是什么意思?为什么会有警告?

它声明该令牌没有签名。历史上有些库会把这类令牌当作有效令牌接受,导致攻击者可以伪造任意载荷。配置正确的验证方会直接拒绝 alg none。如果你在真实系统中看到它,那就是一个安全问题,而不是什么新奇现象。

JWT 的结构

头部:{"alg":"HS256","typ":"JWT"} 告诉验证方用的是哪种签名算法。载荷:即声明,是一个 JSON 对象,包含签发方选择放入的任何内容,以及验证方能理解的注册声明(iss、sub、aud、exp、nbf、iat、jti)。签名:对 base64url(header).base64url(payload) 计算的 HMAC 或数字签名。载荷哪怕改动一个字符,签名就不再匹配——这正是签名的意义所在。

常见的 JWT 错误

• 不验证签名就信任载荷,或者用令牌中声明的算法而不是服务器预期的算法来验证(算法混淆)。

• 访问令牌有效期过长。exp 应设得较短(几分钟到一小时),较长的会话改用刷新令牌。

• 把个人数据或机密数据放进载荷;任何持有令牌的人都能读取。

• 在存在 XSS 风险的网站上把令牌存放在 localStorage 中。对于浏览器会话,httpOnly Cookie 更安全。

• 忘记检查 aud 和 iss,导致为某个服务签发的令牌可以被拿去重放攻击另一个服务。

• HMAC 密钥太短或由人随意设定。HS256 至少需要 256 位(32 个随机字节);可被猜到的密钥只需一个令牌就能被离线暴力破解。

该选择哪种签名算法

• HS256(HMAC-SHA256):同一个共享密钥既用于签名也用于验证。简单快速,但每个能验证的服务也都能签发令牌。适用于单一后端内部。

• RS256(RSA PKCS#1 v1.5 + SHA-256):支持最广泛的非对称方案;签发方保管私钥,其他各方用公钥验证。使用 2048 位密钥时签名为 256 字节。

• PS256(RSA-PSS):与 RS256 使用相同的密钥,但填充方案更现代;在所有使用方都支持时选用。

• ES256(ECDSA P-256):密钥小得多,签名仅 64 字节,安全性相当;在较新的系统中很常见,部分场景(Apple、与 WebAuthn 相关的 API)必须使用。

• EdDSA(Ed25519):签名快速且确定,越来越多的库开始支持;浏览器对它的支持比其他算法来得晚。

相关免费工具

  • Base64 编码 / 解码工具 — 把文本或文件编码为 Base64,把图片转成带 CSS 和 <img> 代码片段的 data URI,还能把 Base64 解码回可预览的文件。数据不会离开你的浏览器。
  • JSON 格式化 — 格式化、压缩和校验 JSON,解析错误精确到行和列。在浏览器中运行,无需上传。
  • 密码生成器 — 生成高强度随机密码、好记的密码短语或 PIN 码。完全在浏览器中运行,不发送、不存储任何内容。