Skip to content

← All tools

Free online tool

JWT decoder and signature checker

Paste a token to see the header, the payload and every claim, with expiry and issue times as real dates and how long ago or how soon they are. Add a secret or public key to check the signature. The token never leaves this page.

A leading "Bearer ", quotes and line breaks are removed for you. The token and key stay in this page. They are not uploaded, saved or logged.

Decoding is not verifying. Anyone can create a token that decodes to these claims. Only a signature check with the right key shows that the issuer really made it.

Header

{
  "alg": "HS256",
  "typ": "JWT"
}

Payload

{
  "iss": "https://auth.example.com",
  "sub": "user-1234",
  "aud": "api.example.com",
  "name": "Ada Lovelace",
  "role": "admin",
  "iat": 1760000000,
  "exp": 1760003600
}

Claims

ClaimValueMeaning
isshttps://auth.example.comIssuer: who created the token
subuser-1234Subject: who the token is about, usually a user ID
audapi.example.comAudience: who the token is meant for
exp1760003600UTC: 2025-10-09 09:53:20 UTCExpires at: reject the token from this time on
iat1760000000UTC: 2025-10-09 08:53:20 UTCIssued at: when the token was created
nameAda LovelaceCustom claim
roleadminCustom claim

Times are checked against this device's clock with no leeway. Servers often allow a minute or two of clock difference.

Signature

32 bytes, base64url: WQbV-ewrpWMwGk_AJhqOfHb5Wl4F0ndaPKFE2cr7ArY

Check the signature (optional)

Paste the key that should have signed the token. HS tokens need the shared secret. RS, PS and ES tokens need the public key, as a PEM (-----BEGIN PUBLIC KEY-----) or a JWK. The key type must match the token's alg: an HS token is never checked with a public key, and an RS/PS/ES token never with a secret, which blocks the classic algorithm-confusion trick.

Algorithm in the header: HS256

The secret is

The example was signed with the secret "demo-secret-change-me".

Checking…

How it works

  • •A signed JWT is three base64url parts joined by dots: header, payload and signature. The page splits them, decodes the first two as UTF-8 JSON and shows them formatted. In the formatted header and payload, long numbers are shown exactly as written; in the claims table they are shown as JavaScript reads them, so a number with more than about 15 digits can be rounded there.
  • •exp, nbf and iat are read as seconds since 1970 (UTC), as the JWT standard (RFC 7519) defines them, and compared with your device clock once a second. A token counts as expired from the exact second in exp, with no leeway.
  • •Warnings point out things that often cause bugs or security holes: alg "none", no exp, times written in milliseconds, duplicate claims, padding or standard base64, and keys embedded in the header. A token with 5 parts is recognised as encrypted (JWE); only its header can be read.
  • •Signature checks use your browser's built-in Web Crypto: HMAC for HS256/384/512, RSA PKCS#1 v1.5 for RS256/384/512, RSA-PSS for PS256/384/512 and ECDSA (raw R||S signatures, as JWT requires) for ES256/384/512. Keys can be a secret as text or base64, a PEM public key or a JWK.
  • •The key must fit the algorithm in the header. An HS token is never checked with a public key and an RS/PS/ES token never with a secret, so a forged token cannot trick the check by switching its alg.
  • •This tool saves nothing: there is no history, and refreshing the page clears it. The input limit is 2 MB.

Questions

Is it safe to paste a real token here?
The token and key are processed by code running in this page. They are not sent to a server, saved in the browser or written to logs. A live token is still a credential, though: treat any screen or clipboard it passes through with care, and prefer expired or test tokens when you can.
Does decoding a JWT prove it is genuine?
No. The header and payload are only base64url-encoded, not encrypted, so anyone can read them and anyone can create a token with any claims. Only a signature check with the issuer's key shows the token is genuine, and the server must also check exp, aud and iss.
Why does my token show as expiring thousands of years from now?
JWT times are seconds since 1970. If the issuer wrote milliseconds, the number is 1,000 times too big, so it reads as a date far in the future. The page warns about this and shows what the value would be as milliseconds.
Why does the checker refuse my public key for an HS256 token?
HS256 uses one shared secret for signing and checking. If a server accepted a public key as that secret, an attacker who knows the public key could sign their own tokens. That is the algorithm-confusion attack, so the page only checks HS tokens with a secret and RS, PS and ES tokens with a public key.

Related