JWT Decoder
Decode JWT headers and payloads, explain each claim and verify signatures locally
JWT 令牌
令牌只在本机浏览器解码,不会发送到任何服务器。粘贴时多余的空格、引号与 Bearer 前缀会自动去除。
Header 头部
—
—
Payload 载荷
—
—
声明逐条解读
| 声明 | 值 | 含义与本工具的处理 |
|---|
值列保持令牌中的原始类型:字符串带引号、数字与布尔值不带。自定义声明无法逐一预置含义,会标注为业务方自定义字段。
时间戳换算
| 声明 | 本地时间 | 相对当前 |
|---|
签名验证
验签在浏览器内用 WebCrypto 完成,密钥不会离开本机。签名验证只证明「内容未被篡改」,令牌能不能用还要看有效期、签发者、受众与业务权限。
About this tool
Two questions dominate JWT debugging: what exactly is inside, and has it been altered. This tool answers both in the browser, so the token never goes to a third party.
- Three parts: header, payload and signature with decoded byte and character counts
- UTF-8: names and accented characters decode correctly by bytes, with no mojibake
- Claim explanations: registered claims, common OIDC claims and header parameters are explained, and custom fields are marked as application defined
- Validity: exp, nbf, iat and auth_time show local time, UTC ISO and a countdown that updates every second
- Local verification: HS256/384/512, RS256/384/512, PS256/384/512 and ES256/384/512, with keys processed by WebCrypto on the machine
- Key formats: PEM public keys and a single JWK both import; certificates and malformed input explain the reason instead of failing silently
- Messy input: a Bearer prefix, wrapping quotes, newlines and a trailing comma are removed; two-part tokens, empty signatures, alg none, non-JSON payloads and five-part JWE all get a specific message
- Sensitive fields: keys such as password, phone or ID number trigger a warning to look the value up on the server by ID instead
- Samples: valid, expired, verifiable RS256, alg none and non-JSON payload, ready to load
When to use it
- Check whether a token is expired or has the wrong audience when an API returns 401
- Inspect the roles and scopes in an id_token after login
- Verify that iss, aud, kid and the JWKS key match during third-party login integration
- Security review of servers that accept alg none or skip signature checks
- Teaching why a JWT prevents tampering but not reading
Claim reference
| Claim | Location | Must verify |
|---|---|---|
| alg | Header | Yes. Accept a fixed allowlist instead of trusting the algorithm the token declares, which is exactly how algorithm confusion attacks work |
| kid | Header | Use it to select a key, but take the key from your own JWKS, not from the address in jku |
| exp / nbf | Payload | Yes, with 30 to 60 seconds of clock skew tolerance |
| iss | Payload | Compare exactly; this is the most commonly missed check when environments share keys |
| aud | Payload | Yes. Skipping the audience lets a token issued for service A call service B |
| jti | Payload | Only useful with revocation or replay protection; expiry alone is usually not enough |
FAQ
- Does successful decoding mean the token is valid? No. Decoding is only Base64URL restoration, which anyone can do without a key. Validity requires the server to verify the signature, expiry, issuer and audience
- Why can the payload be read in plain text? A JWT is signed, not encrypted. For sensitive data use JWE, which this tool recognizes as five parts and reports as needing the private key, or keep only an ID in the payload
- Is alg none a vulnerability? There is no legitimate none verification flow. The risk is old libraries that verify using the algorithm the token declares, so an attacker can drop the signature and set alg to none to forge an identity
- HS256 or RS256? HMAC is simpler when one service signs and verifies its own tokens. When public keys must be distributed to many verifiers, such as microservices or an open platform, use RS256 or ES256 so a shared secret cannot leak
- Why does verification require a secure context? WebCrypto only runs on https or localhost. Over plain http on a LAN address the tool can decode but not verify
- Why is the exp time eight hours off from the docs? Timestamps in the token are UTC seconds, and the tool converts to your local zone, which is UTC+8 in China
To restore a single Base64URL section, use the Base64 tool; to turn exp seconds into a readable date, use the timestamp converter; to tidy the decoded JSON, use the JSON formatter. Tokens and keys stay in the browser, are never uploaded and are never logged.