88% of basic web app attacks involve stolen credentials - here's how to decode, validate, generate, and stress-test JWTs online free in 2026.
A JWT looks encrypted but usually isn't - anyone can decode the header and payload in seconds. This guide covers decoding, signature validation, generation, and fuzzing JWTs safely.
A JWT looks encrypted. It isn't - by default it's just signed, and anyone with the token can read every field in the payload without knowing the secret. That distinction trips up more developers than any other part of JSON Web Tokens.
This guide covers decoding a JWT by hand, validating its signature, generating tokens and secrets for testing, and fuzzing your own auth server against known attack classes - with a free tool for each step.
A JWT is three dot-separated, Base64Url-encoded segments: a header describing the signing algorithm, a payload holding the claims, and a signature proving the first two haven't been altered. None of that requires encryption - it requires a valid signature.
Paste any token into the JWT Decoder and it splits the string at the dots and decodes the first two parts automatically - no manual Base64 math required.
Decoding shows you the claims; validating proves they weren't tampered with. A validator recomputes the signature using the algorithm in the header and your secret (or public key), then compares it byte-for-byte against the signature on the token.
The JWT Validator also checks time-based claims automatically:
{
"sub": "1234567890",
"iat": 1751251200,
"exp": 1751337600
}Here, exp is a Unix timestamp - the token becomes invalid the instant the current time passes it, regardless of whether the signature is still valid. That's the mechanism behind "session expired" errors, and it's the main lever teams have for limiting how long a stolen token stays useful.
Building or debugging an auth flow usually means minting test tokens by hand before wiring up a real identity provider. The JWT Generator builds a valid, signed token from a header and payload you define:
// Input
Header: { "alg": "HS256", "typ": "JWT" }
Payload: { "sub": "user_42", "role": "admin", "exp": 1751337600 }
Secret: "a-strong-random-secret"
// Output
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyXzQyIiwicm9sZSI6ImFkbWluIiwiZXhwIjoxNzUxMzM3NjAwfQ.9f2a1c...The secret itself matters as much as the algorithm - a short or guessable HMAC secret can be brute-forced offline. The JWT Secret Generator produces high-entropy secrets like k7Jc9!qz8fLp2VbY6nRt0XsWm3AoDeGh, sized for HS256/384/512 rather than a short password reused from somewhere else.
Security researchers disclosed six critical CVEs targeting JWT implementations in 2025, several stemming from algorithm-confusion bugs - a server configured to accept both HS256 and RS256 can sometimes be tricked into verifying a forged token with the wrong key type. The classic version of this is the "alg": "none" attack:
// Forged header - claims no signature is required
{ "alg": "none", "typ": "JWT" }An attacker sets alg to none, drops the signature entirely, and a misconfigured server accepts the token anyway - full account takeover with zero cryptographic work. The JWT Fuzzer throws exactly this class of malformed and adversarial token at an endpoint you control, so you find the misconfiguration before an attacker does. Only run it against systems you own or are authorized to test.
"alg": "none" explicitly and enforce an algorithm allowlist server-side.Split the token at the two dots, then Base64Url-decode the first two segments (header and payload) - no secret needed for this part. The JWT Decoder does this instantly if you'd rather skip the manual decoding.
Yes, when implemented correctly. The signature prevents tampering, but the payload is readable by default. Always transmit JWTs over HTTPS and never store sensitive data in the claims.
JWS (JSON Web Signature) signs the payload for integrity but leaves it readable. JWE (JSON Web Encryption) actually encrypts the payload so it's hidden without the decryption key. Most tokens called "JWTs" in the wild are JWS, not JWE.
Because JWTs are stateless, a server can't easily revoke one once issued. The exp (expiration) claim caps how long a stolen or leaked token stays valid, which is why short-lived tokens paired with refresh flows are the standard pattern.
RFC 7518 covers symmetric HMAC (HS256, HS384, HS512) using one shared secret, and asymmetric RSA/ECDSA (RS256, ES256) using a public/private key pair. Mixing the two without an algorithm allowlist is exactly what algorithm-confusion attacks exploit.
Decoding, validating, generating, and fuzz-testing a JWT are four distinct jobs, and conflating "signed" with "encrypted" is the single most common JWT mistake. Treat the payload as public, keep tokens short-lived, and verify signatures with an explicit algorithm allowlist.
Every tool here runs free in your browser. Start with the JWT Decoder and JWT Validator, or browse the full JWT toolkit for generation, secret creation, and fuzzing tools.