navaja.dev / jwt

JWT decoder and verifier

Paste a JSON Web Token to read its header and claims, see when it expires, and check its signature with a secret or public key. You can also create and sign tokens. Your tokens never leave this browser.

Header

            
Payload

          

How to decode a JWT

  1. Paste the token into the box. It decodes as you paste; a Bearer prefix or quotes are removed for you.
  2. Read the header and payload. Times like exp, iat and nbf are shown as dates, with a warning if the token has expired or isn't valid yet.
  3. Verify the signature by pasting the secret (for HS256) or the public key (for RS256, ES256 and others) as PEM, JWK or a JWKS. You see right away whether the signature matches.

What is a JWT?

A JSON Web Token (RFC 7519) is three Base64url parts joined by dots: a header that names the algorithm, a payload of claims (who the user is, when the token expires) and a signature. Anyone can read the header and payload, because they are only encoded, not encrypted. The signature proves the token came from someone with the key and wasn't changed. So never put secrets in a JWT payload, and always verify the signature on the server before trusting a claim.

Supported algorithms and keys

Keys can be PEM (-----BEGIN PUBLIC KEY-----), a JWK, or a whole JWKS like the one at an identity provider's /.well-known/jwks.json; the key is picked by the token's kid. Verification uses your browser's built-in WebCrypto.

Security checks

Besides the signature, navaja jwt flags the mistakes behind real-world JWT bugs: tokens with alg: none, tokens with no exp (they never expire), expiry times in milliseconds instead of seconds, very long lifetimes, HMAC secrets shorter than the hash (easy to brute-force), and headers like jku, x5u or an embedded jwk that a careless server might use to fetch or trust the attacker's key. It also refuses the algorithm-confusion trick: a token that claims HS256 can't be "verified" with an RSA or EC public key used as the secret.

Create a JWT

Switch to Create to build a token for testing: edit the header and payload, set iat and exp in one click, pick an algorithm, and sign with your own key or one generated in the browser. Open in decoder checks it straight away.

Questions

Is it safe to paste my JWT here?

Yes. Decoding and verifying happen entirely in your browser with JavaScript and WebCrypto. The token and keys are never sent to a server, logged or stored. Still, treat production tokens like passwords and prefer short-lived ones.

Can anyone read the contents of a JWT?

Yes. The header and payload are only Base64url-encoded, not encrypted. Anyone who has the token can read them. Only encrypted tokens (JWE, five parts) hide the payload.

What do exp, iat and nbf mean?

They are times in seconds since 1 January 1970 (UTC). exp is when the token expires, iat is when it was issued, and nbf is the time before which it must not be accepted. navaja jwt shows each as a date and how long ago or from now it is.

Why does verification fail?

The most common reasons are the wrong key (a different secret, or the private key instead of the public key), a secret that is really Base64 (tick Secret is Base64-encoded), a token that was changed, or an algorithm mismatch between the token and the key.

What is the difference between HS256 and RS256?

HS256 uses one shared secret to sign and verify, so every verifier can also create tokens. RS256 signs with a private key and verifies with a public key, so services can check tokens without being able to forge them.

What is alg none?

An unsigned token. Libraries that accept alg none let anyone forge tokens, so servers must always reject it and require the algorithm they expect.

Can I verify with a JWKS URL?

Paste the JSON from the JWKS URL (for example https://your-issuer/.well-known/jwks.json). The key with the token's kid is used. The tool doesn't fetch URLs itself.

How do I convert an RSA PUBLIC KEY or certificate?

WebCrypto needs the SubjectPublicKeyInfo format (BEGIN PUBLIC KEY). Convert with openssl rsa -RSAPublicKey_in -in key.pem -pubout, or get it from a certificate with openssl x509 -pubkey -noout -in cert.pem.