💻 Coding

JWT Encoder/Decoder

Decode a JSON Web Token to inspect its header and payload, verify an HS256 signature, or encode your own token, all client-side.

About the JWT Encoder/Decoder

A JWT is really just a base64url-encoded header and payload, dot-separated, with a signature computed over both. Paste one in and it decodes locally so you can inspect the claims, and if you supply the secret it'll verify or generate an HS256 signature too, all without a network request.

A critical distinction: JWTs are encoded, not encrypted

This is worth stating plainly because it's a genuinely common misconception: the header and payload of a JWT are just base64url-encoded JSON, readable by anyone who copies the token, with no secret or key required at all. That's exactly why decoding works instantly the moment you paste a token in here, no secret needed. The secret only comes into play for the signature, which exists purely to prove the token wasn't tampered with after it was issued, integrity, not confidentiality. Never put sensitive information you wouldn't want exposed directly in a JWT's payload, anyone who intercepts the token, whether or not they know the signing secret, can read every claim inside it.

Why base64url instead of standard base64

Standard base64 uses +, /, and trailing = padding characters, all of which have special meaning inside URLs and HTTP headers, + can be interpreted as a space, / looks like a path separator, and = often marks query-string boundaries. Since JWTs are routinely passed in URLs, cookies, and Authorization headers, standard base64 would require additional escaping to travel safely through those contexts. Base64url swaps + for -, / for _, and drops the padding entirely, producing an encoding that's safe to use directly in a URL or header with no further escaping needed.

Why this tool uses the browser's native Web Crypto API instead of hand-rolled HMAC

Unlike some of this site's other tools that implement their own parsers and tokenizers from scratch, HMAC-SHA256 signing and verification here go through crypto.subtle, the browser's built-in, standardized cryptographic API, rather than a JavaScript reimplementation of the HMAC algorithm. That's a deliberate choice: cryptographic primitives are notoriously easy to get subtly wrong by hand, timing differences, incorrect padding, off-by-one errors in the hashing rounds, in ways that can silently weaken the security guarantee without being obviously broken. Using the browser's own audited, native implementation means the actual cryptographic math is handled by code that's been reviewed and tested far more rigorously than a one-off hand-written version could be.

Why only HS256 is supported for signature verification

The Verify Signature panel only appears when the decoded header's alg field is HS256, because HS256 (HMAC with SHA-256) is a symmetric algorithm, the same shared secret is used to both create and verify the signature. Algorithms like RS256 or ES256 are asymmetric instead, signed with a private key and verified with a mathematically related but different public key, typically supplied as a certificate rather than a plain text secret. Supporting those would need an entirely different input (a public key, not a shared secret) and a different Web Crypto API call shape, which is why this tool focuses specifically on the HS256 case most commonly seen in smaller applications and API tokens.

A practical caution worth repeating even for a local-only tool

Everything here runs entirely client-side with no network request, which is true and worth trusting for this specific tool. Even so, it's good general practice never to paste a real, live production JWT or its actual signing secret into any web-based tool, including this one, when testing or debugging. Use example tokens and placeholder secrets for experimentation, and if you need to inspect a genuine production token, prefer decoding it in a local script or your own trusted tooling instead, simply as a matter of good security hygiene rather than any specific concern about this particular page.

Frequently Asked Questions

Can I decode a JWT without knowing the signing secret?

Yes, the header and payload are just base64url-encoded JSON, not encrypted, so anyone can read them without any secret. The secret is only needed to create or verify the signature, which proves the token wasn't tampered with, it doesn't hide the payload's contents.

Why does a JWT use base64url instead of regular base64?

Standard base64 uses characters (+, /, =) that have special meaning in URLs and headers. Since JWTs are commonly passed in URLs, cookies, and Authorization headers, base64url substitutes URL-safe characters and drops padding, so the token travels safely without needing extra escaping.

Why does this tool use the Web Crypto API instead of a custom HMAC implementation?

Cryptographic algorithms are easy to get subtly wrong when hand-implemented, in ways that can silently weaken security without being obviously broken. Using the browser's native, audited crypto.subtle API means the actual signing math runs through code that's been far more rigorously reviewed than a one-off implementation would be.

Why can't I verify an RS256 or ES256 token here?

Those are asymmetric algorithms, signed with a private key and verified with a separate public key, typically supplied as a certificate. HS256 uses one shared secret for both signing and verifying, a fundamentally different flow, which is why this tool's verification panel is scoped to HS256 specifically.

Is it safe to paste a real production JWT into this tool?

Technically yes, since everything runs client-side with no network request. But as general security hygiene, it's still best to avoid pasting real production tokens or secrets into any web-based tool during testing, use example tokens and placeholder secrets instead.

Should I put sensitive information in a JWT's payload?

No, since the payload is readable by anyone who has the token, regardless of whether they know the signing secret. JWTs provide integrity (proof the token hasn't been altered), not confidentiality, so sensitive data shouldn't be placed directly in the claims.