Verify a JWT signature

Paste a token and the key that should have signed it. Verification uses exactly the algorithm in the token header and a key of the matching type — HMAC secrets, PEM public keys, X.509 certificates, JWKs and JWK Sets (matched by kid).

🔒 Tokens, secrets and keys never leave your browser.
🔒 Decoded locally — never sent anywhere.0 chars

What verification proves — and what it doesn't

A valid signature proves that the header and payload were produced by someone holding the signing key and have not been modified since. It does not prove the token is still valid for your API. After the signature check you must still validate the claims: exp (not expired), nbf (already active), iss (the issuer you trust) and aud (intended for you). That is why this tool reports the signature and the claims separately — a token can be signature verified ✓ and expired ✕ at the same time.

Which key do I need?

Token algVerify withAccepted formats
HS256 / HS384 / HS512The same shared secret the issuer signed withText (UTF-8), Base64, Base64URL, hex
RS256 / RS384 / RS512The issuer's RSA public keyPEM (SPKI or PKCS#1), X.509 certificate, JWK, JWKS
PS256 / PS384 / PS512The issuer's RSA public keySame as RS*
ES256 / ES384 / ES512The issuer's EC public key on P-256 / P-384 / P-521PEM, certificate, JWK, JWKS

For identity providers (Auth0, Okta, Keycloak, Cognito, Entra ID, Firebase and others) the public keys are published as a JWKS, usually linked from the issuer's /.well-known/openid-configuration as jwks_uri. Paste the JWKS and the key whose kid matches the token header is selected automatically — or use Load a JWKS from a URL, which fetches only the key set, never your token.

Why verification fails

Verify in code — pin the algorithm

Never let the token choose its own algorithm. Every mainstream library lets you pass the list of allowed algorithms:

// Node.js / browsers — jose
const { payload } = await jwtVerify(token, publicKey, {
  algorithms: ["RS256"],
  issuer: "https://auth.example.com/",
  audience: "api.example.com",
});

# Python — PyJWT
claims = jwt.decode(token, public_key, algorithms=["RS256"],
                    issuer="https://auth.example.com/", audience="api.example.com")

The decoder generates ready-to-run snippets for JavaScript, TypeScript, Python, Java, Go, C# and PHP from any token you paste. For the full checklist read How to verify a JWT correctly.