JWT Decoder

  1. Paste a JWT (the whole eyJhbGciOi... string) into the input box.
  2. The header and payload are decoded and displayed as JSON automatically.
  3. Check the Claims summary panel for exp / iat / iss / aud / sub with human-readable dates.
  4. To verify the signature, enter the shared secret (HS256/HS512) or PEM public key (RS256) and click Verify.

Help

FAQ

Is a JWT encrypted?Show
No, in almost all cases. A standard JWS token is only Base64URL-encoded and signed - anyone can read the payload, including this tool. Signature verification proves integrity and authenticity, not confidentiality. If you need encryption, look for JWE (encrypted) tokens, which have 5 dot-separated parts.
Does decoding a JWT validate it?Show
No. Decoding only reverses the Base64URL encoding. A forged token with a valid-looking payload decodes just as easily. Only signature verification (the Verify button) proves the token was issued by someone holding the key, and even then you must still check exp, nbf, iss, and aud yourself.
What is the difference between HS256 and RS256?Show
HS256 is symmetric - the same secret signs and verifies, so any party that can verify can also forge tokens. RS256 is asymmetric - a private key signs, a public key verifies. Use RS256 (or ES256) whenever the verifying party should not be able to mint tokens.
Can a JWT be revoked or invalidated before exp?Show
Not by itself. JWTs are stateless - once issued, they are valid until exp unless the server keeps a denylist (e.g. Redis) or rotates the signing key. Keep token lifetimes short and use refresh tokens for longer sessions.
Where should I store JWTs in the browser?Show
Prefer HttpOnly, Secure, SameSite cookies set by the server. localStorage is readable by any JavaScript on the page, so a single XSS vulnerability leaks the token. Cookies need CSRF protection, but token theft via XSS is usually the bigger risk.
Why does my token have exp but still gets rejected?Show
Clock skew. exp is a Unix timestamp in seconds and servers usually allow only 30-60s of leeway. Also check nbf (not before) - a token issued with a future nbf is rejected before it starts. And confirm aud matches the API the client is calling.

How to use this JWT decoder

  1. Paste a JWT (the whole eyJhbGciOi... string) into the input box.
  2. The header and payload are decoded and displayed as JSON automatically.
  3. Check the Claims summary panel for exp / iat / iss / aud / sub with human-readable dates.
  4. To verify the signature, enter the shared secret (HS256/HS512) or PEM public key (RS256) and click Verify.

Privacy Notice

Full guide

What is a JWT?

A JSON Web Token (JWT) is an open standard (RFC 7519) for representing claims between two parties as a compact, URL-safe string. It is the most common way to carry identity and authorization state in stateless APIs: the server issues a signed token, and every subsequent request presents it instead of a session cookie lookup.

A JWT is not encryption. It is a carrier for JSON claims with an integrity mechanism. The JWT standard actually defines two distinct things people constantly conflate:

  • JWS (JSON Web Signature) - signed but readable by anyone. This is what 99% of "JWTs" in the wild are, and what this tool decodes.
  • JWE (JSON Web Encryption) - actually encrypted. You can tell one apart instantly: a JWE has five dot-separated parts (header.encryptedKey.iv.ciphertext.tag), a JWS has three (header.payload.signature).

Anatomy: header.payload.signature

A JWT is three Base64URL-encoded segments joined by dots:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkphbmUiLCJpYXQiOjE3MDAwMDAwMDAsImV4cCI6MTcwMDA4NjQwMH0
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Decoding the first two segments gives the JSON you see in the tool output:

Header - metadata about the token:

{ "alg": "HS256", "typ": "JWT" }

Payload - the claims. Note there is nothing secret here; anyone with the token can read it with two lines of JavaScript, exactly like this tool does.

Signature - the proof. For HS256 it is HMAC-SHA256(base64url(header) + "." + base64url(payload), secret). Change a single character of the payload and the signature no longer matches.

The encoding is Base64URL, not standard Base64: + becomes -, / becomes _, and padding = is dropped. That is what makes the token safe to put in URLs, HTTP headers, and query strings without encoding surprises.

Signature algorithms: HS vs RS vs ES

The alg header decides how the signature is produced and who can verify it.

AlgorithmTypeKey modelTypical use
HS256 / HS384 / HS512HMAC + SHA-2One shared secret signs and verifiesMonolith, single service issuing and verifying
RS256 / RS384 / RS512RSA PKCS#1 v1.5Private key signs, public key verifiesMicroservices, third-party verifiers, OIDC
ES256 / ES384ECDSA (P-256/P-384)Same asymmetric model, smaller keys and signaturesModern APIs, mobile, constrained environments
PS256RSA-PSSAsymmetric, probabilistic paddingRequired by some government / FAPI profiles
noneNo signature—Should be rejected. Historically the source of the alg=none attack

The rule of thumb: if the party verifying the token should not be able to create tokens, you need an asymmetric algorithm. With HS256, every service that can validate a token can also forge one - a compromised microservice becomes a token mint.

This tool verifies HS256/HS512 with a shared secret and RS256 with a PEM public key, using the browser's Web Crypto API.

Registered claims you should actually use

The payload can hold anything, but RFC 7519 reserves these keys:

ClaimMeaningNotes
issIssuerWho created the token, e.g. https://auth.example.com
subSubjectWho the token is about - usually the user ID
audAudienceWho the token is for. APIs must reject tokens whose aud does not match them
expExpirationUnix seconds. Verification libraries enforce this - plain decoding never will
nbfNot BeforeToken is invalid earlier than this timestamp
iatIssued AtWhen the token was created
jtiJWT IDUnique ID, used for one-time tokens or denylist entries

The tool's Claims panel renders exp, iat, and nbf as human-readable dates so you can spot a stale or not-yet-valid token at a glance.

Security pitfalls that still bite teams in 2026

1. Trusting a decoded token. Decoding is not validation. Attackers craft beautiful payloads all day; only the signature check proves authenticity, and only your own exp/aud/iss checks prove fitness for your API.

2. The algorithm-confusion attack. Classic CVE bait: a server accepts tokens and verifies whatever alg the header claims. Attacker takes an RS256 token, changes the header to HS256, signs with the public key (which the server happily treats as the HMAC secret). Always pin the expected algorithm server-side, like this tool does with algorithms: [alg].

3. Weak HMAC secrets. HS256 with a dictionary-word secret falls to offline brute force in minutes, because an attacker with one valid token can test candidate secrets without touching your server. Use at least 256 bits of randomness (openssl rand -base64 32).

4. Putting sensitive data in the payload. It is Base64, not encryption. PII, internal IDs, and permission details in the payload leak to every place the token travels - including browser dev tools, logs, and proxies.

5. Long-lived tokens with no revocation. A stolen JWT is valid until exp. Best practice: short access tokens (5-15 minutes) plus refresh tokens stored server-side, and a jti denylist if you need instant revocation.

6. Storage in localStorage. Any XSS on your origin reads every token in localStorage. HttpOnly cookies keep tokens out of JavaScript's reach entirely; pair with SameSite and CSRF tokens.

JWT vs opaque session tokens

JWTOpaque session ID + store
VerificationLocal crypto, no DB hitServer-side lookup every request
RevocationHard (denylist / short exp)Trivial (delete the row)
SizeLarger (hundreds of bytes +)Tiny
Cross-serviceExcellent - any service with the public keyRequires shared session store or gateway

Use JWTs where many independent services must verify identity without a round trip; use server sessions when revocation and simplicity matter more.

How this tool processes your token

Everything runs in your browser: the segments are split and Base64URL-decoded with the standard alphabet translation, JSON is parsed and rendered, and signature verification calls Web Crypto (crypto.subtle) directly. No network request carries your token or secret - which is also why it is safe to debug real credentials from staging here.

Further reading