Skip to content
← Back

JWT Decoder - Online JWT Token Decode & HS256 Verify

Security
Runs locally · Not uploaded

Online JWT decoder with HS256 signature verification. Decode Header, Payload, Signature locally — hs256 online check without uploading your token.

Was this result helpful?

For local tools, open DevTools → Network and search your input — it should not appear in requests.

Next steps

Usage Guide

A JWT consists of Header, Payload and Signature; the first two segments are merely Base64URL-encoded — not encrypted — so anyone can read them. This tool decodes tokens locally in your browser, checks the signing algorithm and expiry, and includes HS256 verification (the key stays on your machine) — built for debugging login sessions and API authentication.

1. Read a JWT in thirty seconds

  1. Paste the token; the three segments render separately in real time.
  2. Header first: alg names the signature algorithm (HS256/RS256/ES256), typ is usually JWT.
  3. Payload next: sub (subject), exp (expiry, Unix seconds), iat (issued-at) and aud (audience) are the four fields that matter most.
  4. Time claims render as a compact timeline under the decoded output (UTC + relative offset such as “expired 2 hours ago”) — Copy stays in the toolbar above, unobstructed.
  5. The tool flags alg=none with a red warning and whether the algorithm belongs to the safe set (HS256/RS256/ES256/PS256). HS256 verify is available on this page; RS256/JWKS remains a later enhancement.

2. Choosing between HS256 and RS256

HS256 is symmetric: one shared key both signs and verifies — simple and fast, suited to monoliths or fully mutually-trusting services; the catch is that anyone holding the key can forge as well as verify. RS256 is asymmetric: a private key signs, a public key verifies, so third parties can verify without being able to forge. Combined with a standard JWKS endpoint (/.well-known/jwks.json), keys can rotate without redeploying — multi-service setups and open platforms should default to RS256.

3. The fine print of exp/nbf validation

  • exp is Unix seconds, not milliseconds — mixing units across systems is the top cause of mysteriously early expiry. This decoder normalizes obvious millisecond NumericDates by magnitude.
  • Allow clock-skew leeway (30–60 seconds): a few seconds of drift across distributed machines is routine.
  • nbf needs the same leeway; iat is audit metadata, never a gate.
  • Do not treat frontend exp checks as the source of truth for login state: the server may have revoked the token long before exp.

4. Why production verification must live server-side

Verification requires the secret or private key, and the browser is a fully public execution environment — shipping an HS256 secret to the frontend is publishing it. The legitimate frontend use of decoding is display only (username, avatar, permission labels); the actual authorization decision belongs in server middleware performing full validation: signature, exp/nbf, aud/iss matching, and revocation status.

5. Common error messages decoded

  1. Signature invalid → key mismatch, or someone edited header/payload without re-signing; first check whether alg was tampered with.
  2. Token used before issued (or nbf in the future) → clock drift between issuer and verifier; check NTP and leeway settings.
  3. JWT malformed → wrong segment count, missing separators, or Base64URL padding stripped without re-padding.
  4. Suddenly everyone is admin → verify the code actually validates the signature instead of only decoding the payload.

6. The alg=none attack: why an algorithm allowlist is the floor

The JWT spec permits alg none (unsigned tokens), and early libraries accepted it by default: an attacker flips header alg to none, drops the signature, and verification silently passes. Modern libraries reject none by default, but any hand-rolled parser must maintain its own algorithm allowlist — reading alg from the header and obeying it means letting the attacker choose your verification method.

7. What this page can and cannot verify

Decoding header/payload needs no key — anyone can do it; that is JWT’s self-contained display model. Signature checks are different: this page verifies HMAC family algorithms (HS256 and siblings) with the key staying in browser memory; RS256/ES256 need a public key or JWKS fetch and belong in server integrations. A local “Signature valid” only means your pasted key matches this token — it does not replace production checks for aud/iss, revocation, and key rotation.

8. Claim cheat sheet for debugging

  • sub: subject (often a user id); do not treat email as the sole primary key unless the product contract says so.
  • iss / aud: issuer and audience — reject aud mismatches on cross-service calls instead of accepting anything that merely decodes.
  • jti: token id used with a server-side denylist for active revocation; without jti, precise single-token invalidation is hard.
  • Custom claims (role, tenant_id): plain JSON fields — their security meaning exists only after the server verifies the signature and then trusts them.

FAQ

HS256 yes: paste the token and the secret, and the check runs locally. RS256/ES256 need a public key or a JWKS endpoint fetch — that is server-side integration territory and out of this page's scope, so treat those tokens as decode-only here. Also note that “Signature valid” only means your local secret matches the token; it is no substitute for a server-side verification chain (aud/iss matching, revocation, key rotation).

HS256 is symmetric: one key both signs and verifies. It is simple and fast, a good fit for monoliths or fully trusted service-to-service traffic, but anyone holding the key can forge as well as verify. RS256 is asymmetric: the private key signs, public keys verify, third parties can verify without being able to forge, and keys rotate through a standard JWKS endpoint (/.well-known/jwks.json) without redeploying — the default for multi-service systems, open platforms, and third-party integrations.

After decoding, standard time claims appear as a timeline: exp (expiry), iat (issued-at), and nbf (not-before), each shown as a readable UTC time plus a relative offset such as “expired two hours ago”. NumericDate counts Unix seconds per RFC 7519; if a source system mistakenly uses milliseconds, the tool normalizes by magnitude. Production verifiers should allow 30–60 seconds of clock-skew leeway.

alg=none means the token is unsigned. An early generation of libraries accepted none by default: an attacker could flip the header's alg to none, drop the signature, and pass verification silently. Modern mainstream libraries reject it, but if you hand-roll parsing you must maintain an algorithm allowlist — honoring whatever alg the header declares lets the attacker choose your verification method.

Signature invalid: wrong secret, or header/payload edited without re-signing — check alg for tampering first. Token used before issued: clock drift between issuer and verifier; check NTP and leeway settings. JWT malformed: not three segments, missing separators, or stripped Base64URL padding never restored. Suddenly everyone is admin: your code decoded the payload without actually verifying the signature.

Yes. Decoding and signature checks run locally in your browser — neither the token nor the secret is sent to any server, and the key is used once in memory. One reminder: the payload itself is Base64URL-encoded, not encrypted, so it should never contain secrets in the first place.

Related Tools

Related Articles