๐Ÿ”

Decoding and signature verification run entirely in your browser. The token and any key you enter are never sent to a server.

Decode a JWT without handing it to anyone

A JSON Web Token is three Base64URL segments joined by dots: a header that names the signing algorithm, a payload holding the claims, and a signature that lets the issuer prove the first two were not modified. Almost everything developers need to debug authentication problems lives in the first two segments, and neither of them requires a key to read.

That last detail is the reason this tool exists. Most online decoders send your token to a server, but the token is exactly the thing an attacker wants: a bearer token is valid simply because someone holds it. Copying a production token into a third-party website hands over a working credential, complete with the user's identity and scopes. Decoding it locally removes that risk entirely.

Paste a token above and you get the decoded header and payload, every claim explained in plain English, the expiry rendered in your own timezone, a list of security findings, and the option to verify the signature locally โ€” with HS256, HS384, HS512, RS256 and ES256 supported. A leading Bearer prefix, line breaks from a copied log line and surrounding quotes are all tolerated, because that is how tokens actually arrive in practice.

Base64URL is encoding, not encryption

This is the single most common misconception about JWTs, and it has real security consequences. The payload is not scrambled: it is merely encoded with Base64URL, a URL-safe variant of Base64 that swaps + for -, / for _ and drops the padding. Anyone holding the token can reverse that in one line of code โ€” no key, no permission, no trace.

Because the payload is readable by design, never store secrets there. A payload commonly exposes a user id, an email address, role names, scopes, an issuer and an audience. Treat all of it as public data that may end up in logs, browser history, screenshots and analytics dashboards. If the contents genuinely must stay confidential even from someone who intercepts the token, you need a JWE โ€” a five-segment, encrypted structure โ€” not a signed JWT.

It is worth being precise about what a valid signature does and does not prove. It proves the token was issued by somebody holding the signing key and that the header and payload have not been altered since. It does not prove the token is still meant to be accepted by your service, and it does not make the contents secret.

What to check before you trust a token

Decoding is only half the job. When you are debugging an authentication failure, work through the same checks the server should be performing, in this order.

1. Expiry. Confirm exp exists and is in the future, and that iat is not in the future either. A missing exp means the token never expires โ€” a stolen copy stays valid forever.

2. Algorithm. The alg header must match exactly what your service expects. Be suspicious of none, of unexpected algorithm families, and of a token whose header was swapped while the payload stayed the same.

3. Issuer and audience. iss should identify the system that issued the token and aud should contain your service. Tokens minted for one service must not be accepted by another: that is the confused-deputy problem in practice.

4. Scopes and roles. Check that the permissions in the token are the minimum the operation needs. A token carrying administrative scopes where read-only access would do turns any leak into a much larger incident.

5. Lifetime and revocation. Short lifetimes limit the damage of a leak. Where tokens are long-lived, look for a jti claim โ€” without a unique token id there is no practical way to blacklist a single token after a logout or a breach.

The security findings above the decoded output automate these checks, so you can see at a glance whether the token you are holding would pass a careful review.

Decoding in practice

A healthy access token

The header names the algorithm and the payload carries identity, issuer, audience and a short lifetime.

Input
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyXzEwMjQiLCJleHAiOjIwNTAwMDAwMDB9...
Result
Header:
{
  "alg": "HS256",
  "typ": "JWT"
}

Payload:
{
  "sub": "user_1024",
  "iss": "https://auth.example.com",
  "aud": "api.example.com",
  "scope": "read:tools",
  "iat": 1760000000,
  "exp": 2050000000
}

No high-risk findings: exp is present, the algorithm is explicit and the lifetime is bounded.

An expired token

A token whose exp is already in the past is reported as a high-risk finding.

Input
{"sub":"user_1024","iat":1759900000,"exp":1759903600}
Result
High risk โ€” Token is expired
Expired 2 hour(s) ago (local time shown in the table)

exp  โ†’  in the past

If the issuer clock is correct, the user simply needs a new token โ€” or a refresh flow.

An unsigned token (alg=none)

The signature segment is empty and the header declares no algorithm.

Input
{"alg":"none","typ":"JWT"}.{"sub":"admin","role":"admin"}.
Result
High risk โ€” alg = "none" โ€” token is not signed
Anyone can modify the payload of this token. A server that accepts it is vulnerable to forgery.

This is a forgery attempt or a badly misconfigured issuer. Reject it.

A five-segment JWE

Encrypted tokens cannot be decoded at all without the decryption key.

Input
eyJhbGciOiJSU0EtT0FFUCJ9...ZW5jcnlwdGVk...aXY...Y2lwaGVydGV4dA...dGFn
Result
This looks like a JWE (encrypted JWT) โ€” it has 5 segments.
A JWE payload is encrypted, so the header and claims cannot be read without the decryption key.

Not an error in your token: encrypted payloads are unreadable by design.

Frequently asked questions

Is a JWT encrypted?

No. A JWT is Base64URL encoded, not encrypted. Anyone who holds the token can read the header and payload without any key โ€” that is why this page can decode it offline. The only part that requires a key is the signature, which proves the token was issued by someone holding the signing key. Never place passwords, card numbers or other secrets inside a JWT payload: treat everything in it as public information.

Is it safe to paste a real token here?

The decoding and any signature verification happen entirely inside your browser using JavaScript and the Web Crypto API. There is no upload, no API call and no logging, so the token never reaches our server โ€” you can confirm this yourself by opening your browser DevTools Network tab while using the tool and watching for outgoing requests. That said, a JWT is a live credential: if it is short-lived production token, prefer decoding a test token or one you are about to rotate anyway.

Why does the tool say my token is expired when my clock looks correct?

Expiry claims are Unix timestamps in seconds, measured against the verifier clock. If the issuer and your machine disagree by more than a few minutes, a token can look expired or not-yet-valid even though it was just issued. Check three things: that exp is in seconds rather than milliseconds, that your system clock is synchronised, and whether the nbf (not before) claim is in the future. Server-side clock skew is a very common cause of "invalid token" bugs.

What does alg=none mean and why is it flagged as high risk?

alg=none declares that the token is not signed at all โ€” the signature segment is empty. If a server accepts such a token, anybody can forge one with any payload they like, including administrator roles. The safe rule is to reject unsigned tokens outright and to validate that the alg header matches exactly what your service expects. This tool warns whenever it sees alg=none, and an empty signature is a strong sign the token came from a broken or malicious issuer.

Can this tool verify RS256 or ES256 signatures?

Yes, if you paste the matching public key in PEM format. Public keys are safe to share โ€” they can only verify signatures, never create them. Never paste a private key into any website, including this one: a private key would let an attacker issue valid tokens for your system. For HS256, HS384 and HS512 the token is verified with the shared secret instead.

What is the difference between exp, iat and nbf?

iat is when the token was issued, exp is when it stops being valid, and nbf is the earliest moment it may be accepted. iat and exp together define the lifetime of the token: a lifetime of days or weeks is risky because a leaked token cannot easily be revoked. nbf is mostly used for tokens prepared in advance. A healthy access token usually has a short lifetime of five to sixty minutes, with a separate refresh token handling renewal.

Why can I not read a token with five segments?

A five-segment token is a JWE โ€” a JSON Web Encryption structure โ€” rather than the usual three-segment JWS. Its payload is genuinely encrypted, so the claims cannot be read without the decryption key even in principle. That is exactly why JWE is used when the contents must stay confidential even from someone who intercepts the token. This tool tells you when it detects a JWE instead of pretending the decode failed.

Do you store or log the tokens people paste?

No. Because decoding happens in the browser, there is nothing to store on the server. The tool does not write your token to localStorage, cookies or the URL, and refreshing the page clears it. If you need proof for a security review, open DevTools, switch to the Network tab and use the tool: the only requests you should see are for the page assets themselves.

What this tool does not do

  • It does not decrypt JWE (five-segment, encrypted) tokens โ€” that is impossible without the key.
  • It does not fetch your issuerโ€™s live JWKS endpoint, because the tool makes no network requests at all. Paste the public key manually if you need to verify RS256 or ES256.
  • It does not validate that a token is accepted by your service: signature and claims can be perfectly valid while the token is revoked or scoped for a different audience.
  • It does not keep a history of decoded tokens, in memory or anywhere else.
  • It never supports creating or forging tokens, including alg=none โ€” that would only help attackers.

Related tools