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
| HS256 | RS256 | |
|---|---|---|
| Algorithm | HMAC-SHA256 | RSA-SHA256 |
| Key type | Shared secret | Private/public key pair |
| Who can sign | Anyone with the secret | Only the private key holder |
| Who can verify | Anyone with the secret | Anyone with the public key |
| Key rotation | Harder (all parties must update) | Easier (rotate private key, publish new public key) |
| Performance | Faster | Slower (RSA math) |
| Best for | Single-service or internal systems | Multi-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 →