HS256 vs RS256: Which JWT Signing Algorithm Should You Use?

Both algorithms produce signed JWTs, but they work differently and are suited to different architectures. Choosing the wrong one can leave you with a security gap or unnecessary complexity.

How HS256 works

HS256 (HMAC-SHA256) is symmetric: the same secret is used to both sign and verify tokens.

sign(header + "." + payload, secret) → signature
verify(header + "." + payload, signature, secret) → valid/invalid

Every service that needs to verify a token must hold the same secret. If you have one backend that issues tokens and one that verifies them — and they're the same service — HS256 is simple and fast.

Use HS256 when: a single server (or a tightly controlled group sharing a secret) both issues and verifies JWTs.

How RS256 works

RS256 (RSA-SHA256) is asymmetric: the private key signs, the public key verifies.

sign(header + "." + payload, privateKey) → signature
verify(header + "." + payload, signature, publicKey) → valid/invalid

The issuer holds the private key and never shares it. Any consumer — microservice, third-party API, mobile app — can verify the signature using the public key, without ever being able to create tokens.

Use RS256 when: you have multiple services verifying tokens, or when you need consumers to verify without having signing capability.

Side-by-side comparison

HS256RS256
AlgorithmHMAC-SHA256RSA-SHA256
Key typeShared secretPrivate/public key pair
Who can signAnyone with the secretOnly the private key holder
Who can verifyAnyone with the secretAnyone with the public key
Key rotationHarder (all parties must update)Easier (rotate private key, publish new public key)
PerformanceFasterSlower (RSA math)
Best forSingle-service or internal systemsMulti-service, third-party, or OAuth flows

The security implication

With HS256, a compromised secret means an attacker can forge tokens. With RS256, a leaked public key is harmless — only the private key can forge.

If any consumer of your tokens is outside your direct control (a third-party integration, a mobile SDK you distribute), RS256 is the safer default.

How to verify which algorithm a token uses

The alg claim is in the JWT header. Decode the header (the first Base64 segment) to check:

{
  "alg": "RS256",
  "typ": "JWT"
}

Paste any JWT into the JWT validator to inspect the header and verify the signature against either a secret or a public key.

For background on what JWTs contain, see what are JWT claims or how to decode a JWT.

Got a config file to check?

Open the config toolkit →