🔑 JWT Token Decoder & Inspector

A JWT decoder that also verifies the signature in your browser: HS256 with a secret, RS256 and ES256 with a public key. Claims, expiry and alg:none flagged.

Free No Signup Required Browser-Based

Verification runs in your browser through the Web Crypto API and nothing is transmitted. Even so, a production signing secret pasted into any web page has been typed into a browser and may sit in your clipboard and form history — use a test key.

HEADER: ALGORITHM & TOKEN TYPE
{
  "alg": "HS256",
  "typ": "JWT"
}

HS256: HMAC using SHA-256.

PAYLOAD: DATA CLAIMS
{
  "sub": "1234567890",
  "name": "Alex Turning",
  "iat": 1516239022,
  "exp": 1799999999,
  "role": "admin"
}
  • subSubject — who the token is about
  • iatIssued At — when it was created
  • expExpiration Time — must not be accepted at or after this

What JWT Token Decoder & Inspector Does

A JSON Web Token is three Base64url-encoded segments separated by dots: a header describing the signing algorithm, a payload of claims, and a signature over the first two. Decoding the first two segments requires no key at all — they are encoded, not encrypted.

That property is the source of the most common and most costly JWT misunderstanding. Anyone holding a token can read every claim in it. Putting an email address, a role, an internal user ID or anything else sensitive in a JWT payload is equivalent to printing it on the outside of the envelope.

This decoder runs entirely in your browser and does not transmit the token. It shows the header, the decoded claims and the expiry status. It deliberately does not verify the signature, because verification requires the secret or public key — and pasting a signing secret into any web page is a mistake.

How to Use JWT Token Decoder & Inspector

  1. Paste your encoded JSON Web Token (JWT) into the text area
  2. Instantly inspect the decoded Header and Payload JSON structures
  3. Check token expiration status and timestamp validity
  4. Optionally paste the shared secret (HS256) or PEM public key (RS256, ES256) to verify the signature in your browser

JWT Structure

Example: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMifQ.dBjftJeZ4CVP… — three dot-separated segments.

SegmentContentsEncrypted?
HeaderAlgorithm (alg) and token type (typ)No — Base64url only
PayloadClaims: subject, expiry, issuer, custom fieldsNo — Base64url only, readable by anyone
SignatureHMAC or digital signature over header.payloadNot encrypted; proves integrity, not confidentiality

Registered Claims (RFC 7519 §4.1)

All are optional, but each has a defined meaning that libraries rely on.

ClaimNameMeaning
issIssuerWho created and signed the token
subSubjectWho the token is about — usually a user ID
audAudienceWho the token is intended for; reject if it is not you
expExpiration TimeUnix seconds after which the token must be rejected
nbfNot BeforeUnix seconds before which the token must be rejected
iatIssued AtUnix seconds when the token was created
jtiJWT IDUnique identifier, used to prevent replay

Source: RFC 7519 — JSON Web Token

Common Signing Algorithms

algTypeKeyNotes
HS256HMAC + SHA-256Shared secretVerifier can also forge tokens — same key both ways
RS256RSA + SHA-256Private/public pairVerifiers only need the public key; standard for OIDC
ES256ECDSA P-256 + SHA-256Private/public pairMuch shorter signatures than RS256
noneUnsecuredNoneMust be rejected. Accepting it means accepting forged tokens

Every JWS Algorithm and What the Spec Requires of It

RFC 7518 §3.1, in full. The requirement column is the specification's own — only HS256 is Required of a conforming implementation, which is why it is the one you meet everywhere. "Recommended+" means ES256 is expected to become Required in a future revision.

algAlgorithmImplementation requirement
HS256HMAC using SHA-256Required
HS384HMAC using SHA-384Optional
HS512HMAC using SHA-512Optional
RS256RSASSA-PKCS1-v1_5 using SHA-256Recommended
RS384RSASSA-PKCS1-v1_5 using SHA-384Optional
RS512RSASSA-PKCS1-v1_5 using SHA-512Optional
ES256ECDSA using P-256 and SHA-256Recommended+
ES384ECDSA using P-384 and SHA-384Optional
ES512ECDSA using P-521 and SHA-512Optional
PS256RSASSA-PSS using SHA-256 and MGF1 with SHA-256Optional
PS384RSASSA-PSS using SHA-384 and MGF1 with SHA-384Optional
PS512RSASSA-PSS using SHA-512 and MGF1 with SHA-512Optional
noneNo digital signature or MAC performedOptional

Source: RFC 7518 — JSON Web Algorithms §3.1

Decoding and Verifying in Your Language

The libraries differ; the rule does not. Pass the algorithms you expect as a fixed list. A verifier that takes the algorithm from the token's own header is letting the attacker choose how their forgery gets checked.

LanguageUsual libraryThe thing to get right
JavaScript / Nodejsonwebtoken, or jose for JWK and JWKSPass an explicit algorithms list; do not rely on the default
PythonPyJWTalgorithms= is documented as "do not compute from the alg in the token itself" — hard-code it or configure it beside the key
Javajava-jwt (Auth0) or jjwtBuild the verifier around one algorithm object rather than reading the header
Gogolang-jwt/jwtCheck the method inside the keyfunc — the classic mistake is returning a key without looking at it
PHPfirebase/php-jwtPass a Key with its algorithm, not a bare string
.NETSystem.IdentityModel.Tokens.JwtSet ValidAlgorithms in the validation parameters
BrowserWeb Crypto APIWhat this page uses — importKey then verify, no dependency
Shellbase64 -d and jq for readingReading is trivial; verifying in shell is not — use a library

How to Read Your Result

What a tampered token actually looks like

This page shipped one for months without anyone noticing, which is the point. Its payload read {"sub":"1234567890","name":"Alex Turning","iat":1516239022,"exp":1799999999,"role":"admin"} and its signature was SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c — the famous jwt.io signature, which is computed over a completely different payload, {"sub":"1234567890","name":"John Doe","iat":1516239022}. Somebody had edited the claims, granted themselves an admin role and an expiry three years out, and kept the old signature. It decodes perfectly. Every field displays. Nothing about reading it reveals the problem: only recomputing the HMAC over header.payload and comparing does, which is why "it decoded fine" is never evidence that a token is genuine.

Verifying HS256 needs the secret; verifying RS256 does not

This is the practical difference between the families and it decides which one you should be using. HMAC signs and verifies with the same shared secret, so anyone who can check a token can also mint one — fine inside a single service, dangerous the moment a second party needs to validate. The RSA and ECDSA families split it: the issuer holds the private key, everyone else verifies with a public key that grants no signing power. That is why OpenID Connect providers publish a JWKS endpoint of public keys and sign with RS256 or ES256. RFC 7518 also sets a floor on the HMAC side: "a key of the same size as the hash output (for instance, 256 bits for HS256) or larger MUST be used" — a short passphrase does not meet it, however strong it looks.

The "alg: none" attack

The specification permits an unsecured JWT with alg set to "none" and an empty signature. Libraries that honored the header's own claim about which algorithm to use would accept an attacker-modified token with the signature stripped. Any verifier must decide the expected algorithm itself and refuse anything else — never trust the token to tell you how to check the token.

Algorithm confusion (RS256 → HS256)

A related flaw: an attacker changes alg from RS256 to HS256 and signs with the server's public key as if it were an HMAC secret. If the library selects the verification method from the header, it validates successfully. The public key is, by definition, public. Pin the algorithm server-side.

Expiry and revocation

exp is a Unix timestamp in seconds, not milliseconds — a common bug that produces tokens valid until the year 56000. More fundamentally, a signed JWT cannot be revoked: it is valid until it expires, because verification is offline. Short lifetimes plus a refresh token, or a server-side deny list, are the usual mitigations.

Limitations & Accuracy Notes

  • Verification here proves the signature matches the key you supplied. It says nothing about whether that is the right key, whether the issuer is one you trust, or whether the token has been revoked — all of which your server still has to decide.
  • Signature checking covers the HS, RS, PS and ES families through the Web Crypto API. EdDSA (Ed25519) is not covered because browser support for it is still uneven, and JWE encrypted tokens are a different format entirely.
  • Never paste a production token containing live session credentials into any online decoder, including this one. Although decoding here happens locally in your browser, the safe habit is to use tokens from a development environment.
  • JWE (encrypted JWTs) have five segments rather than three and cannot be read without the decryption key. This decoder handles JWS, the signed three-segment form.
  • Claim names beyond the registered set are application-defined. A "role" or "scope" claim means whatever the issuing system decided it means.

Frequently Asked Questions

What are the three parts of a JWT token?
A JWT consists of 3 dot-separated Base64URL-encoded strings: Header (algorithm & token type), Payload (data claims & expiration), and Signature (tamper-verification).
Is my secret key exposed when decoding a JWT here?
No, decoding only reads the public Base64URL payload. All decoding executes strictly inside your browser, keeping your tokens confidential.
Can this verify the JWT signature, not just decode it?
Yes. Paste a shared secret for the HS256, HS384 and HS512 tokens, or a PEM public key for the RS, PS and ES families, and the check runs in your browser through the Web Crypto API. A valid result means the token has not been altered since it was signed with that key — it does not mean the key is the right one, the issuer is trusted, or the token has not been revoked. Those decisions still belong to your server.
Why does my token show "invalid signature"?
Three usual causes. The key is wrong — for HMAC the secret must match byte for byte, and a trailing newline counts. The algorithm is not the one you think: an RS256 token needs the public key, not the secret. Or the token really was modified, which is the case worth taking seriously. Note that a token can decode perfectly and still be forged; this page previously shipped a sample that did exactly that.
How do I decode a JWT with the secret to check it is genuine?
You recompute the signature rather than decrypt anything. Take the first two segments exactly as they appear, join them with a dot, run HMAC-SHA256 over that string with your secret, base64url-encode the result and compare it to the third segment. If they match, the claims are unchanged. That is all verification is for HS256 — which is also why the same secret can forge a token as easily as check one.
What key size does HS256 need?
At least 256 bits. RFC 7518 §3.2 states that "a key of the same size as the hash output (for instance, 256 bits for HS256) or larger MUST be used". A memorable passphrase is usually far short of 32 bytes, which is how HMAC-signed tokens end up brute-forceable regardless of how good the algorithm is. Generate random bytes instead.
Is my token sent anywhere?
No. Decoding happens entirely in your browser, which is the point — pasting a live token into a server-side decoder means handing a working credential to someone else.
Does decoding a JWT verify it?
No, and this is the critical distinction. Decoding reads the header and payload, which are only Base64url-encoded. Verifying means checking the signature against a secret or public key, which proves the token has not been altered. A decoded token tells you what it claims, not whether those claims are trustworthy.
Is the payload encrypted?
No. Anyone holding the token can read every claim in it. That means a JWT should never carry anything you would not be willing to show the person holding it — no passwords, no internal identifiers you consider sensitive, no personal data beyond what is necessary.
What do exp, iat and nbf mean?
They are standard registered claims: exp is the expiry time, iat is when the token was issued, and nbf is the time before which it must not be accepted. All three are Unix timestamps in seconds, not milliseconds — a factor-of-1000 mistake here produces expiry dates in the far future.
What is the "alg: none" vulnerability?
An old but instructive flaw. Some libraries honored a header claiming the algorithm was "none" and skipped signature verification entirely, letting anyone forge a token by editing the payload. Current libraries reject it, and the general lesson holds: the algorithm must be decided by the verifying server, never read from the token.
Can I edit a token here and have it still work?
No. Changing any part of the payload invalidates the signature, and any correctly implemented server will reject it. Producing a valid modified token requires the signing key.

References & Further Reading

By OnlineToolHubs Team • September 2026