JWT Encoder/Decoder
Decode JWT header and payload, verify signatures locally.
HS256/384/512 supported · RS/ES require a public key (roadmap)
JWT
{
"alg": "HS256",
"typ": "JWT"
}{
"sub": "1234",
"name": "Ada Lovelace",
"iat": 1710000000,
"exp": 2000000000
}- Issued at (iat)
- 2024-03-09T16:00:00.000Z
- Expires (exp)
- 2033-05-18T03:33:20.000Z
Qb3q14k7VFAJx6hLzO0i5e4Gss_e2JZBVXrdFSW8_3sWhat is a JWT Encoder / Decoder?
A JSON Web Token (JWT) is a compact, URL-safe way to transport a set of signed claims between two parties. Authentication systems emit them to prove a user is logged in; authorisation services use them to carry permissions; API gateways use them to relay a user identity downstream. Every JWT has three parts separated by dots: a header that names the signing algorithm, a payload that holds the claims, and a signature that binds the first two together under a secret or private key. Tampering with the header or payload after signing invalidates the signature, so the recipient can trust the claims without re-contacting the issuer.
The wire format is three Base64URL-encoded segments joined by dots. Base64URL (the URL-safe variant of Base64, swapping +/ for -_ and stripping padding) means the token can travel in HTTP headers, query strings, and cookies without further escaping. That compactness matters: Authorization: Bearer eyJ… is the canonical HTTP pattern, and your application sees that header on every request.
Decoding is trivial — anyone with the token can read the header and payload with no secret. JWT is signed, not encrypted. Treat the payload as public; never put passwords, API keys, or PII there unless you're also using JWE (JSON Web Encryption, a separate spec). Sensitive claims should live in a server-side session with the JWT carrying only a session ID. The signature is what makes the claims trustworthy, not secret.
Our tool runs in two modes. Decode splits any JWT into its three parts, pretty-prints the JSON, surfaces the standard time claims (iat issued-at, nbf not-before, exp expiry) as human-readable ISO dates, and flags an expired token with a red label. Paste an HMAC secret and we verify the signature in the browser via the jose library. Encode takes a header and payload as JSON and signs a token with an HMAC secret — useful for quick test tokens during development.
Signature algorithms fall into three families. HS* (HS256, HS384, HS512) use HMAC with a shared secret — fast, simple, everyone who can verify can also sign. Use for internal service-to-service tokens. RS* (RS256…) use RSA with an asymmetric key pair; the private key signs, the public key verifies. Use when issuers and verifiers are different services. ES* (ES256…) use elliptic-curve signatures; similar properties to RS but with smaller keys and faster verification. Our tool currently supports the HS family — RS and ES require public-key parsing and are on the roadmap.
Security gotchas. Accept only the algorithms your system needs, and never accept alg: none — a famous early JWT bug. Rotate secrets; use at least 32 bytes of random data for HS256. Set an exp on every token and keep expiries short (minutes, not days) — use refresh tokens for longer sessions. Finally, do not roll your own JWT library in production; stick with battle-tested implementations (jose, jsonwebtoken, pyjwt, jjwt).
Privacy: token and secret stay in your browser. That matters because a real JWT often carries enough data (user ID, email, internal roles) that pasting it into an unknown tool is a potential leak risk. This decoder runs locally.
How to use the JWT Encoder / Decoder
- Pick decode or encode. Tabs at the top flip the mode.
- In decode mode, paste a token. The header, payload, and signature appear on the right with time claims already converted to readable dates.
- Paste the HMAC secret to verify the signature; a green or red badge tells you if it checks out.
- In encode mode, edit the header and payload as JSON, then click Sign.
- Copy the decoded parts or the signed token; every panel has its own copy button.
Features
- Decode any JWT — header, payload, and signature shown separately.
- Auto-converts
iat,nbf,expto ISO dates and flags expiry. - Live signature verification for HS256 / HS384 / HS512.
- Sign new tokens with any HMAC secret — great for local testing.
- Runs in your browser — no token or secret leaves your device.
Frequently asked questions
- Is a JWT encrypted?
- No. A JWT is signed, which means its authenticity is verifiable, but the header and payload are Base64URL-encoded in plain sight. Anyone can read them. For encrypted tokens, use JWE (a separate spec). Do not put passwords, API keys, or sensitive PII in a JWT payload.
- What does 'Signature invalid' mean?
- Either the secret is wrong, the token was tampered with, or the algorithm mismatch — our verifier supports only HS256/384/512. Confirm your secret exactly matches the issuer's and that the header's 'alg' matches the secret type.
- Why is my RS256 token not verifying?
- RS256 uses asymmetric keys (private to sign, public to verify). Our tool currently supports only HS* (HMAC-based). Add public-key verification is on the roadmap; in the meantime, use jwt.io or your backend's JWT library for RS/ES verification.
- What are iat, nbf, and exp?
- Registered JWT claims for time. iat (issued-at) is when the token was created; nbf (not-before) is the earliest moment it's valid; exp (expiry) is when it stops being valid. All are Unix epoch seconds. Our decoder converts each to a readable ISO date and flags an expired token in red.
- Can I send tokens I decode to a server?
- Not through this tool. Decoding happens entirely in your browser; we never see the token or the secret. If you need a server-side JWT verifier, use your backend language's JWT library (jsonwebtoken, pyjwt, jose).
- What's the 'alg: none' vulnerability?
- Early JWT implementations accepted tokens with 'alg: none' as valid without verifying anything. Many were exploited before libraries fixed the default. Modern libraries reject 'none' by default; always configure accepted algorithms explicitly in your verifier.