Skip to content
100% in your browser. Nothing you paste is uploaded — all processing runs locally. Read more →

JWT Decoder

Paste a JWT. See the decoded header and payload, with claim explanations. Switch to the Verify tab to check the signature with a secret. Switch to Sign to generate test JWTs.

 
 
⚠ Use this for testing only. Don't sign production tokens with secrets you've pasted into a web tool.
 
🔒 100% client-side · uses your browser's Web Crypto API · no upload

What is a JWT?

A JSON Web Token is three base64url-encoded segments joined by dots: header.payload.signature. The header says how the token was signed. The payload contains claims (user identity, expiry, etc.). The signature lets the recipient verify both haven't been tampered with — but only if they have the right secret or public key.

The first two parts aren't secret. Anyone can base64-decode them. JWTs are tamper-evident, not encrypted. See What is a JWT? for the full story.

How this tool compares to jwt.io

jwt.io is the canonical JWT inspection tool — well-built, free, also client-side. This tool's differences:

Common use cases

The three parts in detail

Header

{
  "alg": "HS256",     // signing algorithm
  "typ": "JWT",       // type — almost always "JWT"
  "kid": "key-2026"   // optional: hint for key rotation
}

Payload (claims)

{
  "iss": "https://auth.example.com",   // issuer
  "sub": "user-12345",                 // subject
  "aud": "api.example.com",            // audience
  "exp": 1735689600,                   // expiry (Unix seconds)
  "iat": 1735603200,                   // issued at
  "scope": "read:users write:users",   // custom claim
  "email": "alice@example.com"         // custom claim
}

Signature

For HS256: HMAC-SHA256(base64url(header) + "." + base64url(payload), secret). For RS256: similar but using RSA-SHA256 with a private key. The signature is then base64url-encoded as the third segment.

Standard claims (JWT-spec)

See the claims reference for every registered claim, what it means, and when to use it.

Try the related tools

FAQ

Is my JWT sent anywhere?

No. Decoding is just base64url + JSON.parse, both built into your browser. Verification and signing use the Web Crypto API — also browser-native. Open DevTools → Network and verify: no requests are made.

What does it mean that the signature isn't verified by default?

Decoding a JWT just means base64-decoding the three segments — anyone can do it without the secret. Decoded ≠ trusted. Until you verify the signature with the right secret/key, the contents could have been tampered with. Use the Verify tab to check.

Why HMAC only? What about RS256 / ES256?

HMAC (HS256/384/512) uses a single shared secret — trivial to verify in a browser. RSA and ECDSA need a public key in PEM or JWK format and a few more lines of crypto setup. We're considering adding RS256 support; vote with your email signup.

Should I sign production JWTs with this tool?

No. The Sign tab is for testing — generating fixtures, exploring claim shapes, debugging server bugs. Don't paste a real production secret into a web form. For real signing, use a library on a server you trust.

What is the 'alg: none' attack?

Some old JWT libraries accepted tokens with alg: none as 'no signature required.' An attacker could re-sign any token that way and pass verification. Modern libraries reject none by default. This tool's verifier requires HS256/384/512 explicitly — none won't be accepted.

What happens if I change the payload?

The signature won't match the new payload, so any properly-implemented verifier will reject the modified token. The decoder will still parse the modified token (because base64-decode doesn't validate signatures), but verification will fail. That's the whole point of signing — tamper-evidence.