JWT Decoder
Decode JSON Web Tokens (JWT) and verify signatures in your browser using the Web Crypto API. Nothing is sent to a server.
Runs entirely in your browser. Nothing is sent to our servers.
About this tool
A JSON Web Token (JWT) packs a JSON header, a JSON payload, and a signature into three Base64URL-encoded chunks separated by dots. This tool decodes the header and payload in your browser, and (optionally) verifies the signature using the Web Crypto API. The token, secret, and key never leave your device.
Anatomy of a JWT
header.payload.signature
Each part is Base64URL-encoded (no padding, -/_
instead of +//). The header declares the
alg (signing algorithm) and typ. The payload holds
claims like sub (subject), iss (issuer),
exp (expiry), and your application-specific data.
Verification — what to paste in the secret box
- HS256, HS384, HS512: paste the shared HMAC secret as plain text exactly as the issuer uses it.
- RS256, RS384, RS512, PS256, etc.: paste the RSA
public key in PEM format (begins with
-----BEGIN PUBLIC KEY-----). - ES256, ES384: paste the EC public key in PEM format.
Never paste a private key into a browser tool to test signing — there's no legitimate reason to. To verify a JWT issued by a third party, fetch their JWKS endpoint and use the corresponding public key.
Important: decoding ≠ verifying
A JWT's payload can be decoded by anyone, even without the secret. Decoding proves nothing about authenticity. If your application makes decisions based on a JWT, you must verify the signature on the server side using your trusted key. This tool's verification feature is for debugging your auth flow, not as a production verification step.
Frequently asked questions
- Which algorithms can this tool verify?
- HS256/384/512 (HMAC), RS256/384/512 (RSA-SHA), PS256/384/512 (RSA-PSS), ES256/384 (ECDSA). All are handled via the Web Crypto API. The
nonealgorithm is explicitly never accepted. - Why does my JWT show as "expired" but my server still accepts it?
- The expiry check uses your computer's clock. Clock drift between client and server can cause apparent expiry differences. Servers usually allow some leeway (typically 30-60 seconds) for this exact reason.
- Can I edit the payload and re-sign?
- Not in this tool, by design. Re-signing requires a private key, and we don't want to encourage pasting private keys into a browser tool. To edit and re-sign, use a server-side library like
jsonwebtoken(Node) orfirebase/php-jwt(PHP). - Is the JWT I paste here logged anywhere?
- No. All parsing and crypto operations happen in your browser tab. The tool has no server-side endpoint that sees the token.
Last updated: May 17, 2026