MiServe DevTools

Your lid

Pin tools here. They are saved in this browser.

JWT Decoder, Verifier & Signer

Decode a JSON Web Token, read its claims and expiry, verify the signature with a secret or a public key, and sign HMAC tokens.

Runs in your browser. Nothing you paste is uploaded.

About this tool

What a JWT is

A signed JSON Web Token (RFC 7519) is three Base64URL strings joined by dots: a header, a payload and a signature. The header says how the token is signed (alg). The payload is a JSON object of claims, statements such as who the token is about (sub), who issued it (iss) and when it expires (exp). The signature is computed over the first two parts.

Decoding is not verification. The header and payload are only encoded, not encrypted: anyone who holds a token can read it, as this page does without any key, and anyone can write a token with any claims they like. Never put a secret in a JWT payload, and never trust a claim before the signature has been verified.

Verifying the signature

HS256, HS384 and HS512 are HMACs: the same secret signs and verifies, so everyone who can verify can also forge. RS256, PS256 and ES256 and their 384 and 512 variants are asymmetric: the issuer signs with a private key, and you verify with the public key, which is often published as a JWK Set at the issuer's jwks_uri.

Paste the secret, or the public key as PEM, as an X.509 certificate or as a JWK. The check is done by your browser's Web Crypto API. The result is one of three things: the signature is valid, it is invalid, or it could not be checked. In the last case the page says why: there is no key, the key has the wrong type or curve, the algorithm is not supported, or the header says "alg": "none", which means the token is not signed at all.

A valid signature is necessary but not sufficient. A real service must also check the expiry, the issuer and the audience, and must decide which algorithm it accepts itself instead of believing the token's header.

Times, the sample token and signing

exp, nbf and iat are Unix timestamps in seconds. The claims table shows them as dates in your time zone, and the badge above it says whether the token is expired, not valid yet, or how long it remains valid, by your device's clock.

The page opens with a sample token that is created in your browser, issued now and valid for one hour. It is signed with HS256 and the sample secret devtools-sample-secret-not-for-production, which is why it verifies. That secret is public: do not use it for anything real.

Sign builds a token from the header and payload you edit and an HMAC secret. Use it for tests and local development. Tokens, secrets and keys you enter stay in this tab: nothing is sent, stored or logged.

Questions

Is it safe to paste a JWT here?

The token is decoded and verified by JavaScript in your browser and is not sent to a server. Even so, a token that has not expired is a working credential, so be careful with any tool that asks for one and prefer expired or test tokens.

Can anyone read the contents of a JWT?

Yes. The header and payload are Base64URL-encoded JSON, not encrypted, so anyone who has the token can read them without a key. The signature hides nothing: it only shows that the token was created by someone who holds the signing key and that it was not altered afterwards.

What is the difference between HS256 and RS256?

HS256 uses one shared secret for both signing and verifying, so every party that verifies could also create tokens. RS256 uses a private key to sign and a public key to verify, which lets many services verify tokens that only the issuer can create.

Why does my token show as expired?

Its exp claim is a moment in the past according to your device's clock. Some servers tolerate a small clock difference, but an expired token has to be replaced, by signing in again or by using a refresh token.

More in Encoding