JWT Debugger
Treat real tokens as credentials
How JWT Debugger works
Two opposite operations share one workflow. Reading a token requires no key whatsoever — chop the string at its dots and the first two segments unpack directly into JSON objects. Producing a token does require a key, since its trailing segment is a keyed digest taken over everything preceding it.
Which digest, and which key, depends on the named algorithm. The HS family computes an HMAC across the exact characters of the first two segments and the dot between them, using one shared key that both mints and checks — possession of it confers the ability to forge, so a public deployment must keep it on the server and nowhere else. The RS, PS, ES and Ed25519 families instead sign with a private key and check with the matching public one, which is what lets a service publish the means to verify its tokens without publishing the means to issue them.
Almost every awkward JWT bug is found by alternating between the two halves. You read a failing token, spot a claim that looks wrong, rebuild it with the value corrected, sign it with the same key, and read the result back. Splitting that loop across two separate pages adds a navigation and a re-paste to every lap of it, which is why both halves live behind one switch here, sharing whatever key you typed.
Nothing about the encoding hides anything. Whoever holds a token can lift every claim out of it without permission or credentials — what the trailing segment buys you is proof that the first two segments came from a key holder and reached you unmodified. Confidentiality is simply not on offer, so keep card numbers, passwords and internal identifiers out of the claim set entirely.
Reference
- token = base64url(header) + "." + base64url(payload) + "." + base64url(signature)
- signing input = base64url(header) + "." + base64url(payload) — the exact ASCII, never a re-serialisation
- HS256 / HS384 / HS512: signature = HMAC-SHA-n(shared key, signing input)
- RS / PS / ES / Ed25519: signature = sign(private key, signing input), checked with the public key
- iat / nbf / exp are NumericDate values — whole seconds counted from 1970-01-01T00:00:00Z
- Base64URL: + becomes -, / becomes _, trailing = is dropped
How to use this tool
Choose a direction
Stay on Decode when a token already exists and something about it is failing. Flip to Encode when you need to manufacture one that reproduces a failure on demand.
Work on the claims
Reading, you get the two JSON objects plus every time-bounded claim resolved against the clock. Writing, each keystroke re-signs, and the shortcut buttons stamp a fresh issue time or an hour of remaining life into the claim set.
Type the key once
Whatever you enter persists across the switch, so a token minted on one side can be checked on the other without retyping anything. Symmetric algorithms take a shared secret — tick the Base64 option in Settings when yours is stored encoded rather than as literal characters. The rest take a PKCS#8 PEM block or a JWK, and the private key you signed with also serves for checking, since only its public half is used.
Hand work to the other half
Press Decode this on a token you just built, or Edit & re-sign on one you pasted in, and the switch flips with your material already loaded.
Worked examples
Tracking a refused request back to its cause
- Given
- A bearer credential your gateway keeps rejecting, pasted on the reading side
- Result
- Claims readable, key check green, expiry timestamp already in the past
Three independent answers arrive at once, and only one of them is red. Chasing the key when the clock is the culprit costs an afternoon.
Manufacturing a token that reproduces a bug
- Given
- An hour of remaining life stamped in, then edited by hand down to five seconds
- Result
- A credential you can watch lapse while a request is in flight
Renewal paths are notoriously hard to exercise because real credentials outlive the test run. Shrinking the window makes the awkward case reproducible.
Separating a key mismatch from tampering
- Given
- Material built on one side, then read back with a deliberately altered claim
- Result
- Structure still parses perfectly; the keyed check turns red
Both faults present identically at first glance. Rebuilding the same claims yourself and comparing the trailing segment tells you which one you are looking at.
When to use it
- Diagnosing a rejected request by reading what a credential actually asserts, rather than inferring it from application logs.
- Minting throwaway credentials to exercise an endpoint whose guard you are currently writing.
- Reproducing a colleague’s failure locally by rebuilding their claim set with your own key.
- Confirming that a service refuses material whose claims were edited after it was issued.
- Auditing which personal details your issuer is placing where every recipient can read them.
- Demonstrating the structure to someone learning it, without a live credential leaving the machine.
Things to watch out for
- Reading proves nothing at all. Fabricated material parses exactly as cleanly as authentic material, and only a key check separates the two.
- Keep a shared key long and randomly generated — 32 bytes or more. Anything a person invented can be recovered offline from a single captured token.
- Never let an incoming token dictate which algorithm you check it with. Fix that choice in your own configuration; the classic forgeries all begin with a verifier that trusts the field it is meant to be checking. This page reads the declared algorithm to decide which check to offer you, and then pins it to that one value — a real verifier should pin it to a value the token never gets a say in.
- Reach for an asymmetric family whenever more than one party checks your tokens. Handing every verifier a shared secret hands every verifier the ability to issue, and that authority is almost never what was intended.
- Time-bounded claims count whole seconds. Handing a millisecond timestamp straight through yields material that appears to remain usable for millennia, which is a defect rather than a convenience.
- Both halves of this page work on material you supply, so treat what you paste with the same care you would give a password: rotate anything real that has been through a clipboard.
Frequently asked questions
Does anything I paste or type leave this page?
It does not. Parsing, the keyed check and the signing step all run through your own browser’s cryptography interface, and no request carries any of it anywhere. Neither the material nor your key is retained after you close the tab.
Why merge encoding and decoding into one page?
Because the work alternates between them. You read something, adjust a claim, rebuild it and read the result — a loop that two separate pages interrupt with navigation and repeated pasting. Sharing one key across the switch removes the remaining friction.
Which algorithms can this check and produce?
The full JWA signature set: HS256, HS384 and HS512 on a shared secret; RS256, RS384 and RS512; the PSS variants PS256, PS384 and PS512; ES256, ES384 and ES512 on the P-256, P-384 and P-521 curves; and Ed25519, which many libraries still label EdDSA — both names are offered. Only the unsecured "none" is absent, since there is nothing there to check. Everything but the HS family wants a PKCS#8 PEM block or a JWK: the private key to sign, and to check either the public key, a certificate, or that same private key, from which only the public half is taken. Should openssl have handed you a PKCS#1 or SEC1 block instead, the page names the one-line conversion.
Do I need the key to read a token?
No, and that is the property people find most surprising. Everything except the trailing segment is merely encoded for safe transport, so any recipient can extract the full claim set. A key becomes necessary only to establish that the material is genuine.
What should I conclude when the keyed check fails?
Either the claims were altered after issue, or you are checking against the wrong key. Experience says the second is far more likely — a staging key applied to production material, or a rotation nobody propagated.
My token checks out but my API still says no. Why?
Look at the time-bounded claims first, then at the intended recipient and the issuer. Material can be entirely genuine while being expired, not yet usable, or minted for a completely different service than the one refusing it.
Related Developers tools
All developer tools- Base64 Encode / Decode Encode and decode Base64 for text and files, with URL-safe support.
- Encrypt / Decrypt Text Encrypt and decrypt text with a passphrase (AES-GCM/CBC) or an RSA public key — output as Base64.
- Hash Generator Compute MD5, SHA-1, SHA-256, and SHA-512 digests, or Argon2 password hashes with a pepper.
- JSON Formatter Pretty-print, minify, and validate JSON with precise error positions and a tree view.
- UUID Generator Generate one or thousands of v4 UUIDs and copy them all at once.
- URL Encoder / Decoder Percent-encode or decode URLs and query-string components.