JWT decoder, verifier and builder
Paste a token and it splits into header, payload and signature at once; times appear in your time zone with a countdown, and 16 security rules highlight dangerous settings. Verify the signature with a secret, PEM, certificate, JWK or JWKS. The second tab builds a test token with a generated secret or key pair.
Free, no sign-up
Paste a token (a “Bearer” prefix is fine). It is decoded in your browser and never sent anywhere.
HS*: the secret. RS/PS/ES/EdDSA: a public key PEM, certificate, JWK or JWKS (the key is picked by kid). Never stored.
How it works
Decoding
The token is split into three parts (JWS Compact, RFC 7515 §7.1), each decoded from base64url. Errors name the part and the character position: a “+” instead of “-”, for example, means the token was encoded with standard Base64.
Signature check
The algorithm comes from the header, but only from a known list, and the key must match it — this is the defence against algorithm substitution. Keys: a secret (text or base64), PEM (SPKI, PKCS#1, an X.509 certificate, PKCS#8 — its public part is used), JWK or a JWKS with selection by kid.
Times
exp, nbf and iat are shown as dates in your time zone and relative to now, with a countdown to expiry. Clock skew tolerance is 60 seconds.
Findings
Each has a rule ID, evidence from the token, an explanation and what to do. Copy or download the report as Markdown — without the key or signature.
Building
Edit the header and payload as JSON with the error line and column; buttons set iat, exp, nbf and jti. Sign with HS256/384/512 and a random secret or with ES256/EdDSA and a new key pair (PEM and JWK to download).
Standards and rules
JWS — RFC 7515, JWT — RFC 7519, algorithms — RFC 7518, EdDSA in JOSE — RFC 8037, JWK/JWKS keys — RFC 7517, base64url — RFC 4648 §5, security guidance — RFC 8725 (JWT Best Current Practices).
HS256 / HS384 / HS512
- Scheme
- HMAC-SHA-2
- Key
- shared secret ≥ hash length
- Standard
- RFC 7518 §3.2
- Verified with
- WebCrypto HMAC
RS256 / RS384 / RS512
- Scheme
- RSASSA-PKCS1-v1_5
- Key
- RSA ≥ 2048
- Standard
- RFC 7518 §3.3
- Verified with
- WebCrypto
PS256 / PS384 / PS512
- Scheme
- RSASSA-PSS, salt = hash length
- Key
- RSA ≥ 2048
- Standard
- RFC 7518 §3.5
- Verified with
- WebCrypto
ES256 / ES384 / ES512
- Scheme
- ECDSA, r‖s signature
- Key
- P-256 / P-384 / P-521
- Standard
- RFC 7518 §3.4
- Verified with
- WebCrypto
EdDSA
- Scheme
- Ed25519
- Key
- OKP Ed25519
- Standard
- RFC 8037
- Verified with
- @noble/curves
none
- Scheme
- unsigned
- Key
- —
- Standard
- RFC 7518 §3.6
- Verified with
- always a finding
JWT-ALG-NONE
- What
- alg: none — unsigned token
- Severity
- critical
- Why it matters
- Anyone can forge an unsigned token. If a server accepts alg=none (in any letter case), signature checking is switched off.
JWT-ALG-CONFUSION
- What
- Algorithm confusion: HS* with a public key
- Severity
- critical
- Why it matters
- The classic attack: the token says alg=HS256 and the server uses its public RSA/EC key as the HMAC secret. Everyone knows the public key, so everyone can sign tokens.
JWT-ALG-KEY-MISMATCH
- What
- Algorithm does not match the key type
- Severity
- high
- Why it matters
- A signature cannot be checked with a key of another type: ES256, for example, needs an EC P-256 key.
JWT-WEAK-SECRET
- What
- Weak HMAC secret
- Severity
- high
- Why it matters
- A secret shorter than the hash output (RFC 7518 §3.2: at least 256 bits for HS256) or a dictionary word can be cracked offline from a single captured token.
JWT-SIG-EMPTY
- What
- Empty signature with alg ≠ none
- Severity
- high
- Why it matters
- There is no signature although the header claims an algorithm. This is how attackers probe whether a server skips the check.
JWT-NO-EXP
- What
- No expiry (exp)
- Severity
- medium
- Why it matters
- Without exp a stolen token works forever, until the key is rotated.
JWT-LONG-LIFETIME
- What
- Very long lifetime
- Severity
- medium
- Why it matters
- A lifetime over 24 h for an access token (over 30 days — medium): a stolen token stays usable for long, and a JWT cannot be revoked without a denylist.
JWT-EXPIRED
- What
- Token has expired
- Severity
- info
- Why it matters
- A server must reject this token (RFC 7519 §4.1.4).
JWT-NBF-FUTURE
- What
- nbf is in the future
- Severity
- low
- Why it matters
- The token is not valid yet. Sometimes this means the issuer's clock is off.
JWT-IAT-FUTURE
- What
- iat is in the future
- Severity
- medium
- Why it matters
- The token was “issued” after now — the issuer's clock is ahead or the token was crafted by hand.
JWT-SENSITIVE-CLAIM
- What
- Personal or secret data in the payload
- Severity
- medium
- Why it matters
- A JWS payload is not encrypted — it is base64url that anyone holding the token can read (browser, logs, proxies).
JWT-CRIT-UNKNOWN
- What
- crit header with extensions
- Severity
- high
- Why it matters
- A recipient must reject the token if it does not understand any extension listed in crit (RFC 7515 §4.1.11). A library that silently ignores crit is a vulnerability.
JWT-REMOTE-KEY
- What
- jku / x5u / jwk: the token names its own key
- Severity
- high
- Why it matters
- If the server fetches the key from jku/x5u or trusts an embedded jwk without an allowlist, an attacker signs tokens with their own key (and jku is also an SSRF vector).
JWT-KID-INJECTION
- What
- Suspicious kid
- Severity
- high
- Why it matters
- A kid with “../”, quotes, “;”, “|”, “$(”, a null byte or a URL looks like injection: a server that puts kid into a file path, SQL or a command can be made to use an attacker's key.
JWT-NO-AUD
- What
- No audience (aud)
- Severity
- low
- Why it matters
- Without aud a token issued for one service may be accepted by another service of the same issuer.
JWT-PAYLOAD-NOT-JSON
- What
- Payload is not JSON
- Severity
- info
- Why it matters
- This is a valid JWS but not a JWT: a JWT payload is a JSON object of claims (RFC 7519 §7.2).
- Weak secret: shorter than the hash output (RFC 7518 §3.2), no more than 4 distinct characters, or from a dictionary of values seen in docs and tutorials (secret, your-256-bit-secret, your-384-bit-secret, your-512-bit-secret, your_jwt_secret, your-secret-key, jwt_secret, jwt-secret and others — 44 in total).
- Long lifetime: over 24 h is low severity, over 30 days is medium.
- kid: “../”, quotes, “;”, “|”, “&”, “$”, “<>”, “--”, SQL words UNION/SELECT, a null byte, a URL, an absolute path or more than 128 characters.
The tool's tests check the reference examples from RFC 7515 (appendices A.1 HS256 and A.3 ES256), RFC 8037 (A.4 EdDSA, byte-exact signature) and RFC 7519 §6.1 (unsecured JWT); load them with the “RFC vectors” menu.
Limitations
- The tool checks the token's signature and content, not how your server validates it: a library may accept alg none or skip aud — that is only visible in code and configuration.
- Encrypted tokens (JWE, five parts) are not decrypted — only the header is shown.
- Keys from jku/x5u are not downloaded (the tool makes no network requests) — paste the JWKS yourself. The x5c certificate chain is not validated.
- Token building is for testing: the key pair lives in the tab's memory; production keys are created and kept on the server (KMS, environment secrets).
Privacy and security
- The token, secrets and keys are processed only in your browser (WebCrypto and @noble/curves): they are not sent to a server, not put into the page URL and not saved to localStorage — they are gone when the tab closes.
- Only settings are saved in the browser: the open tab, the build algorithm and the secret encoding.
- Secrets and keys come from the browser's cryptographic generator (crypto.getRandomValues / WebCrypto generateKey); secret characters are picked without bias.
- Analytics receives only the fact of a decode, verification or export and a category (algorithm family, result) — no token or key.
- The result reaches us only if you send a request yourself and keep the “Attach the result” box ticked — the form shows exactly what will be sent. Keys, passwords and tokens are never part of the summary: it holds only the algorithm, the signature check result, the rules and the times — no token, payload, claim values, secret or key.
- Do not paste production private keys into any online tool, this one included: verification needs only the public key.
Related tools
All tools · 40
Password and passphrase generatorPasswords, passphrases from English or Russian words, PINs and patterns from a cryptographic generator, exact entropy and crack times, and a check of your own password for common weaknesses.
WireGuard config generatorA website cannot be a VPN — but here you build a real WireGuard setup for your server: X25519 keys, wg0.conf with NAT, a .conf and QR code per phone and laptop, subnet and route checks, a ZIP and setup steps. Keys never leave your browser.
SSH key generatorEd25519 and ECDSA P-256 in OpenSSH format with a passphrase (like ssh-keygen), SHA256/MD5 fingerprints and randomart, restricted authorized_keys, ~/.ssh/config and an inspector for any public key. Keys are generated on your device.
CIDR subnet calculatorIPv4 and IPv6: mask, range and exact address count, a binary view with the network boundary, subnetting and VLSM, list merging, overlaps with an address map, reverse DNS zones.
Image compressor (WebP/AVIF)Drop images in — WebP, AVIF or JPEG by quality or a target size in KB, a 1:1 before/after slider, srcset and <picture>, batch ZIP. All in the browser.Need an authentication review of your product?
A code and access audit: how tokens are issued and validated, roles, secrets, RLS and APIs — with a risk map and a fix plan. The first short call is free.
- The first short conversation is free — we choose the format
- NDA — yours or ours
- Pricing after a brief and an agreed scope