Glossary

What Is a JWT Signature? (And How to Verify One)

A JWT signature cryptographically binds a token's header and payload so it can't be tampered with. Plain explanation of HMAC vs RSA signatures with verification code.

Short answer

A JWT (JSON Web Token) signature is a cryptographic tag at the end of the token that proves the token's header and payload weren't modified after the issuer signed them. It's computed by hashing header.payload with a secret (HMAC) or a private key (RSA/ECDSA). To verify, you recompute the signature with the matching secret/public key and compare. If it matches, the token is authentic; if not, it was forged or altered.

The structure

A JWT looks like this — three Base64URL-encoded blocks separated by dots:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0IiwibmFtZSI6IkFsaWNlIn0.K2N3...
└────── header ──────┘ └────── payload ──────┘ └ signature ┘

Decode any JWT with the JWT decoder. The first two parts decode to JSON; the third is the binary signature.

How the signature is computed

For HS256 (HMAC-SHA-256), the most common algorithm:

signature = HMAC_SHA256(
  base64url(header) + "." + base64url(payload),
  secret
)
token = base64url(header) + "." + base64url(payload) + "." + base64url(signature)

For RS256 (RSA + SHA-256), it's an asymmetric signature using the issuer's private key — verifiers use the matching public key to check.

Algorithm choices

AlgTypeVerifier needsUse when
HS256HMAC-SHA-256 (symmetric)The same secret used to signBoth sides are your own services
HS384 / HS512HMAC with bigger hashesSame secretHigher security; rarely needed
RS256RSA + SHA-256 (asymmetric)Public key onlyPublic-key verifiers (mobile apps, third-party services)
ES256ECDSA P-256 + SHA-256Public key onlySame as RS256 but smaller signatures
EdDSAEd25519 signaturesPublic key onlyModern preferred asymmetric option
noneNo signature(nothing)NEVER. This is a vulnerability.

Verifying a JWT (Node.js example)

import jwt from 'jsonwebtoken';

try {
  const decoded = jwt.verify(token, secret, {
    algorithms: ['HS256'],         // ← whitelist explicitly
    issuer: 'https://example.com',
    audience: 'my-app',
  });
  // decoded.sub, decoded.exp, etc.
} catch (err) {
  // Signature invalid, token expired, or claims didn't match
}

Critical: always pass algorithms as a whitelist. Without it, an attacker can swap alg in the header to none or HS256 (and use your public key as the secret), bypassing verification.

Common pitfalls

  • "alg: none" trick — old jsonwebtoken libraries accepted unsigned tokens. Always whitelist algorithms.
  • HS256 with RSA public key as secret — if a verifier accepts both HS256 and RS256 without checking, attacker can use your public key as the HMAC secret. Whitelist exactly one algorithm per use case.
  • Storing the secret/private key insecurely — anyone with the HS256 secret can mint tokens. Treat it as crown-jewel data.
  • Reusing keys across environments — dev/staging/prod should each have their own signing keys. A leak in dev shouldn't compromise prod.
  • Decoding ≠ verifyingJWT decoder reads the payload without checking the signature. Useful for inspection, but never trust unsigned data in your application.

What the signature does NOT do

  • Doesn't encrypt the payload. Anyone can decode the JWT and read the claims — never put secrets in there.
  • Doesn't prevent replay. If an attacker steals a valid JWT, they can reuse it until expiry. Use short exp + refresh tokens.
  • Doesn't prove who's using it. Possession of a valid token = authentication. If the token leaks, anyone can use it.

Related tools

Decode and inspect any JWT (signature is shown but not verified): JWT decoder. Manually compute HMAC signatures: hash generator. Base64URL is JWT's encoding flavor: Base64.

Featured Tools

Try these free tools directly in your browser — no sign-up required.

what is jwt signature jwt signing jwt verification hs256 vs rs256 jwt secret

Explore 300+ Free Tools

Utilko has tools for developers, writers, designers, students, and everyday users — all free, all browser-based.