ToolBoxOnline
Developer

How to Verify a JWT Signature: HS256, RS256, and Why "Signed" Doesn't Mean Safe

A signed JWT can still be forged if you verify it the wrong way. Here's how to check a token's signature — HS256 vs RS256, the algorithm-swap attack, and the verification steps.

JWT signatureHS256RS256JWT verificationtoken security

You open a request log and find the token that broke your API. It's a JWT — three parts separated by dots, the middle one a blob of characters. You paste it into a JWT decoder and see the payload: a user ID, a role, an expiry. The header says the token was signed with HS256. "Signed" sounds safe. Then someone reminds you that signing alone proves nothing if you verify with the wrong key.

What the Signature Actually Does

A JWT's third segment is a signature computed over the header and payload. Anyone can read all three parts — that's the point of the format, and why decoding a token is not a security review. The signature exists so a server can confirm the token wasn't altered after it was issued. Verification is a check: recompute the signature with the secret key and see if it matches. If it does, the token came from someone who knows the key. If it doesn't, reject it. The hash generator shows the same idea with ordinary checksums: a string that changes whenever the input changes.

HS256 vs RS256: Why the Choice Matters

HS256 signs with a single shared secret — one key that both signs and verifies. RS256 uses a key pair: a private key signs, a public key verifies. The counter-intuitive part: "signed" tokens fail not because the math is weak but because of how the algorithm is chosen. If the server trusts whatever algorithm the token header claims, an attacker can send a token with header {"alg":"none"} or downgrade RS256 to HS256 and sign it with the public key — which is, by design, public. The fix is a server that pins the algorithm instead of trusting the header.

The Verification Workflow

When you inspect an unfamiliar JWT, decode all three parts first and check the header's alg against what the issuing service actually uses. Then verify the signature with the right key, confirm the expiry hasn't passed, and check the issuer and audience claims — an expired-but-signed token is still an expired token. The base64 converter helps when you want to look at the raw encoded segments side by side. Signature checks stop forged tokens; claim checks stop tokens that were once valid and should no longer be.

A signed JWT is a claim that hasn't been tampered with, not a promise that it's trustworthy. We covered expiration and security claims in our guide to reading JWT expiration. Decode it, pin the algorithm, verify with the right key — and the token you trusted becomes a token you checked.

Tools mentioned in this article

Compartir esta herramienta