JWT Decoder & Verifier
Decode JSON Web Tokens and verify HS/RS/ES/PS signatures — fully in your browser
—
—
What Is a JWT Decoder?
A JWT is three base64url segments joined by dots, header, payload and signature, and this decoder splits them, restores padding, decodes with a strict UTF-8 pass and pretty-prints the header and payload as readable JSON. Registered claims such as iss, sub, aud, exp, nbf, iat, jti, kid, typ and alg get plain-language labels, while exp, nbf and iat are additionally rendered as absolute UTC dates plus a relative distance, and an expiry badge tells you at a glance whether the token reads expired, active or not yet valid.
Debugging logins without guessing
- Paste an access token while chasing a 401 and immediately see the subject, audience and expiry instead of staring at opaque text, then copy the decoded header or payload blocks separately for a ticket or a chat thread.
- Watch the expiry badge before blaming the server, since a clock-skewed nbf or an already-passed exp explains most mysterious rejections, and the bundled sample token gives you a known-good value to learn the layout.
Decoding is not verification, and the verifier is picky
- Reading the payload proves nothing about authenticity: HS variants verify only against the shared secret you type in, raw or base64url when the checkbox is set, while RS, PS and ES variants verify against a PEM public key through WebCrypto, and unknown algorithms report that verification is unavailable.
- Tokens with an alg of none get an explicit warning rather than a green tick, empty input, a wrong segment count, or undecodable header or payload segments each surface their own distinct error instead of a blank screen.
Decoding and signature checks run on your device via page script and WebCrypto, with zero fetch calls anywhere in the page, so tokens stay in memory only. Your secrets and tokens are never sent to any server by this tool.
Last updated · 2026-09-01
What the three segments actually are
A JWT is three base64url segments joined by dots:
- header names the algorithm; payload carries the claims; signature binds both under a secret or key.
- Nothing in header/payload is encrypted — anyone holding the token reads every claim. That is by design; JWT is a signed container, not a safe.
- Verification needs the signing key and happens on your server; this page decodes locally so you can inspect claims without pasting tokens anywhere remote.
Decoding is not verifying
Claims become real dates
Header and payload print as readable JSON while registered claims like exp, nbf, and iat turn into actual dates, with a clear verdict of expired, active, or not yet valid.
HS, RS, PS, and ES verification
Verify HS256/384/512 against a shared secret in plain or base64 form, and RS, PS, or ES tokens against a PEM public key, using Web Crypto inside the page.
Malformed tokens explained
Structural problems are reported precisely — missing dot, invalid header, unreadable payload — and tokens claiming the none algorithm are flagged instead of trusted.
Frequently asked questions
Is my token sent to a server?⌄
No. Decoding and signature verification happen entirely in your browser using the Web Crypto API. Your token, secret and keys never leave your device, so it is safe to inspect production tokens.
Which signature algorithms can you verify?⌄
HS256/384/512 with a shared secret (UTF-8 or base64url), and the asymmetric families RS256/384/512, PS256/384/512 and ES256/384/512 by pasting the PEM public key. For asymmetric tokens you only need the public key, never the private key.
A JWT is not encrypted — what does that mean?⌄
A standard JWT is only base64url-encoded and signed, not encrypted, so anyone can read its payload. Never put secrets in a JWT. The signature only proves the token was not tampered with by someone without the key.
It says signature invalid — is the token forged?⌄
Usually one of three boring causes: the token was signed by a different environment’s secret; the issuer rotates keys and yours is stale; or the algorithm in the header does not match what your verifier expects (the infamous alg=none trick). Decode the header here first, then compare against the key your backend actually uses.