HS256 vs RS256: Choosing a JWT Signing Algorithm
Against HS256 and RS256, the key model matters more than the headline algorithm. HS256 uses a single symmetric secret for both signing and verification: anyone who can verify tokens can also forge them.1 RS256 uses an asymmetric key pair: a private key signs, a public key verifies.1 Any service that only needs to verify tokens receives the public key without gaining the ability to issue new ones. The choice between them determines your trust boundaries and verification strategy.
Pasting a token into the decoder above reveals the alg claim in the header: the first step in diagnosing algorithm-related verification failures. ES256 (ECDSA) provides the same asymmetric benefit as RS256 with smaller key sizes and faster signature operations, making it the preferred choice for high-throughput APIs. Understanding the algorithm guarantees encoded in the alg claim prevents algorithm confusion attacks, where an attacker downgrades a token to a weaker algorithm your server inadvertently accepts.2
HS256: symmetric signing
HS256 (HMAC-SHA256) generates a signature by applying HMAC-SHA256 to the header and payload using a shared secret that both the signer and the verifier must possess. Because the same key both signs and verifies, every party that can verify tokens can also create new ones, which makes HS256 appropriate for single-service authentication where one backend controls both token issuance and verification without distributing the secret.
Why HS256 stays local
Yet sharing the HS256 secret with multiple services means all of them can forge arbitrary tokens, creating a significant security risk in distributed architectures where a single compromised service can impersonate any user. Keep HS256 secrets server-side only and never expose them to browser code or mobile applications, because any client-side embedding can be reverse-engineered to extract the key, which is why asymmetric algorithms are mandatory for any scenario where the verification key must cross a trust boundary.
RS256: asymmetric signing
RS256 (RSA-SHA256) uses a public/private key pair where the private key signs tokens during issuance while the public key verifies them during API calls, creating a clear separation between the authority to issue tokens and the authority to verify them. Consequently, distributing the public key to multiple services or publishing it via a JWKS endpoint lets each service verify tokens independently without gaining the ability to issue new ones, which is the fundamental security property that makes RS256 ideal for distributed systems.
Microservice architectures and third-party API integrations require RS256 or ES256, since giving every service the HS256 secret would allow any single compromised service to forge tokens for any user across the entire platform. ES256 (ECDSA-SHA256) provides the same asymmetric security model with shorter keys and faster signature operations at equivalent security levels, which reduces token size and improves verification throughput in high-volume APIs.
Algorithm confusion and security
Algorithm confusion attacks exploit JWT libraries that accept any algorithm the token header specifies rather than enforcing an allowlist on the server side.3 An attacker modifies the header to use HS256 and signs with the server's RS256 public key, effectively treating the publicly known RSA key as an HMAC secret to produce a signature that the vulnerable library accepts as valid. Building on this, the defence is straightforward: always enforce the expected algorithm in your verification code and reject any token whose alg does not match your allowlist, and never accept alg: none under any circumstances because that value indicates an unsigned token with no cryptographic proof of origin.
Generating and rotating RS256 key pairs for JWT signing
Generating an RS256 key pair for JWT signing requires a minimum of 2048-bit RSA keys; 4096 bits provides a larger security margin at the cost of slower signature operations. Generate a pair with openssl genrsa -out private.pem 2048 followed by openssl rsa -in private.pem -pubout -out public.pem. Store the private key in your secrets manager and publish the public key in a JWKS document at a stable URL your relying parties can fetch.
Managing the rotation transition window
Rotating RS256 keys without revoking existing tokens requires a transition window where both the old and new public keys appear in the JWKS simultaneously, each with a distinct kid.4 Start by adding the new key to the JWKS before switching signing to the new private key. Continue serving the old public key until all tokens signed with it have reached their exp. Remove the old public key only after that window closes.
Keeping private keys sealed after retirement
Keep the private key out of your JWKS document. The JWKS should expose public key parameters only, with a distinct kid for every key version.4 During rotation, sign with the newest private key while serving both public keys; once the oldest valid token expires, remove the old public key from the JWKS and keep the retired private key sealed in your secrets manager.
Publishing only public parameters in the JWKS keeps the signing authority with the service that holds the private key. The retired private key stays sealed so it can still verify old signatures during any dispute or audit long after it leaves active use. Document each key version and its kid so future operators know which private key corresponds to which public entry.
When to use this
Use RS256 or ES256 for any multi-service or public-facing API. Use HS256 only in single-service environments where the secret never leaves the server that issues the tokens. Reading the decoded token header for RS256 versus HS256 for JWTs shows you the alg value immediately, which is the first thing to check when you inherit a codebase and are not sure which algorithm it actually uses.
Examples
Single-service app (HS256 acceptable)
A web app where one server issues and verifies all tokens: no external services need to verify. HS256 is sufficient and simpler to configure. Keep the secret in an environment variable and rotate it with a key management service.
Microservices or third-party API (RS256 required)
An API gateway and three microservices all need to verify tokens. RS256 lets you distribute only the public key to each service. The token-issuing service keeps the private key and is the only party that can create valid tokens.
- 1.
M. Jones et al., "JSON Web Algorithms (JWA)," RFC 7518, IETF, May 2015. https://datatracker.ietf.org/doc/html/rfc7518
- 2.
D. Hardt, "JSON Web Token Best Current Practice," RFC 8725, IETF, February 2021. https://datatracker.ietf.org/doc/html/rfc8725
- 3.
PortSwigger, "JWT Algorithm Confusion Attacks," portswigger.net, accessed June 2026. https://portswigger.net/web-security/jwt/algorithm-confusion
- 4.
M. Jones et al., "JSON Web Key (JWK)," RFC 7517, IETF, May 2015. https://www.rfc-editor.org/rfc/rfc7517