Decoding is not verifying
A JWT has three parts separated by dots: a header, a payload, and a signature. The header and payload are just Base64URL-encoded JSON — anyone can decode them. The signature is a cryptographic check computed over the header+payload using a secret (HMAC) or private key (RSA/ECDSA).
This tool decodes. It does not verify. Verification requires the issuer's signing key.
You should never paste that key into a website — use your language's JWT library (jsonwebtoken
in Node, PyJWT in Python, jose in most stacks) on your server, where the key
already lives.
A decoded JWT proves nothing about authenticity. Never trust a decoded token's claims without verifying the signature first. Pen-testers and attackers can create fake tokens that decode perfectly fine.
How to use the JWT decoder
- Paste your JWT into the input box. All three dot-separated parts must be present.
- The header and payload decode live (200ms debounce).
- The claim summary surfaces the most useful fields: algorithm, issuer, audience, subject, iat/nbf/exp with human-readable times.
- EXPIRED / NOT YET ACTIVE labels appear when the current time is outside the token's window.
Privacy
Every byte of processing happens in your browser. Open DevTools → Network and paste a token: no request is sent. You can disconnect from the internet and the tool keeps working. The source is on GitHub for inspection.
Even so — if a token contains production credentials, PII, or API keys, be conscious that pasting into any browser tab leaves traces (browser history, clipboard managers, auto-save). For genuinely sensitive tokens, decode locally via CLI instead.
Standard JWT claims, explained
RFC 7519 defines seven registered claim names. The decoder surfaces each when present:
- iss (issuer) — who issued the token. A URL or identifier. Verify this matches your expected issuer.
- sub (subject) — the token's principal, usually a user ID.
- aud (audience) — who the token is for. Verify this matches your API/client.
- exp (expiration) — Unix timestamp after which the token is invalid. Always check this.
- nbf (not before) — Unix timestamp before which the token is not yet valid.
- iat (issued at) — Unix timestamp when the token was created.
- jti (JWT ID) — unique identifier, useful for revocation lists.
Everything outside those seven is a custom claim — app-specific data like role, email, tenant ID, scopes. There's no standard format; it's whatever your issuer put there.
Header claims you should recognize
- alg — signing algorithm.
HS256,RS256,ES256are common.noneis a legendary security disaster — never accept. - typ — token type. Usually
JWT. Newer specs useat+jwtfor OAuth 2.0 access tokens. - kid — key ID. When an issuer rotates keys,
kidtells your verifier which key to use from their JWKS. - jku / jwk — embedded key URL / key. Security-sensitive; never trust without strict allowlisting.
JWT security pitfalls
The "alg: none" attack
If your JWT library accepts alg: none, an attacker can create tokens with no signature that pass
verification. Always validate the alg against an allowlist — e.g., only RS256.
HS256 vs RS256 key confusion
If your verifier accepts both symmetric (HS*) and asymmetric (RS*, ES*) algorithms with the same key lookup, an attacker can sign a token with your public key using HS256 and your verifier will accept it. Lock the algorithm per issuer.
Missing exp check
Some JWT libraries verify the signature but don't check exp unless you ask. Always verify
expiration. Old tokens are replay fodder.
Unvalidated jku / x5u
Headers that include a URL pointing to the signing key let the attacker choose the key. If your verifier
fetches jku without strict domain pinning, you're giving away signature verification.
Frequently asked questions
Can this tool verify my JWT?
Intentionally no. Verifying HS256 requires the shared secret; RS256/ES256 require the public key. Pasting secrets into web forms is a bad habit even when the site is client-side — verify server-side with your JWT library instead.
What's the difference between JWT, JWS, and JWE?
JWT is the claim format. JWS is the signed envelope (what you usually see — three dot-separated parts). JWE is the encrypted envelope (five parts, rare). This tool handles JWS. JWE would be opaque to any decoder that lacks the decryption key.
Why is my token's signature 512+ characters?
Longer signatures indicate asymmetric algorithms (RS256 signatures are ~344 chars, RS512 ~683 chars). HS256 signatures are 43 chars (Base64URL of a 32-byte HMAC). Length is a quick way to eyeball the algo.
The decoder shows "not yet active." Is my token broken?
Your token has an nbf (not-before) claim set to a future time. Either the issuer set it
wrong, or your clock is behind the issuer's. Check Date.now() vs nbf * 1000.
Clock-skew tolerance is typically 30–60 seconds in real verifiers.
My token shows "EXPIRED" but my API still accepts it. Why?
Your API isn't checking exp, your API's clock is wrong, or your API is caching a prior
successful verification. All three are bugs — fix the server, not the token.
Related tools
- JSON Formatter — Format, validate, and beautify JSON online. 100% client-side — your data never leaves your browser.
- Base64 Encoder / Decoder — Encode and decode Base64 strings and files. Client-side, safe for sensitive data.
- URL Encoder / Decoder — Percent-encode and decode URLs per RFC 3986.
- Hash Generator — Generate MD5, SHA-1, SHA-256, and SHA-512 hashes client-side.
Further reading
Pillar
Part of Encoding & Crypto — Base64, URL, JWT, hashes, UUID, QR, password.
Written and maintained by Mian Ali Khalid. Last updated 2026-04-25.