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.

Paste a token. A leading “Bearer” and surrounding spaces are ignored.

For HS algorithms the shared secret; for RS, PS, ES and EdDSA a PEM public key, a certificate, a JWK or a JWK Set. Leave empty to decode only. Keys are used in this page and never saved.

Off by default. When on, the fields of this tool are kept in the local storage of this browser, unencrypted, until you turn it off.

No token yet

Your result will appear here.

Keyboard shortcuts

Ctrl + Enter, ⌘ + Enter
Run the tool with the current input
Alt + Shift + C
Copy the result
Alt + Shift + X
Clear all fields

Shortcuts work while the focus is inside the tool. Every action is also available as a button.

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

  1. Paste the token. A whole “Bearer …” value works; the word “Bearer” is ignored.
  2. Read the header, the payload and the line about the expiry.
  3. 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.
  4. 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”.
  5. 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.

Algorithms and the keys they need (RFC 7518, RFC 8037, RFC 9864)
algSignatureKey
HS256, HS384, HS512HMAC with SHA-2Shared secret, at least as long as the hash (32, 48, 64 bytes)
RS256, RS384, RS512RSASSA-PKCS1-v1_5 with SHA-2RSA, at least 2048 bits
PS256, PS384, PS512RSASSA-PSS, salt as long as the hashRSA, at least 2048 bits
ES256, ES384, ES512ECDSA; r and s side by side, 64, 96 or 132 bytesEC on P-256, P-384 or P-521
EdDSA, Ed25519Ed25519OKP 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.

Token from RFC 7519, section 3.1
eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.
eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.
dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
Decoded header and payload
{
  "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.

HMAC key from RFC 7515, appendix A.1 (k value)
AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow

RFC 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.

Header of the RFC 7515 A.2 token
{"alg":"RS256"}

Reference: the structure of a token

Parts of a signed token (JWS compact serialization)
PartContentEncoding
HeaderJSON object that names the algorithm (alg) and often the type (typ) and a key identifier (kid).Base64URL without padding
PayloadJSON object with the claims.Base64URL without padding
SignatureSignature or message authentication code over the first two parts as they are written in the token.Base64URL without padding
Registered claim names of RFC 7519
ClaimNameMeaning
issIssuerWho created the token.
subSubjectWhom the token is about.
audAudienceFor whom the token is intended.
expExpiration timeThe token must not be accepted on or after this time.
nbfNot beforeThe token must not be accepted before this time.
iatIssued atWhen the token was created.
jtiJWT IDA 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