JWT verify
Verify a JSON Web Token's signature (HS256/384/512, RS256/384/512 or ES256/384) and validate its exp / nbf / iss / aud claims. Runs in your browser; your token and key never leave your device.
About this tool
JWT verify decodes a JSON Web Token (JWT — the JWS compact
serialization) and verifies it two ways: it checks the cryptographic
signature against your key, and it validates the standard claims
(exp, nbf, iss, aud). The result is a clear report telling you whether
the token is valid, which checks passed, and — if it isn't — exactly why.
- HMAC (shared secret):
HS256,HS384,HS512— verify with the same secret string used to sign the token. - RSA (public key):
RS256,RS384,RS512— RSASSA-PKCS#1 v1.5. Paste a PEM public key (-----BEGIN PUBLIC KEY-----SPKI, or-----BEGIN RSA PUBLIC KEY-----PKCS#1). - ECDSA (public key):
ES256(P-256),ES384(P-384) — JWS rawr‖ssignatures. Paste a PEM PKCS#8 EC public key.
What gets checked
- Signature — always verified against the key. A mismatch means the token was tampered with or signed with a different key.
exp(expiry) andnbf(not-before) — compared against the current time, with an optional leeway to absorb small clock skew.iss(issuer) andaud(audience) — checked only when you supply an expected value. The audience may be a string or an array.
Security
- Setting a required algorithm makes verification reject any token whose
algheader doesn't match — the standard defense against algorithm-confusion / downgrade attacks. Tokens using the unsecuredalg: noneare always rejected. - Everything runs in your browser via WebAssembly — your token and key are never uploaded to a server. You can also run it from the gizza CLI or inside a gizza chat.
Notes
- Need to create tokens to test against? See the JWT sign tool. Need an RSA or EC key pair? See the key-pair generator tools.
- For HS* the secret is taken as raw UTF-8 bytes (the same way most JWT libraries treat a string secret).
FAQ
What goes in the key field — a secret, a public key, or a private key?
It depends on the algorithm. For HS256/384/512, paste the shared secret string
(interpreted as raw UTF-8 bytes, as most JWT libraries do). For RS* and ES*,
paste the PEM public key — -----BEGIN PUBLIC KEY----- (SPKI) or
-----BEGIN RSA PUBLIC KEY----- (PKCS#1). Never paste a private key;
verification doesn't need it.
Do I need to fill in the required-algorithm field?
It's optional but recommended: when set, any token whose alg header differs
is rejected outright, which blocks algorithm-confusion and downgrade attacks.
Left empty, the token's own alg is used — except alg: none, which this
tool always refuses.
A token that just expired still fails — can I allow for clock skew?
Yes, that's the leeway field: the number of seconds of tolerance applied
to both the exp (expiry) and nbf (not-before) checks. It defaults to 0,
so even one second past expiry fails until you grant some leeway.
How are the issuer and audience claims matched?
Both are only checked when you supply an expected value. The issuer must equal
the token's iss exactly. The audience passes if the token's aud — whether
a single string or an array — contains your expected value.
Developer & Automation Access
Run it from the terminal
Same engine as this page, headless — via the gizza CLI:
gizza tool jwt-verify "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0...." 'key=your-256-bit-secret (or paste a PEM PUBLIC key for RS*/ES*)'New to the CLI? Get gizza →
Open it by URL
Pre-fill and auto-run this tool with query parameters — the names match the API/CLI:
https://gizza.ai/tools/jwt-verify/?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0....&key=your-256-bit-secret%20%20%20%28or%20paste%20a%20PEM%20PUBLIC%20key%20for%20RS%2A%2FES%2A%29&algorithm=&issuer=https%3A%2F%2Fissuer.example.com&audience=my-api&leeway=0Machine-readable descriptor: tool.json — title + parameters JSON Schema for agents.
