JWT Decoder & Verifier

Decode and inspect any JSON Web Token - header, payload, timestamp claims - and optionally verify an HS256 signature in-browser.

How it works

A JSON Web Token is three Base64url-encoded strings joined by dots: header.payload.signature. Paste a token into the box and it is split on the dots, each part is Base64url-decoded, and the header and payload are parsed as JSON and pretty-printed. This happens as you type, there is no submit button for decoding.

Reading the decoded output

The badges at the top of the result show the alg (signing algorithm) and typ from the header, plus a status badge derived from the exp claim: Valid window if the expiry is in the future, Expired if it is in the past. The Header block tells you how the token was signed; the Payload block holds the claims (the actual data). Any iat, exp and nbf values are also broken out into a Timestamp claims table and converted from Unix epoch seconds to a human UTC date with a relative offset, so you can see at a glance whether a token is active, not-yet-valid, or stale.

Verifying the signature

Decoding never requires a key, the header and payload are not encrypted. The signature is the only part that proves authenticity, and verifying it needs the key that signed the token. When the alg is HS256, HS384 or HS512, a verify panel appears: enter the shared HMAC secret and the tool re-computes the signature over header.payload using the browser's crypto.subtle API and compares it byte-for-byte. A match means the token was signed with that exact secret and has not been altered. RS* and ES* algorithms use asymmetric keys and are out of scope here: decode them, but verify them with the issuer's public key elsewhere.

Standard JWT claims (RFC 7519)

The payload can hold any keys, but these seven registered claims have defined meanings. The time-based claims (exp, nbf, iat) are a NumericDate: seconds elapsed since the Unix epoch, in UTC.

ClaimNameMeaning
issIssuerWho created and signed the token.
subSubjectThe principal the token is about (often a user ID).
audAudienceThe recipient(s) the token is intended for.
expExpirationAfter this time the token must be rejected.
nbfNot BeforeThe token is invalid until this time is reached.
iatIssued AtWhen the token was created.
jtiJWT IDA unique identifier, useful to prevent replay.

Frequently asked questions

Is a JWT encrypted?

No. A standard signed JWT (a JWS) is only Base64url-encoded, so anyone who holds the token can read every claim in it. Encoding is not encryption. The signature protects against tampering, not disclosure, never put secrets in a payload. Encrypted tokens are a separate format (JWE) and are not what this tool decodes.

Why does my token show as expired?

The status badge compares the exp claim against the current time. If exp is a Unix timestamp in the past, the token is outside its validity window and most servers will reject it. Check the iat and nbf values too, a token can also be rejected because it is not yet valid.

Can this verify RS256 or ES256 tokens?

It will decode them, but it only verifies the symmetric HMAC family (HS256/384/512), where signing and verifying use the same shared secret. RS* and ES* are asymmetric: they are verified with the issuer's public key, which is out of scope here. You can still inspect their header and claims.

What does an "alg" of "none" mean?

It marks an unsecured token with no signature at all. This is legitimate only in narrow cases and is a well-known attack vector when a server is tricked into accepting it. If you see "alg":"none" on a token that should be signed, treat it as suspicious.

Is it safe to paste a production token here?

The decoding and verification run entirely in your browser, so nothing is transmitted. The real risk is your surroundings: a live token is a credential. Prefer test tokens, and if you must inspect a production one, do it on a trusted machine and treat the value as sensitive.

Everything runs locally in your browser: the token, the secret and the results are never sent to any server or stored. Remember that Base64url is encoding, not encryption: decoding proves nothing about a token's authenticity. Only a successful signature check (with the correct secret or key) confirms a token is genuine and untampered.

Related tools