JWT Decoder, Verifier & Generator
Decode any JWT to see its header, payload, and signature. Verify signatures across all common
algorithms — HS256, RS256, ES256, EdDSA, PSS, and more. Generate new signed tokens for testing.
Scan tokens for the common JWT vulnerabilities (alg:none attacks, weak HMAC secrets,
expired claims). Everything runs in your browser via WebCrypto; nothing transmits.
How to use the JWT Decoder
For most use cases, Decode mode is what you want. Paste a JWT — the three
Base64URL-encoded segments separated by dots — and the tool splits it into header, payload, and
signature, decodes the JSON of the first two, and highlights interesting claims
(exp warnings, iss mismatches, missing standard fields).
When you need to confirm a token wasn't tampered with, switch to Verify and paste the secret (for HMAC algorithms) or the issuer's public key in PEM format (for RSA / ECDSA / EdDSA). The result is a clear pass/fail with a reason for any failure: bad signature, expired token, algorithm mismatch, malformed key.
Generate mode is for testing your own verifier. Pick an algorithm, edit the payload
JSON, paste a secret, and get a freshly signed token. The example payload uses standard claims
(sub, iat, exp) — adjust them or add custom claims as needed.
Vulnerability scan runs four checks: alg:none detection, algorithm
confusion detection, weak HMAC secret heuristics, and claim validity. Useful when you're auditing a
token issued by a third-party system you don't fully control.
What is a JWT?
A JSON Web Token is a compact, URL-safe way to transmit claims between two parties. The token is three Base64URL-encoded segments separated by dots:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NSIsIm5hbWUiOiJBbGljZSJ9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
- Header (first segment): JSON describing the algorithm (
alg) and token type (typ), plus optionally a key identifier (kid) and JWK Set URL (jku). - Payload (second segment): JSON containing the claims. Standard claims are
iss(issuer),sub(subject),aud(audience),exp(expiry),nbf(not before),iat(issued at),jti(token ID). Application-specific claims are added freely. - Signature (third segment): A cryptographic signature over
header.payloadusing the algorithm named in the header. Verifies that the token was issued by someone with access to the signing key and hasn't been tampered with in transit.
The payload is not encrypted — it's Base64URL encoded, which is trivially reversible. Anyone with the token can read its claims. The signature only guarantees authenticity, not confidentiality. For confidentiality, use JWE (JSON Web Encryption) or transport the token over TLS only.
JWT signing algorithms and when to use each
| Algorithm | Type | Key | Use case |
|---|---|---|---|
| HS256 / HS384 / HS512 | HMAC + SHA-2 | Shared secret | When issuer and verifier are the same service. Simplest setup; the secret must stay private. |
| RS256 / RS384 / RS512 | RSA + SHA-2 | Private key issues, public key verifies | When verifiers are separate services (microservices, third parties). Most common asymmetric choice. Use 2048+ bit keys. |
| ES256 / ES384 / ES512 | ECDSA + SHA-2 | EC private/public | Smaller signatures, faster verification. Preferred over RSA for mobile clients. |
| PS256 / PS384 / PS512 | RSA-PSS + SHA-2 | RSA private/public | RSASSA-PSS — RSA with probabilistic padding. Stronger security properties than RS256. Less widely supported. |
| EdDSA | Ed25519 / Ed448 | EdDSA private/public | Modern, fast, small signatures. Best choice for new systems. Adoption growing but not universal yet. |
| For new systems: ES256 or EdDSA. Both are smaller, faster, and as secure as RS256. | |||
Common JWT vulnerabilities to watch for
Most JWT bugs in the wild fall into one of these four patterns. The vulnerability scanner in this tool checks all of them.
-
The
alg:noneattack. An attacker forges a token with header{"alg":"none"}and an empty signature. A verifier that trusts the header's algorithm and accepts an empty signature when the algorithm is "none" will accept anything. Fix: verifiers must check the algorithm against an allowlist before verifying, and never accept "none." - Algorithm confusion. An attacker takes a public key intended for RS256 verification and uses it as the HMAC secret to sign an HS256 token. A verifier that uses the same library API for both algorithms — passing the key as a generic "secret" — will verify the attacker's token as legitimate. Fix: verifiers must hard-code the expected algorithm, not read it from the header.
- Weak HMAC secrets. HS256 with a secret shorter than 32 bytes (the digest size) is crackable offline within hours. HS384/512 with shorter-than-digest secrets is the same problem. Fix: HMAC secrets must be cryptographically random and at least as long as the digest output (32/48/64 bytes for HS256/384/512).
-
Expired or future-dated tokens accepted. Verifiers must check
exp(expiry),nbf(not before), and clock-skew tolerance. Servers with badly-synced clocks sometimes accept tokens that are minutes expired or hours in the future.
Frequently asked questions
Is it safe to paste production JWTs into this tool?
Which signing algorithms does the verifier support?
alg:none is detected but never accepted; the scan mode flags it as a critical vulnerability.What does the vulnerability scan check?
alg:none attacks where the token claims no signature is needed; (2) algorithm confusion where an RS256 verifier is given an HS256 token signed with the public key; (3) weak HMAC secrets — secrets shorter than the digest output for HS256/384/512; (4) expired or not-yet-valid claims (exp, nbf, iat sanity). It does not attempt to crack the secret or guess the signing key.Can I generate a JWT here for testing?
What's the difference between a JWT, a JWS, and a JWE?
How do I get an RSA public key in the right format?
-----BEGIN PUBLIC KEY-----). If your IdP exposes a JWKS endpoint, fetch the key set, find the entry whose kid matches the JWT header's kid, and convert the n and e fields to PEM — a tool like jwk-to-pem on npm handles this. Pasting JWKS JSON directly is on the roadmap; for now the tool wants PEM.