99tools

JWT Decoder

runs in your browser

Decode a JSON Web Token, check its expiry against the clock, and verify the signature: HMAC with a secret, or RS, PS, ES and EdDSA with a public key.

Token

about this tool

What you are looking at

A JSON Web Token is three Base64URL segments joined by dots: a header saying how it was signed, a payload of claims, and a signature over the first two. Paste one and you get the header and payload as readable JSON, with the standard claims interpreted against your clock.

The payload is not secret. It is encoded, not encrypted — anyone holding the token can read it. That is the single most common misunderstanding about JWTs, and a good reason never to put anything confidential in one.

The segments use the URL-safe Base64 alphabet described on the Base64 page, so a single segment copied from a header decodes there as well.

Expiry and the other time claims

exp, iat and nbf are Unix timestamps, which tell you nothing at a glance. They are shown as real times with a plain-English distance — "expired 4 minutes ago", "valid in 2 hours" — because "is this token actually dead?" is the question that brings most people here. A token that expired while you were debugging looks identical to one that was never valid, until you read the date.

Verifying the signature

Decoding proves nothing about authenticity: anyone can craft a token with any payload. Verification needs the key the issuer signed with, and which key that is depends on the algorithm in the header.

HMAC — HS256, HS384, HS512 — is signed and verified with the same shared secret. Type it in and the signature is recomputed and compared.

RSA and elliptic curve — RS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384, ES512 and EdDSA — are signed with a private key and verified with the matching public one. Paste the public half in any of the forms an issuer publishes it: a PEM block beginning BEGIN PUBLIC KEY, a single JWK, or a whole JWK set copied from a .well-known/jwks.json endpoint. When the header carries a kid, that key is taken out of the set; without one the algorithm and key type are used, and if two keys would both fit the tool says so rather than picking one.

All of it runs on WebCrypto in your browser, so the same code path the browser uses for TLS does the arithmetic.

Two shapes are refused rather than half-read, with the command that converts them: an X.509 certificate, and a PKCS#1 BEGIN RSA PUBLIC KEY block, which browsers cannot import. A private key is refused outright — verifying never needs one, and a private key does not belong in a web page.

alg: none is a real value in the specification and a real attack: a library that trusts the header will accept an unsigned token. A token claiming it is reported here as unsigned, never as valid.

Why do this locally

Access tokens are credentials. Pasting a live bearer token into a website hands that site your session, and there are popular JWT debuggers that do exactly that. Every part of this runs in the page — decoding and every signature check — so the token, the secret and the key stay on your machine.

To build and sign a token rather than read one, the JWT generator fills in iat and exp for you and signs with HMAC, RSA, ECDSA or EdDSA.

questions

Is the contents of a JWT encrypted?
No. The header and payload are Base64URL-encoded, not encrypted, so anyone holding the token can read every claim in it. Never put confidential data in a JWT payload.
Is it safe to paste a real token into a JWT decoder?
Only if the decoding happens locally. An access token is a credential, and pasting a live one into a website hands that site your session. This tool decodes and verifies entirely in your browser, so nothing is transmitted.
Can it verify an RS256 or ES256 token?
Yes. Paste the issuer public key as a PEM block, a JWK or a whole JWK set and the signature is checked in the browser with WebCrypto. RS, PS, ES and EdDSA are all covered, as well as the HMAC family.
Which key does it use out of a JWKS?
The one whose kid matches the kid in the token header. Without a kid in the header it falls back to the algorithm and then the key type, and if two keys would both fit it says so rather than guessing.
What does alg: none mean?
It means the token carries no signature at all. It is a real value in the specification and a real attack, because a library that trusts the header will accept an unsigned token. This tool reports such a token as unsigned, never as valid.
How do I tell whether a JWT has expired?
Read the exp claim. It is a Unix timestamp, so it is shown here as a real date with a plain-English distance such as 'expired 4 minutes ago', which distinguishes a token that just lapsed from one that was never valid.
Does decoding a token prove it is genuine?
No. Anyone can craft a token with any payload they like. Only checking the signature against the correct key proves authenticity.