JWTs show up everywhere in modern authentication, but the gap between "I can read what's inside this token" and "I can trust what's inside this token" trips up a surprising number of people working with them for the first time.

The Three Parts of a JWT

A JWT is three base64url-encoded segments joined by periods: a header, a payload, and a signature. The header typically identifies the signing algorithm and token type. The payload holds the actual claims — the data the token is asserting, like a user ID or an expiration time. The signature is a cryptographic value computed over the header and payload together, and it's the only part of the three that actually requires a secret or private key to produce.

Decoding Is Not the Same as Verifying

This is the single most common misunderstanding about JWTs: the header and payload are only encoded, not encrypted. Base64url encoding is fully reversible by anyone with no key required — it's a way of representing binary-safe data as text, not a way of hiding it. Anyone who intercepts a JWT can decode and read its payload instantly. What they can't do without the right secret or private key is prove the token is genuine and hasn't been tampered with — that's what the signature is actually for, and checking it is a separate, deliberate step called verification.

Tip: Never put anything genuinely secret (a password, a raw credit card number) inside a JWT payload — since it's just encoded, not encrypted, anyone holding the token can read it without needing the signing key at all.

Standard Claims: exp, iat, sub

The JWT spec defines a handful of standard (but optional) claim names that most systems use consistently. exp is the expiration time — a Unix timestamp after which the token should be rejected. iat is "issued at," recording when the token was created. sub identifies the subject the token is about, usually a user ID. None of these are enforced by the token format itself; they're conventions that the system reading the token has to actually check and act on — a JWT with an expired exp claim doesn't stop working on its own, it just contains data that a properly written verifier should reject.

Why HMAC and RSA/ECDSA Differ

JWT signatures come in two structurally different families. HMAC algorithms (HS256, HS384, HS512) use a single shared secret for both signing and verifying — whoever holds that secret can do either. RSA and ECDSA algorithms (RS256, ES256, and similar) use an asymmetric key pair instead: a private key signs the token, and a separate public key verifies it, without the public key ever being able to forge a new signature. Asymmetric signing is what lets one service issue tokens while many other services verify them without ever holding the actual signing secret — a shared HMAC secret would have to be distributed to every verifier, which is a much bigger security exposure at scale.

How Expiry Actually Gets Checked

Checking expiry is simple arithmetic once you understand the exp claim: it's a Unix timestamp (seconds since January 1, 1970 UTC), and a token is considered expired the moment the current time passes that value. There's nothing enforcing this at the token level — it's purely a comparison the verifying system has to perform itself, using its own system clock. This is also why clock drift between systems occasionally causes confusing edge cases: a token can appear valid or expired slightly earlier or later depending on whose clock is being trusted at the moment of the check.

Try It Instantly

Decode a JWT's header and payload, check its expiry, and optionally verify an HMAC signature with our free JWT Decoder — everything runs locally in your browser, nothing is sent anywhere.

FAQ

Is decoding a JWT the same as verifying it's genuine? No. The header and payload of a JWT are only base64url-encoded, not encrypted, so anyone can decode and read them without any secret. Verifying that a token is genuine and untampered requires checking its signature against the secret or public key that issued it, which is a separate step this tool only performs if you provide the correct HMAC secret.

Is my token sent anywhere when I paste it in? No — decoding and signature verification both happen entirely in your browser using standard JavaScript and the Web Crypto API. Nothing about your token, including any secret you enter for verification, is ever sent to a server.

Why does the signature verification only work for HMAC (HS256/HS384/HS512) tokens? HMAC algorithms use a single shared secret for both signing and verifying, which this tool can check directly once you provide that secret. RSA and ECDSA algorithms (RS256, ES256, and similar) use a public/private key pair instead — verifying those would require the issuer's public key, which is a more involved setup this simple tool doesn't currently support.

What does the "exp" field in the payload mean? exp stands for "expiration time" — a Unix timestamp after which the token should no longer be considered valid. This tool converts it to a readable date and flags whether the token has already expired relative to your current system clock.

Have a token to inspect? Try the free JWT Decoder — decode instantly, verify HMAC signatures, no sign-up.