Skip to content
All tools
TokensRuns locallyNo account

JWT decoder and signature verifier

Decode a JSON Web Token’s header and payload and verify HS256/HS384/HS512 signatures against a known secret - all locally.

Open in ctfpal

A JWT is three Base64-URL segments joined by dots: header, payload, signature. The first two are not encrypted - anyone holding the token can read the claims. The signature is the only thing standing between a user and an admin claim, which is why every JWT challenge is really a question about how the signature is checked.

Read the header first

The header names the algorithm, and that name is the attack surface. alg: HS256 means a shared secret - crackable if it is weak. alg: RS256 means a public key - and an implementation that lets you switch it to HS256 will verify the signature using the public key as an HMAC secret, which you already have. alg: none means no verification at all.

Header fieldWhat it enables
algAlgorithm confusion, none bypass
kidPath traversal or SQL injection into key lookup
jku / x5uPoint key retrieval at a server you control
typRarely checked; occasionally a filter bypass

Worked example

A standard HS256 token

Input

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiZ3Vlc3QiLCJhZG1pbiI6ZmFsc2V9.7vN1kUnJ3nHfP_3Xf2X8sXJ7lPMlN3Sf

Result

Header {"alg":"HS256","typ":"JWT"}, payload {"user":"guest","admin":false}

The `admin: false` claim is readable and, without signature verification, editable.

Load this example in the workspace

Common questions

Can I edit a JWT payload?
You can always edit it; whether the server accepts it depends on signature verification. That is exactly what the [none-algorithm](/tools/jwt-none-algorithm) and [secret brute force](/tools/jwt-secret-bruteforce) pages are about.