Skip to content
100% in your browser. Nothing you paste is uploaded — all processing runs locally. Read more →

JWT Decode vs Verify — Reading a Token Isn’t Trusting It

On this page
  1. Two different jobs on the same three segments
  2. What “decode” actually does
  3. What “verify” actually does
  4. Common mistake: trusting a decoded payload in the client
  5. How to try both in the browser
  6. Related: claims checklist + vs sessions

A JWT is three Base64url segments joined by dots: header.payload.signature. Anyone can read the first two. That is decode. Only someone with the right key can prove the third segment matches. That is verify.

The mix-up is simple: a decoded payload looks authoritative. It is not. Decode is reading. Verify is trusting. This page owns JWT decode vs verify — why a Base64 decode is not signature verification.

The primer is What is a JWT?. This page does not redo it. When you want to decode a JWT online or check a signature, use the decoder and verify tools. Paste stays in your browser. Nothing is uploaded. There is no signup.

Two different jobs on the same three segments

Same token. Two jobs.

Decode answers: what does this token claim? Split on dots, Base64url-decode the header and payload, parse the JSON. You see alg, sub, exp, whatever the issuer — or an attacker — put there. No key. No trust.

Verify answers: did the holder of the expected key sign these exact bytes? Recompute the signature over header.payload with the algorithm you accept and the key you hold. Compare it to the third segment. Then, if that check passes, validate claims.

DecodeVerify
JobRead header + payloadProve the signature, then check claims
Needs a key?NoYes — HMAC secret or public key
SignatureIgnoredCompared byte-for-byte
Tells youWhat the token saysWhether you can trust what it says
Typical useDebug, inspect, teachAuthn / authz decisions

If you only decoded it, you have JSON. You do not have a trusted identity. A decoder will happily show {"admin": true} from a token you typed yourself. That is the format: the first two parts are meant to be readable. The third is what makes them binding.

What “decode” actually does

How to decode JWT: three mechanical steps.

  1. Split the string on . into three segments.
  2. Base64url-decode the first two (header and payload).
  3. Parse each as JSON.

The third segment is the signature. Decode leaves it alone. It does not recompute HMAC. It does not load a public key. It does not look at exp. A token with alg: none, a swapped payload, or a garbage signature still “decodes” if the first two segments are valid Base64url JSON.

That is why decode JWT online tools work without a secret. The header and payload were never encrypted. They are encoded — URL-safe Base64 of JSON — so they can travel in a header. Encoding is not signing. Anyone who can see the token can read the claims.

What you get: the header, including the algorithm the token claims (HS256, RS256, …), and the payload (sub, name, iat, plus custom fields). What you do not get: proof the payload was not edited, that the issuer is who you expect, or that the token is unexpired and meant for your service.

Decoded ≠ trusted. The decoder is a magnifying glass. Use it to see what a failing request says — then verify before you act on any of it.

What “verify” actually does

JWT signature verification needs a key. For HMAC (HS256 / HS384 / HS512) both sides share a secret. For asymmetric algorithms (RS256, ES256, EdDSA) the signer holds a private key and the verifier uses the matching public key. The wrong key, or the wrong algorithm, is a failed verify — not a “maybe.”

A real verifier does more than “looks like JSON”:

  1. Parse the three segments. Invalid Base64url or JSON is a reject, not a soft decode.
  2. Pin alg. Compare header.alg to an allow-list you chose. Do not let the token pick the algorithm. Reject none. Algorithm confusion (RSA public key used as an HMAC secret because the header said HS256) is a short, well-known class of bugs — optional reading: the fast-jwt writeup.
  3. Check the signature with the correct key for that pinned algorithm. HMAC uses the shared secret. Asymmetric uses the public key. A match means those header and payload bytes were signed by the key holder and have not changed.
  4. Then check claims. Signature OK is not “the user is allowed in.” Still validate exp, nbf, iss, and aud as appropriate. The checklist lives on standard claims.

“JWT verified” means those checks passed — at least the signature plus the claim rules you configured. It does not mean you decoded the payload in DevTools and liked the sub. Libraries bundle steps 1–4 when you call verify with pinned algorithms. Skipping that and JSON.parseing the middle segment is decode with extra steps.

This site’s verify page runs HMAC (HS256/384/512) in the browser with Web Crypto. RSA and ECDSA still belong in a server library with a pinned algorithm list.

Common mistake: trusting a decoded payload in the client

The footgun: read the payload in JavaScript, then treat sub, roles, or admin: true as fact.

Anyone can mint a three-segment string. Change the payload, Base64url-encode it again, keep or junk the signature. A decoder will still show the new JSON. A client that “authorizes” from that JSON is trusting the user.

Typical versions:

The payload is public. That is the design. JWTs are tamper-evident when verified, not confidential, and not trusted when merely decoded. If a stolen token should die the moment you delete a row, you may want a session — that comparison is JWT vs session cookies.

How to try both in the browser

You can see the difference without leaving this host.

Decode. Open the JWT decoder. Paste a token. The decode tab shows the header and payload, with registered claims explained inline. No secret. That is reading.

Verify. Open Verify HMAC, or switch to the Verify tab on the same tool. Paste the token and the shared secret. The browser recomputes the HMAC and tells you valid or invalid.

Both paths stay on your device. The paste never uploads. There is no account. Use a test token — not a production HMAC key.

If verify fails, the usual causes are the wrong secret, a tampered segment, or an algorithm this HMAC tool does not support. A green decode next to a red verify is the lesson: you can read it and still must not trust it.

Decode a JWT → · Verify a signature →

Standard claims — after the signature passes, still check exp, nbf, iss, and aud. That page is the registered-claim checklist.

JWT vs session cookies — when a self-contained token is the wrong shape and a session is simpler to revoke.

What is a JWT? — header, payload, signature, and where tokens fit. Fundamentals only.

Ready to see both jobs on the same token? Use the decoder and verify. Browser-only. Nothing uploaded.