Decode a JWT Online (and When HS256 Verify Is Enough)
Decoding a JWT and verifying its signature are different jobs. JWT Decoder always Base64URL-decodes the header and payload in your browser — no upload — and shows the raw signature segment. Checking the signature is optional: paste an HMAC secret and the tool uses Web Crypto (crypto.subtle) for HS256, HS384, or HS512 only. That check is debug-only, not server-side authentication. RS256 and ES256 are not verified here. For structure, claims, and safer production use of JWTs, see JWT Explained — this guide is the decode-and-verify workflow and its honest limits.
Decode first — verification is optional
A JWT is three Base64URL segments: header, payload, signature. Decoding turns the first two into readable JSON. Anyone with the token can do that; encoding is not encryption. Signature verification asks a second question: “Was this token produced by someone who holds this secret (or private key)?” JWT Decoder always answers the first. It only answers the second when you supply a secret and the header alg is an HMAC algorithm it supports.
What JWT Decoder actually does
| Step | Behavior |
|---|---|
| Decode | Splits on ., Base64URL-decodes header and payload, shows formatted JSON and common claims |
| Signature display | Shows the raw third segment (or “(none)”) — display only until you verify |
| Optional HMAC | If you paste a UTF-8 secret and alg is HS256/HS384/HS512, recomputes HMAC over header.payload with Web Crypto and compares |
| Compare | Timing-safe byte compare (timingSafeEqual) so length/content differences do not short-circuit early |
| Unsupported algs | RS256, ES256, and other non-HMAC algorithms → skipped with an explicit message |
| alg: none | Flagged as an unsecured token; HMAC is not applied |
| Privacy | Token and secret stay in the tab; nothing is sent to a server |
When HS256 verification is enough
Use the optional secret check when you (or your team) signed the token with a shared HMAC secret; when you are debugging “why is my API rejecting this?” and need to know if the signature matches the secret you think the server uses; and when the header alg is HS256, HS384, or HS512.
A valid result means: with this secret, the signature over this header and payload matches. It does not mean the token is safe to accept in production by itself — you still need exp, iss, aud, and the rest of your auth rules on the server.
When it is not enough
- Third-party or IdP tokens that use RS256 or ES256 (asymmetric) — those need a public key (JWKS), not a shared secret, and this decoder does not verify them
- Tokens where you do not have the HMAC secret — guessing is not supported and not appropriate
- Anything as a substitute for server-side verification in your app
If alg is RS256 or ES256, decode the claims for debugging, then verify on the server or with tooling that loads the issuer’s public keys.
alg: none and other red flags
If the header says alg: none, the token is unsecured. JWT Decoder warns and skips HMAC. Never treat an unsigned token as authenticated. Also remember: a matching HS256 signature with the wrong secret store, or trusting alg from the token without pinning allowed algorithms on the server, is a classic footgun — covered in more depth in JWT Explained.
How to decode and optionally verify a JWT
Decode a JWT and check an HMAC signature locally
All work stays in the tab. Paste a secret only when you already trust that secret.
- 1
Open JWT Decoder
Go to /tools/developer/jwt-decoder.
- 2
Paste the token
Full header.payload.signature string. Header and payload appear as JSON; claims like exp and iat are surfaced when present.
- 3
Read alg (and kid if present)
Confirm whether this is HMAC (HS*) or asymmetric (RS* / ES*).
- 4
Optional: paste the HMAC secret
Only for HS256, HS384, or HS512 when you hold the shared secret. Leave blank to decode only.
- 5
Read the HMAC status
Valid, invalid, or skipped (wrong algorithm, alg none, or no secret).
- 6
Debug, then verify for real on the server
Use the browser check for local debugging. Production acceptance still belongs in your API with pinned algorithms and claim checks.
JWT Decoder
Decode JWTs locally and optionally verify HS256/HS384/HS512 with a secret — debug-only, not a replacement for server auth.
What not to expect
- Public-key (RS256/ES256) verification
- Recovering a lost secret
- Encryption of the payload — JWTs are signed, typically not encrypted unless you use JWE
- A green “valid” HMAC as proof the token is safe for every audience and expiry rule
Common mistakes
Expecting HS256 verify on IdP access tokens
Auth0, Cognito, Okta and similar tokens are usually RS256. Decode the claims here; verify with the issuer’s public keys elsewhere.
Treating decode-only as “verified”
Readable claims are not proof of authenticity. Verification is a separate, optional step.
Using a sample or docs secret
A matching check against the wrong key is worse than no check — you get false confidence.
Using this tab as a production auth gate
Browser HMAC checks are for debugging. Accept tokens only in server code with pinned algorithms.
Best practices
- Decode freely; verify HMAC only with secrets you already control
- Pin allowed algorithms on the server (HS256 or RS256 — never “whatever the header says”)
- Reject alg: none in production code paths
- Prefer asymmetric signing when more than one service must verify without sharing a minting secret
Frequently asked questions
How do I verify a JWT signature online?
Paste the token into JWT Decoder. Decoding always works locally. To check an HMAC signature, paste the shared secret — only HS256, HS384 and HS512 are supported. That check is for debugging, not production auth.
Can I decode a JWT without the secret?
Yes. Header and payload are Base64URL, not encrypted. Anyone with the token can read them. The secret is only needed to verify an HMAC signature.
Why can’t I verify RS256 or ES256 here?
Those use asymmetric keys. This tool’s optional check is HMAC via Web Crypto with a shared secret. Use your server or a JWKS-aware verifier for RS/ES.
What does “alg none” mean?
The token is unsecured. JWT Decoder warns and does not apply HMAC. Do not accept unsigned tokens as authenticated.
Is a “valid” HS256 result enough to trust the token in my app?
No. It only means the signature matches the secret you pasted. Still enforce expiry, issuer, audience and algorithm pinning on the server.
Does the decoder upload my JWT or secret?
No. Decode and HMAC both run in the browser.
Put this into practice
JWT Decoder runs entirely in your browser — no upload, no account, no limits.
Open JWT DecoderRelated tools
Related guides
JWT Explained: Structure, Claims and Safe Use
What a JSON Web Token contains, how the three segments work, which claims matter, how signatures are verified and the mistakes that turn JWTs into a security hole.
Base64 Explained: What It Is and When to Use It
How Base64 turns binary into text, why output is about 33% larger, where padding comes from, URL-safe variants, and why Base64 is encoding rather than encryption.
URL Encoding Explained (Percent-Encoding)
Why URLs need encoding, which characters are reserved, the difference between encodeURI and encodeURIComponent, plus and space confusion, and how to avoid double encoding.
Why Client-Side Tools Are Safer for Your Files
What actually happens when you upload a file to an online converter, how browser-based processing differs, how to verify a tool's claims, and when a server is unavoidable.
Why Won't My PDF Unlock? (Password Types Explained)
Why a PDF opens in a viewer but still fails merge or unlock: Password to open vs Owner / permissions lock vs None. What Unlock PDF can remove (RC4, AES-128, AES-256) — and what it cannot (lost passwords, certificate encryption, rare /V3).
How to Compress Images for the Web
A practical guide to image compression: lossy vs lossless, choosing quality levels, resizing before compressing, format choice, and compressing images in your browser.