JWT Decoder

Decode JSON Web Tokens (JWT) on the client side. Inspect header, payload, verify signature (HS256), check expiration, and debug claims.

Leave empty to skip signature verification. For HS256, provide the same secret that signed the token.
These examples illustrate real JWT attacks. The tool will show verification failures or warnings.
Zero data exposure: All operations are performed locally in your browser. Tokens never leave your device. The page is stateless — refreshing clears all inputs.

JSON Web Tokens: technical deep dive & security guidance

JSON Web Token (JWT) (RFC 7519) is a compact, URL-safe means of representing claims between parties. Widely used in OAuth2, OpenID Connect, and API authentication. This tool helps developers decode, inspect, and verify token integrity.

JWT Structure (Three Parts)

A well-formed JWT consists of three parts separated by dots (.):

  • Header – contains metadata about the token, typically the signing algorithm (e.g., HS256, RS256) and the token type (JWT).
  • Payload – contains the claims. Claims are statements about an entity (typically the user) and additional data (e.g., expiration, issuer).
  • Signature – created by taking the encoded header, encoded payload, a secret, and the algorithm specified in the header. This ensures the token hasn't been altered.

JWT Structure: header.payload.signature

Header: algorithm & token type | Payload: claims (statements) | Signature: cryptographic verification of integrity.

Signature verification (HS256) – how it works

The signature for HMAC-SHA256 is computed as: HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret). The result is base64url-encoded. This tool recomputes the signature locally when a secret is provided, allowing you to detect tampering. For asymmetric algorithms (RS256, ES256), a public key is required — we decode the token but do not verify the signature.

RS256 verification & JWKS endpoints

RS256 uses RSA digital signatures. The token is signed with a private key, and verification requires the corresponding public key. In production, public keys are often exposed via a JWKS (JSON Web Key Set) endpoint (e.g., https://your-auth-server/.well-known/jwks.json). To verify an RS256 JWT, fetch the JWKS, locate the key matching the kid (key ID) from the header, and use the RSA public key to validate the signature. Many libraries (like jsonwebtoken in Node.js or PyJWT in Python) handle this automatically when you provide the JWKS endpoint.

Real‑world attack scenarios & demos

The attack buttons above demonstrate two critical vulnerabilities:

  • "alg: none" attack – Some vulnerable JWT libraries accept tokens with the "alg": "none" header, effectively bypassing signature verification. Never accept such tokens. The demo token will show a clear warning.
  • Tampered payload – If an attacker modifies the payload but does not recompute the signature, verification fails. Our demo loads a token with altered claims and an invalid signature, showing the failure.

These examples reinforce why proper signature validation is mandatory.

JWT security checklist (OWASP & best practices)

Practice Description
Always validate algorithm Explicitly enforce expected algorithms (e.g., HS256 or RS256). Reject tokens with "none".
Verify signature Never trust a JWT without cryptographic signature verification.
Check expiration (exp) Reject expired tokens; use a reasonable leeway (e.g., 30 seconds).
Validate issuer (iss) & audience (aud) Ensure the token was issued by a trusted authority and intended for your application.
Use short-lived tokens Reduce risk by setting short expiration times (minutes/hours) and refresh via refresh tokens.
Store tokens securely Never store JWT in localStorage if sensitive; prefer httpOnly cookies with proper flags.
Protect against replay Use jti (JWT ID) claim and maintain a blacklist if necessary.

Code examples: verifying JWTs in your backend

Below are minimal examples for HS256 and RS256 verification. These are for educational purposes — always adapt to your environment.

Node.js (jsonwebtoken)
// HS256 const jwt = require('jsonwebtoken'); const token = 'eyJ...'; const secret = 'your-secret'; try { const decoded = jwt.verify(token, secret); console.log('Valid HS256 token', decoded); } catch(err) { console.error('Invalid token'); } // RS256 (with JWKS) const jwksClient = require('jwks-rsa'); const client = jwksClient({ jwksUri: 'https://example.com/.well-known/jwks.json' }); function getKey(header, callback) { client.getSigningKey(header.kid, (err, key) => { const signingKey = key.getPublicKey(); callback(null, signingKey); }); } jwt.verify(token, getKey, { algorithms: ['RS256'] }, (err, decoded) => { if (err) console.error('RS256 verification failed'); else console.log('Valid RS256 token', decoded); });
Python (PyJWT)
import jwt # HS256 token = "eyJ..." secret = "your-secret" try: payload = jwt.decode(token, secret, algorithms=["HS256"]) print("Valid HS256 token", payload) except jwt.InvalidTokenError: print("Invalid token") # RS256 with JWKS from jwt import PyJWKClient jwks_client = PyJWKClient("https://example.com/.well-known/jwks.json") signing_key = jwks_client.get_signing_key_from_jwt(token) try: payload = jwt.decode(token, signing_key.key, algorithms=["RS256"]) print("Valid RS256 token", payload) except jwt.InvalidTokenError: print("Invalid token")

Frequently Asked Questions

RS256 verification requires a public key. This tool decodes RS256 tokens fully and shows header/payload, but does not perform signature validation. Use the code examples above for server-side verification.

No. All decoding, verification, and attack demos happen locally in your browser using JavaScript. No network requests are made with your token data.

It indicates that either the token has been altered, the secret provided is incorrect, or the algorithm is not HS256. Reject such tokens.

Always explicitly specify allowed algorithms in your JWT library (e.g., `algorithms: ['HS256']`). Never accept tokens that omit signature validation.

The core logic is based on standard Web Crypto API and can be inspected via browser DevTools. For transparency, the source code of this page is publicly available on our GitHub (link in footer).

About this tool – Built according to RFC 7519 and OWASP JWT guidance. The cryptographic verification uses the Web Crypto API. All processing is client-side; no data is transmitted. Maintained by the GetZenQuery development team. For security concerns, please contact us via the repository.