Skip to content
Free · Runs in your browser

JWT Decoder and Signature Verifier

Paste a JSON Web Token to read its header and claims, see exactly when it expires, and verify the signature with a shared secret or a public key. Everything happens in your browser.

Paste a JWT (header.payload.signature). A leading “Bearer ” is ignored.

What is inside a JWT

A JSON Web Token (RFC 7519) is three base64url strings joined by dots: header.payload.signature.

  • The header is a small JSON object that names the signing algorithm (alg), usually the type (typ: "JWT") and often a key ID (kid) that tells the receiver which key to verify with.
  • The payload holds the claims: who the token is about, who issued it, who it is for and when it is valid.
  • The signature is computed over the first two parts exactly as they appear in the token. Change one character of the header or payload and the signature no longer matches.

The header and payload are only encoded, not encrypted. Anyone who holds the token can read them, including with the Base64 decoder. So never put passwords, card numbers or other secrets in a JWT. The signature proves the content has not been changed; it does not hide it.

The registered claims, and how they go wrong

  • exp (expiration) is when the token stops being valid, as a NumericDate: whole seconds since 1 January 1970 UTC. A frequent bug is writing milliseconds (13 digits) because that is what Date.now() returns in JavaScript. Libraries then read a date tens of thousands of years away and the token never expires. This decoder flags it.
  • iat (issued at) and nbf (not before) bound the start of the validity window. If the issuer’s clock runs ahead of the server’s, fresh tokens get rejected as “not yet valid”. Most libraries allow a small leeway, often 30 to 60 seconds, for this.
  • iss (issuer) and aud (audience) say who created the token and which service it is meant for. Always check both. A valid token issued for a different application must not be accepted by yours.
  • sub (subject) identifies the user or client, and jti gives the token a unique ID, which lets a server keep a deny-list for revoked tokens.

Paste an exp or iat value into the Unix timestamp converter to see it in any format, or use the claims table above, which shows each time as a UTC date and relative to now.

HS256, RS256, PS256 and ES256 explained

HS256, HS384 and HS512 use HMAC with a shared secret. The same secret signs and verifies, so every service that checks tokens can also create them. That is fine inside one application, but risky when many services need to verify. Use a long random secret (at least 32 bytes for HS256), never a word or a phrase.

RS256, PS256 and ES256 (and their 384 and 512 variants) use a key pair. The identity provider signs with a private key it never shares, and anyone can verify with the public key, usually published at a JWKS URL such as /.well-known/jwks.json. RS uses RSA with PKCS#1 v1.5 padding, PS uses RSA-PSS, and ES uses elliptic-curve ECDSA, which gives much shorter keys and signatures for similar strength.

A token whose header says "alg": "none" has no signature at all. Servers must reject it. Also choose the expected algorithm on the server instead of trusting the header: a well-known attack swaps RS256 for HS256 and signs the token with the public key as if it were an HMAC secret.

How to verify a signature here

  1. Paste the token. The algorithm is read from its header.
  2. For HS algorithms, enter the shared secret. If your configuration stores it Base64-encoded (common in some frameworks), tick “Secret is Base64-encoded”.
  3. For RS, PS and ES algorithms, paste the issuer’s public key, either as PEM starting with -----BEGIN PUBLIC KEY----- or as a single JWK object copied from the provider’s JWKS document (pick the key whose kid matches the token header).
  4. Select Verify signature. “Signature verified” means the token was signed with that key and has not been changed since.

A valid signature is only the first check. Your server must also check exp, nbf, iss and aud. Use the “Load sample token” button to try the whole flow with a token signed on the spot.

Debugging a 401 with a JWT

When an API keeps answering 401 Unauthorized, decode the token it receives and work through the usual suspects:

  • Has it expired? Access tokens commonly live five to sixty minutes, and a client that does not refresh them fails exactly that long after login.
  • Does aud name this API, and does iss match the issuer the API trusts, including the trailing slash?
  • Does the header kid exist in the issuer’s current JWKS? After a key rotation, old tokens and cached key sets disagree.
  • Is the client sending Authorization: Bearer <token> with exactly one space, and no quotes or line breaks copied in?

Real tokens grant access to real accounts. This page decodes and verifies them in your browser and never uploads them, but treat any token you have pasted anywhere as exposed, and let it expire or revoke it.

Frequently asked questions

Is it safe to paste a JWT here?

Decoding and signature checks run entirely in your browser; the token and any key you enter are never sent or stored. Even so, prefer expired or test tokens, because a live token is a credential.

Can someone change the payload of my JWT?

They can change it, but the signature will no longer match, so a server that verifies signatures rejects the token. That is why every API must verify the signature and never just decode the payload.

Is a JWT encrypted?

A normal signed JWT (JWS) is not. Its header and payload are base64url-encoded JSON that anyone can read. Encrypted tokens (JWE) have five parts instead of three, and their content cannot be read without the key.

What is the difference between HS256 and RS256?

HS256 signs and verifies with the same shared secret. RS256 signs with a private key and verifies with a public key, so services that only verify tokens never hold the ability to create them.

Why does my token say it expires in thousands of years?

The exp value was written in milliseconds instead of seconds. JWT dates are NumericDate values in seconds since 1970, so divide by 1000 when you create the token.

Why is the signature invalid when the secret is correct?

Check whether the issuer treats the secret as Base64 (tick the option to match), that no whitespace or line break was copied with the token or secret, and that the token was not re-encoded or modified after signing.

All tools

Need something bigger than a browser tool?

We design and build web apps, internal tools, APIs and cloud infrastructure for teams that need them done properly. Tell us what you are working on.