How to Verify a JWT Signature

Anyone can decode a JWT, but only verification proves it's genuine and untampered. Here's how it works.

What verification checks

A complete validation confirms three things:

  1. Signature — the token was signed with the right key and hasn't been altered.
  2. Expiry (exp) — the token hasn't expired.
  3. Not-before (nbf) and issuer (iss) — optional standard claims, if present.

How signature verification works

The signature is computed over header.payload. To verify, you recompute it with the key and compare.

  • HS256 (symmetric) — the same secret signs and verifies. Recompute the HMAC and check it matches.
  • RS256 (asymmetric) — a private key signs, a public key verifies. Servers can share the public key freely.

HS256 verification in JavaScript

Using the Web Crypto API:

const key = await crypto.subtle.importKey(
  'raw', new TextEncoder().encode(secret),
  { name: 'HMAC', hash: 'SHA-256' }, false, ['verify']
);
// recompute signature over `${header}.${payload}` and compare

Always check expiry

A valid signature on an expired token should still be rejected. Compare exp (a Unix timestamp — see what is a Unix timestamp) against the current time.

Verify online

The JWT validator checks the HS256/384/512 signature with your secret and reports expiry and not-before status with a clear pass/fail verdict — all locally in your browser.

Got a config file to check?

Open the config toolkit →