Cryptography

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

9 min read
By
JWT HS256 vs RS256: Which Signing Algorithm Should You Use?

Photo by Pixabay from Pexels

When you sign a JSON Web Token, you have to choose a signing algorithm. The two most common choices are HS256 (HMAC with SHA-256) and RS256 (RSA signature with SHA-256). Both produce secure signatures. But they have fundamentally different key management models, and that difference has real consequences for your architecture.

Let's break down how each works and when to choose which.

How HS256 Works

HS256 is HMAC-SHA256 applied to a JWT. The header and payload are base64url-encoded, concatenated with a period, and then HMAC-SHA256 is computed over the result using a shared secret key.

The key property of HS256 is that the same key is used for both signing and verification. The auth server uses the key to sign tokens. Any service that needs to verify tokens also needs the same key. And anyone who has the key can sign valid tokens.

This is simple and fast. HMAC computation is cheap, and verification is just recomputing the HMAC and comparing. There is no key distribution infrastructure beyond sharing the secret with every service that needs to verify tokens.

The tradeoff is that every verifier is also a potential forger. If you have ten microservices and each one verifies JWTs, each one has the signing key. If any one of them is compromised, the attacker can forge tokens that all the other services will accept.

How RS256 Works

RS256 uses asymmetric cryptography. The auth server has a private RSA key that it uses to sign tokens. Each service that needs to verify tokens has the corresponding public key.

The key property of RS256 is that signing and verification use different keys. The private key signs. The public key verifies. Anyone with the public key can verify tokens, but no one can forge them without the private key.

This separates the ability to sign from the ability to verify. Your microservices can verify tokens without being able to create them. If a microservice is compromised, the attacker gets the public key, which is useless for forging tokens.

The tradeoff is complexity and performance. RSA signatures are much slower than HMAC. Signing with RS256 is roughly 100 times slower than signing with HS256, and verification is roughly 10 times slower. For most applications, this does not matter because JWT verification happens once per request and takes a few milliseconds. But for high-throughput systems, it can add up.

You also need to manage key pairs instead of shared secrets. The private key needs to be stored securely. The public key needs to be distributed to all verifying services. Many systems use a JWKS (JSON Web Key Set) endpoint where the public key is published and services fetch it periodically.

Key Management: The Core Difference

The choice between HS256 and RS256 is really about key management, not about cryptographic strength.

**With HS256**, every service that verifies tokens has the signing key. This means: - Key distribution: share the secret with every verifier, usually via environment variables or a secret manager. - Key rotation: generate a new secret, update all services, wait for old tokens to expire. - Compromise impact: if any verifier is breached, the attacker can forge tokens for all services. - Simplicity: one key, shared everywhere. No public/private key infrastructure needed.

**With RS256**, only the auth server has the private key. Verifiers have the public key. This means: - Key distribution: publish the public key (often via JWKS endpoint). Services fetch it or it is distributed via configuration. - Key rotation: generate a new key pair, publish the new public key, sign new tokens with the new private key. Services accept both keys during transition. - Compromise impact: if a verifier is breached, the attacker gets the public key, which cannot forge tokens. Only a compromise of the auth server (private key) is critical. - Complexity: key pair management, JWKS endpoints, potential key ID (kid) header handling.

When to Choose HS256

HS256 is the right choice when:

**You have a single verifier.** If only one service verifies tokens (for example, a monolithic backend), there is no benefit to separating signing and verification keys. The simplicity of a shared secret wins.

**You have a small number of trusted services.** If you have two or three services in a tightly controlled environment, and you trust all of them equally, HS256 is simpler and faster.

**Performance is critical.** If you are processing thousands of JWT verifications per second, the performance difference between HMAC and RSA can matter. HMAC is dramatically faster.

**You do not want to manage key pairs.** HS256 uses a single shared secret. No JWKS endpoints, no key rotation complexity, no public/private key infrastructure.

When to Choose RS256

RS256 is the right choice when:

**You have many verifiers.** In a microservices architecture with many services verifying tokens, RS256 limits the blast radius of a compromise. Each service only has the public key.

**You have untrusted verifiers.** If you are issuing tokens that third parties verify (for example, a SSO provider), you must use asymmetric signing. You cannot share the signing key with third parties.

**You want defense in depth.** Even if you have a small number of services, RS256 provides defense in depth. A compromise of one service does not allow token forgery.

**You need non-repudiation.** With RS256, the signature can only have been produced by the private key holder. This provides a stronger audit trail than HS256, where any verifier could have produced the signature.

What About ES256?

ES256 (ECDSA with the P-256 curve) is a third option that uses elliptic curve cryptography. It offers the same key separation as RS256 (private key signs, public key verifies) but with much smaller key sizes and faster signing. Verification is similar in speed to RS256.

ES256 is increasingly recommended over RS256 for new systems because of its smaller keys and signatures. However, RS256 is more widely supported and understood. If you are starting fresh and your libraries support ES256, it is worth considering. But the HS256 vs RS256 decision is the more fundamental architectural choice.

Security Pitfalls to Avoid

Regardless of which algorithm you choose, there are critical security practices:

**Never accept the "none" algorithm.** The JWT spec allows unsigned tokens with alg: "none". Attackers can craft a token with this algorithm and no signature. Your verification code must explicitly check that the algorithm matches what you expect.

**Always verify the algorithm field.** Do not let the token tell you which algorithm to use. Specify the expected algorithm in your verification code and reject tokens that use a different one. This prevents algorithm confusion attacks where an RS256 public key is misused as an HS256 secret.

**Store keys securely.** Whether it is a shared secret (HS256) or a private key (RS256), the key must be stored in a secure location. Environment variables, secret managers, or hardware security modules. Never commit keys to version control.

For a deeper understanding of HMAC, which underlies HS256, read our HMAC vs hash explained guide. And to compute HMACs yourself, try our HMAC generator.

The Bottom Line

For a monolithic app or a small trusted set of services, HS256 is simpler, faster, and perfectly secure. For a larger architecture with many services or third-party verifiers, RS256's key separation is worth the added complexity.

The decision is about your architecture, not about cryptography. Both algorithms are cryptographically secure. The question is: do you need to separate the ability to sign from the ability to verify? If yes, use RS256. If no, use HS256.

Frequently Asked Questions

What is the difference between HS256 and RS256 in JWT?

HS256 uses HMAC with a shared secret key. The same key is used to both sign and verify tokens. RS256 uses RSA with a private key for signing and a public key for verification. Anyone with the public key can verify tokens, but only the private key holder can sign them.

Is RS256 more secure than HS256?

Not necessarily. Both are secure when implemented correctly. RS256 has the advantage of separating signing and verification keys, which means a compromised verifier cannot forge tokens. HS256 is simpler and faster, but requires every verifier to have the signing key, which means every verifier can also forge tokens.

Can I switch from HS256 to RS256 without breaking existing tokens?

Yes, but you need to support both algorithms during the transition. Accept tokens signed with either algorithm, and sign new tokens with RS256. Once all old HS256 tokens have expired, stop accepting HS256. Never accept tokens with the "none" algorithm, and always verify the algorithm field matches what you expect.

Which JWT algorithm should I use for a microservices architecture?

RS256 is generally better for microservices. The auth service holds the private key and signs tokens. Each microservice only needs the public key to verify tokens, which means no service can forge tokens for another. With HS256, every service that verifies tokens also has the secret key and could forge tokens, which is a larger attack surface.

Try NovelCrypt Tools

Experience military-grade encryption for your sensitive data. Create self-destructing messages, encrypt files, or explore our experimental lab tools.

Explore NovelCrypt