JWT decoder
Decode a JSON Web Token, see its claims explained and verify its signature – all in your browser, nothing is sent anywhere.
-
Tokens are decoded and verified in your browser. Nothing you paste here is sent to the server or anywhere else.
Token
Decoded in this page only. The token, secret and key are never sent anywhere – not even to our server.
Header
Payload
|
|
Verify the signature
This token's algorithm has no signature that can be checked here.
Checked with your browser's built-in Web Crypto. A valid signature only proves who signed the token: the service must still check exp, aud and iss.
What this tool checks
Paste a JSON Web Token (JWT) and the page splits it into its three parts – header, payload and signature – decodes the first two from base64url and shows them as formatted JSON. A leading Bearer is ignored, so you can paste an Authorization header value as it is.
Everything happens in JavaScript on your device. The token, any secret and any public key you enter stay in the page: nothing is sent to our server or anywhere else, and the page doesn't store them. You can check this in your browser's developer tools – typing a token makes no network requests. The server only delivers the page.
Below the JSON, the standard claims (RFC 7519) are listed and explained:
iss(issuer),sub(subject) andaud(audience);exp(expires),nbf(not before) andiat(issued at), shown as UTC dates with how long ago or how far ahead they are, such as "3 days ago";jti, and the common OAuth and OpenID Connect claimsazp,scope,nonceandauth_time.
You can also verify the signature with your browser's built-in Web Crypto:
- HS256, HS384, HS512 with the shared secret (as text, or tick the box if it is Base64-encoded);
- RS256/384/512, PS256/384/512 and ES256/384/512 with the public key as a PEM block (
-----BEGIN PUBLIC KEY-----) or as a JWK or JWK set (the key whosekidmatches the token is used); - EdDSA (Ed25519) where your browser supports it.
The tool can't read encrypted tokens (JWE, five parts instead of three) and it doesn't fetch keys from an issuer's JWKS URL: paste the key yourself.
Reading the results
The coloured notes above the JSON sum the token up:
- Expired 3 days ago or Valid for another 2 hours, from
expcompared with your device's clock. - No "exp" claim: the token never expires. If it leaks it stays usable until the signing key changes, unless the service can revoke it.
- alg is "none": the token is not signed at all. Anyone can create or change such a token, so a service must never accept it.
- Very long lifetime: the time from
iat(ornbf) toexpis over 30 days. Over a day is mentioned as unusual for an access token. - Not valid yet (
nbfin the future) and Issued in the future (iatmore than a minute ahead) usually point to a clock that is wrong somewhere. - A time claim that looks like milliseconds rather than seconds, a common bug: JWT times are whole seconds since 1970.
- A header that carries its own key (
jwk) or a key URL (jku,x5u): a server must never trust a key chosen by the token.
When you verify, Signature verified means the token was signed with that secret or the private half of that key and hasn't been changed since. Signature does not match means a wrong key or secret, or a changed token. A valid signature only proves who signed it: the service must still check exp, aud and iss.
Common problems and fixes
"Invalid signature" with the right HS256 secret
Check whether the issuer treats the secret as text or as Base64-encoded bytes. Some libraries and identity providers (older Auth0 setups, for example) Base64-decode the secret before using it. Tick "The secret is Base64-encoded" and try again. Also check for a trailing space or newline copied with the secret.
The public key isn't accepted
The page wants an SPKI public key, which starts with -----BEGIN PUBLIC KEY-----. If you have a certificate or an older RSA key, convert it first:
openssl x509 -pubkey -noout -in cert.pem
openssl rsa -RSAPublicKey_in -in rsa-pub.pem -pubout
Also check the key type matches the algorithm: an RSA key can't verify an ES256 token.
Tokens expire straight away or too early
exp is checked against the clock of the server that validates the token. Make sure servers sync their time with NTP, and allow a small leeway (30 to 60 seconds) in your JWT library for clock differences.
Tokens that live for weeks
Keep access tokens short (5 to 60 minutes) and use refresh tokens, which the server can revoke, for long sessions. Set exp on every token you issue.
FAQ
Is it safe to paste a production token here?
The token is decoded only in your browser and never sent anywhere, so we never see it. Still, a valid token is a password for as long as it lives: paste expired or test tokens where you can, and never paste private keys anywhere.
Is a JWT encrypted?
No. A normal signed JWT (JWS) is only encoded: anyone who has it can read the header and payload, as this page shows. The signature stops changes, not reading. Don't put secrets in a JWT payload; use an encrypted JWE if you must.
What is the difference between HS256 and RS256?
HS256 uses one shared secret to both sign and verify, so every service that checks tokens could also create them. RS256 and ES256 sign with a private key and verify with a public key, so verifying services can't issue tokens.
What does alg "none" mean?
The token has no signature. It exists for cases where the token is protected some other way, but libraries that accepted it by mistake have caused serious security holes. Reject it unless you have a very specific reason.
Why does my token say it expired in 1970 or in the far future?
The time claims are in seconds since 1 January 1970. A value in milliseconds looks like a date tens of thousands of years ahead; a value of a few thousand looks like 1970. Fix the issuer to use whole seconds.