JWT Decoder, Verifier and Encoder
Paste a token to read its header, payload and expiry and to verify its signature, or create a signed test token.
Runs in your browser. Your input is not sent anywhere.
What this tool does
A JSON Web Token (JWT) is a compact way to hand a set of statements, called claims, from one party to another. The usual form is a signed token: three pieces of text joined by dots.
In “Decode and verify” mode the tool decodes the first two pieces, shows them as formatted JSON, lists the time claims as dates and tells you whether the token has expired by the clock of your device. Decoding needs no key, because the header and the payload of a signed token are not encrypted; for the same reason a decoded token proves nothing until its signature is verified.
To verify, enter the key that fits the alg header: the shared secret for HS256, HS384 and HS512, or the public key for RS256, PS256, ES256, EdDSA and their variants. A public key can be a PEM block (PUBLIC KEY or RSA PUBLIC KEY), a certificate, a single JSON Web Key or a whole JWK Set such as the one a provider publishes at its jwks_uri; in a set the token’s kid picks the key.
In “Create a signed token” mode you write the payload, choose the algorithm and sign with a secret or a private key, for example to test your own API. The tool can generate a test key pair for you and shows the public key as PEM and as a JWK with its thumbprint as kid.
Verification and signing run in your browser with the Web Crypto API. Neither the token nor any key is sent, and keys are never saved. This page shows no ads, so no third-party script runs next to your keys.
How to use it
- Paste the token. A whole “Bearer …” value works; the word “Bearer” is ignored.
- Read the header, the payload and the line about the expiry.
- To verify, paste the secret or the public key into the key field. For a secret written as Base64 or Base64URL, such as the k value of a JWK, choose that format.
- To create a token, switch the mode, choose the algorithm, enter the payload as JSON and a secret or private key, or select “Generate a test key pair”.
- Copy the decoded JSON or the new token.
A token and its keys are credentials. Clear the fields when you are done if other people can see your screen, and use test keys when you create tokens: a production signing key does not belong in any web page.
How the result is derived
The text is split at the dots. A signed token has exactly three parts. Each of the first two is decoded from Base64URL to bytes, the bytes are read as UTF-8 text, and the text is parsed as JSON. Each step can fail, and the tool says which part failed and where.
The claims exp, nbf and iat hold a NumericDate: seconds since 1970-01-01T00:00:00Z, ignoring leap seconds. The token is expired when the current time is equal to or later than exp, and not yet valid before nbf. The current time is the clock of your device; a server may allow a few minutes for clock differences.
The signature covers the header and payload exactly as written in the token, joined by a dot (RFC 7515). Only the algorithm named in the header is used, and the key must fit it: an RSA key for RS and PS, the right curve for ES, an Ed25519 key for EdDSA. The tool refuses a public key for an HS token, because treating a public key as an HMAC secret is the classic “algorithm confusion” attack, and it refuses a private key for verification, which needs only the public one.
| alg | Signature | Key |
|---|---|---|
| HS256, HS384, HS512 | HMAC with SHA-2 | Shared secret, at least as long as the hash (32, 48, 64 bytes) |
| RS256, RS384, RS512 | RSASSA-PKCS1-v1_5 with SHA-2 | RSA, at least 2048 bits |
| PS256, PS384, PS512 | RSASSA-PSS, salt as long as the hash | RSA, at least 2048 bits |
| ES256, ES384, ES512 | ECDSA; r and s side by side, 64, 96 or 132 bytes | EC on P-256, P-384 or P-521 |
| EdDSA, Ed25519 | Ed25519 | OKP key with crv Ed25519 |
Web Crypto has no ES256K (secp256k1) and, in most browsers, no Ed448, so tokens with those algorithms are decoded but not verified. A generated key pair gets its RFC 7638 thumbprint as kid, the SHA-256 of the key’s required members in a fixed order.
Worked example
This is the example token of RFC 7519. Line breaks were added after the dots to make it fit; a real token is one line.
eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.
eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.
dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk{
"typ": "JWT",
"alg": "HS256"
}
{
"iss": "joe",
"exp": 1300819380,
"http://example.com/is_root": true
}The claim exp is 1300819380, which is 2011-03-22T18:43:00Z, so the token expired long ago. The signature has 32 bytes, the length of an HMAC with SHA-256, which matches the algorithm HS256 named in the header.
RFC 7515 publishes the key of this example as a JSON Web Key. Enter its k value with the format “Base64 or Base64URL”, and the tool reports the signature as verified; change one character of the key and it reports an invalid signature.
AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAowRFC 7515, appendix A.2, signs the same payload with RS256 and publishes the RSA key as a JWK. Paste that token, and paste the JWK with only its public members kty, n and e: the tool reports the signature as verified with RS256. Paste the full JWK with its private members d, p and q instead, and the tool refuses it, because verification needs only the public key.
{"alg":"RS256"}Reference: the structure of a token
| Part | Content | Encoding |
|---|---|---|
| Header | JSON object that names the algorithm (alg) and often the type (typ) and a key identifier (kid). | Base64URL without padding |
| Payload | JSON object with the claims. | Base64URL without padding |
| Signature | Signature or message authentication code over the first two parts as they are written in the token. | Base64URL without padding |
| Claim | Name | Meaning |
|---|---|---|
| iss | Issuer | Who created the token. |
| sub | Subject | Whom the token is about. |
| aud | Audience | For whom the token is intended. |
| exp | Expiration time | The token must not be accepted on or after this time. |
| nbf | Not before | The token must not be accepted before this time. |
| iat | Issued at | When the token was created. |
| jti | JWT ID | A unique identifier of the token. |
All of these claims are optional in the standard. Which ones are required is decided by the application that uses the tokens.
A text with five parts is an encrypted token (JWE). Its content cannot be read without the key, and this tool does not decode it.
Common mistakes
- Trusting a decoded token. Without verifying the signature, the content may have been written by anyone.
- Letting the token choose the algorithm. A server must accept only the algorithms it expects; the alg header is written by whoever made the token.
- Putting secrets into the payload. It is readable by everyone who gets the token.
- Reading exp as milliseconds. The time claims are in seconds; a value in milliseconds lies tens of thousands of years in the future.
- Accepting the algorithm “none”. Such a token has no signature. The tool marks it clearly.
- Decoding the parts with a decoder for standard Base64. Tokens use the URL-safe alphabet without padding.
- Encoding an ES256 signature as DER, the format of OpenSSL and many libraries. A JWT needs r and s side by side (RFC 7518, section 3.4); the tool names this mistake when it sees it.
- Verifying with the wrong key from a JWK Set. Match the token’s kid; providers rotate keys, and a cached set may lack the new one.
Sources
Frequently asked questions
- Is it safe to paste a real token or key here?
- The tool decodes, verifies and signs in the page and sends nothing; this page loads no ads or other third-party scripts. Keys are never stored. The token is stored only if you turn on “Remember my input on this device”, which keeps it unencrypted in your browser. Whether you may paste production credentials into any web page is a question for the rules of your organization.
- How do I verify an RS256 token with a public key or JWKS?
- Paste the token, then paste the public key into the key field: a PEM PUBLIC KEY block, the certificate, a single JWK or the whole JWK Set from the provider’s jwks_uri. With a set, the key whose kid matches the token is used. The result says whether the signature verifies and which kid was used.
- Can I create a JWT for testing?
- Yes. Choose “Create a signed token”, write the payload as JSON, pick the algorithm and enter a secret, or generate a test key pair for RS, PS, ES or EdDSA. The token is signed in your browser. Give the public key to the service under test; keep production signing keys out of web pages.
- Can I change the payload and use the token?
- You can change the text, but the signature will no longer match, and a server that verifies signatures will reject the token.
- The tool says the token is expired, but my server accepts it. Why?
- The tool compares the claim exp with the clock of your device. If that clock is wrong, the result is wrong. Servers may also accept a token for a short time after its expiry to allow for differences between clocks.
- What are claims that look like a URL?
- Names such as http://example.com/is_root are claims defined by an application. Writing them as a URL of a domain the application controls avoids conflicts with the names of other applications.
Last updated: September 29, 2026