A JWT (JSON Web Token) is a compact, signed credential that travels as a text string. It's used mainly as an access token in APIs, logins and OAuth 2.0 / OpenID Connect: the client sends it with every request in the Authorization: Bearer … header and the server checks the signature to learn who you are and what you can do without querying a database. The signature guarantees that nobody has tampered with it, but it does not encrypt its contents: anyone can read it (this very tool does).
A JWT has three dot-separated parts: header.payload.signature.
• Header — JSON with the signing algorithm (alg) and the type (typ: JWT); sometimes a kid identifying the key used.
• Payload — JSON with the claims: the token's data (user, permissions, expiry…).
• Signature — the result of signing header.payload with the header's algorithm.
The header and payload are encoded in Base64URL (not encryption, just URL-safe text). This tool decodes them to readable JSON and colors the three parts.
Two ways to work:
• Decode — paste a token in the Decode tab and you'll instantly see the header, the payload and a table of claims with their meaning and expiry. You don't need the key to read it.
• Create — in the Create tab you write the payload (JSON), pick an algorithm, supply the secret or private key and get a signed token.
The freshly created token can be handed off with one click to Verify or to the authentication-flow visualizer. Everything happens in your browser: neither tokens nor keys leave your machine.
The header's alg field says which algorithm signed it. This tool supports 12, in three families; the number is the SHA hash size (256/384/512).
• HS256 / HS384 / HS512 (HMAC + SHA) — symmetric: the same secret key signs and verifies. Simple and fast. Use them when the signer and the verifier are the same party or share the secret securely (e.g. a backend that issues and consumes its own tokens). Downside: anyone who can verify can also forge.
• RS256 / RS384 / RS512 (RSA PKCS#1 v1.5 + SHA) — asymmetric: you sign with the private key and verify with the public key. The most common in OAuth/OIDC: the issuer keeps the private key and publishes the public one (JWKS) so anyone can verify without being able to forge. Large keys (2048 bits) and slower signing.
• PS256 / PS384 / PS512 (RSA-PSS + SHA) — asymmetric RSA like RS, but with PSS (probabilistic) padding, considered more robust. Choose it if your platform supports it and you want modern RSA.
• ES256 / ES384 / ES512 (ECDSA + P-256/P-384/P-521 curves) — asymmetric elliptic-curve: same guarantees as RSA but with much smaller, faster keys and signatures. A good default for new tokens.
Rule of thumb: HS* if you share a secret in a controlled environment; ES* or RS*/PS* if third parties must verify without being able to issue.
In Verify the signature is checked for real (browser Web Crypto):
• Pick the algorithm (the one declared in the header is preselected).
• If it's HS*, paste the secret. If it's RS/PS/ES*, paste the public key in PEM (-----BEGIN PUBLIC KEY-----) or JWK (JSON); the tool detects which.
• You'll see Valid signature or invalid, plus the expiry (exp) and "already valid" (nbf) checks.
Two key protections: alg:none (unsigned tokens) is always rejected, and you're warned about algorithm confusion — verifying an asymmetric token as HMAC (or vice versa) is a known security flaw. The key never leaves your machine.
In Create you build and sign a token:
• Write the payload as JSON; the chips quickly add registered claims (sub, iss, aud, exp…) or common ones (name, role, scope…) with example values.
• Pick the algorithm and supply the secret (HS*) or the private key PEM/JWK (RS/PS/ES*). Optional: a kid in the header.
• Generate keys instantly creates a random secret (HMAC) or a key pair (private + public in PEM and JWK) for testing.
• Sign and copy the token. With one click take it to Verify (round-trip) or to the authentication flow.
Claims are the payload's fields. The registered ones (RFC 7519) have standard meaning:
• iss — issuer: who created the token.
• sub — subject: who it identifies (usually the user).
• aud — audience: who it's for; the receiver must be in it.
• exp — expiration: the instant after which it stops being valid.
• nbf — not before: not valid until that instant.
• iat — issued at: when it was created.
• jti — unique ID: useful for revocation or anti-replay.
Times are in Unix seconds (seconds since 1970). The tool shows them as a local date and relatively ("3 h ago", "in 42 min") and flags in red if the token is expired (exp in the past) or not yet valid (nbf in the future). Note: decoding does not validate — expiry only binds if the server checks it on verification.
The Test authz tab simulates a gateway or API decision: you define the rules you'd require (issuer, audience, scopes/roles) and the tool checks the pasted token against them, showing ALLOW or DENY rule by rule, indicating what's missing or doesn't match (including exp and nbf). It helps you understand why a token would be accepted or rejected without standing up the backend.
Key points:
• The signature proves integrity and origin, but does not encrypt: the payload is readable by anyone. Never put sensitive data (passwords, cards…) in a JWT without additional encryption (JWE).
• Treat tokens as secrets: don't paste them in public places or store them in repos. The examples here use toy secrets and keys; for production use real keys generated securely and do not paste them into this tool.
• Always set exp (short expiry) and verify on the server both the signature and the expected algorithm. Reject alg:none and algorithm confusion.
• All the work is local in your browser: nothing is sent to any server.