By AndyPublished Updated

HS256 vs RS256: When to Use Symmetric vs Asymmetric JWT Signing

The choice between HS256 (HMAC-SHA256) and RS256 (RSA-SHA256) is one of the most consequential decisions in a JWT-based authentication architecture. It determines who can verify tokens, who can issue them, and how you manage keys across your system. This guide explains both algorithms, compares their operational differences, and helps you choose the right one for your use case.

The Fundamental Difference

HS256 is a symmetric algorithm. It uses a single shared secret for both signing and verification. Any party with the secret can sign and verify tokens.

RS256 is an asymmetric algorithm. It uses a private key for signing and a public key for verification. Only the party with the private key can sign tokens, but anyone with the public key can verify them, without being able to forge new tokens.

// HS256: one secret, used for both
sign(payload, secret)      → token
verify(token, secret)      → valid/invalid

// RS256: separate keys for sign vs verify
sign(payload, private_key) → token
verify(token, public_key)  → valid/invalid

HS256: HMAC-SHA256

How it works

HMAC-SHA256 computes a keyed hash of the signing input (base64url(header) + "." + base64url(payload)) using the shared secret. The output is used as the JWT signature. Verification re-computes the HMAC and compares it to the token's signature using a constant-time comparison.

When to use HS256

  • ·Simple architectures with a single auth server and a single API service that are both under your control and share the same trust boundary
  • ·Environments where distributing and managing a public key infrastructure adds complexity that isn't justified by the scale
  • ·Internal tools or development environments where the secret can be tightly controlled

HS256 limitations

⚠
Any service that can verify HS256 tokens can also forge them. If a downstream API service is compromised, an attacker can issue arbitrary tokens.
  • ·Secret distribution problem: The shared secret must be securely distributed to every service that verifies tokens. More services = more exposure.
  • ·No separation of signing authority: A verifier is also a potential forger. This is acceptable in a monolithic app but dangerous in a multi-team microservices environment.
  • ·Rotation complexity: Rotating the secret requires coordinating the update across all services simultaneously or implementing a dual-secret overlap period.
  • ·Low-entropy secret risk: An HS256 secret is only as strong as the entropy it contains. Short or predictable secrets (common passwords, UUIDs, base64 of a short string) are vulnerable to offline brute-force attacks against captured tokens. Use at least 32 bytes of cryptographically random data.

RS256: RSA-SHA256

How it works

The auth server uses a 2048-bit (or larger) RSA private key to sign the token with PKCS#1 v1.5 padding. API services verify the token using the corresponding RSA public key. The public key can be distributed via a JWKS endpoint without security risk.

When to use RS256

  • ·Architectures with multiple independent services that need to verify tokens, each gets the public key but cannot forge tokens
  • ·Any system where the token issuer (auth server) and the token consumers (APIs) are operated by different teams or organizations
  • ·When you want to publish your public keys openly via a JWKS endpoint for third-party integrations or open-source SDKs
  • ·Production systems where the principle of least privilege applies, services should not have access to capabilities they don't need

ES256: ECDSA as an Alternative

ES256 (ECDSA with P-256 and SHA-256) provides the same separation of signing and verification as RS256, but with much smaller keys and signatures. An ES256 private key is 256 bits; an RS256 key is typically 2048–4096 bits.

  • ·Smaller signatures reduce JWT size and HTTP header overhead
  • ·Faster verification on constrained hardware (IoT, edge nodes)
  • ·Equivalent security to RS256 with much smaller keys
  • ·Slightly more complex to implement correctly, use a well-tested library

PS256: RSA-PSS as the Modern Alternative to RS256

PS256 (RSA-PSS with SHA-256) is the successor to RS256. Both use RSA key pairs, but they differ in the padding scheme applied before signing:

  • ·RS256 uses PKCS#1 v1.5 padding: deterministic, well-understood, but the padding scheme has theoretical weaknesses (Bleichenbacher attacks) and lacks a tight security proof in the standard cryptographic sense.
  • ·PS256 uses PSS (Probabilistic Signature Scheme) padding: randomised (each signature of the same input produces a different output), and provably secure in the random oracle model. RFC 7518 notes that RSA-PSS is preferable to PKCS#1 v1.5 for new implementations.

In practice, both RS256 and PS256 are secure with 2048+ bit keys. The choice matters more for compliance (some standards now mandate PSS) than for immediate attack surface. If you are starting a new system and require RSA, use PS256. If you are operating an existing RS256 system, migration is low-priority unless your threat model or compliance requirements demand it.

Real-World Algorithm Choices by Platform

Major identity providers and cloud platforms have made different default algorithm choices:

PlatformDefault algorithmNotes
Auth0RS256Recommended default; HS256 available for legacy
OktaRS256Keys published at /oauth2/v1/keys JWKS endpoint
AWS CognitoRS256Keys at cognito-idp.<region>.amazonaws.com/<pool>/.well-known/jwks.json
Google (OAuth2 / Firebase)RS256Keys at accounts.google.com/.well-known/openid-configuration
Azure AD / Entra IDRS256Supports PS256 for newer app registrations
KeycloakRS256Configurable; ES256 and PS256 available
Custom HS256HS256Typical for internal monolith, single shared secret

If you integrate with a third-party identity provider, you have no choice, use whatever algorithm the provider issues. The choice between HS256 and RS256 is relevant only when you are building and operating your own token issuer.

Side-by-Side Comparison

PropertyHS256RS256ES256
Algorithm typeSymmetricAsymmetricAsymmetric
Key for signingShared secretRSA private keyEC private key
Key for verificationSame shared secretRSA public keyEC public key
Key size≥ 32 bytes2048–4096 bits256 bits
Can verifier forge tokens?YesNoNo
JWKS supportNo (key is secret)YesYes
Signature size32 bytes (HS256)256–512 bytes64 bytes
Best forSingle-service appsMulti-service, enterprisePerformance-sensitive

JWT Algorithms List

The alg values for signed JWTs are defined by JSON Web Algorithms, RFC 7518 §3.1, with a few later additions. The implementation-requirement column is RFC 7518's own: only HS256 is required, RS256 is recommended and ES256 is "Recommended+", meaning it is expected to become required.

algFamilyKeySignature sizeStatus
HS256 / HS384 / HS512HMAC with SHA-2Shared secret, at least as long as the hash output32 / 48 / 64 bytesHS256 Required
RS256 / RS384 / RS512RSASSA-PKCS1-v1_5RSA key pair, 2048 bits or moreKey size (256 bytes at 2048 bits)RS256 Recommended
PS256 / PS384 / PS512RSASSA-PSSRSA key pair, 2048 bits or moreKey size (256 bytes at 2048 bits)Optional
ES256 / ES384 / ES512ECDSA on P-256 / P-384 / P-521EC key pair on the named curve64 / 96 / 132 bytesES256 Recommended+
EdDSAEd25519 / Ed448 (RFC 8037)OKP key pair64 bytes (Ed25519)Registered separately
ES256KECDSA on secp256k1 (RFC 8812)secp256k1 key pair64 bytesRegistered separately
noneUnsecured JWTNone0 bytesMust be rejected by verifiers

The jwtdecode.app decoder verifies every HS, RS, PS and ES variant in the browser. EdDSA and ES256K tokens decode normally but cannot be verified there. For how the ECDSA and RSA-PSS rows differ in practice, see ES256 explained and PS256 vs RS256; for why none must be refused, see the none algorithm vulnerability.

HS256 vs HS384 vs HS512

The three HMAC variants differ only in the SHA-2 function underneath. HS256 produces a 32-byte tag, HS384 a 48-byte tag and HS512 a 64-byte tag, so tokens get longer as you move up. RFC 7518 §3.2 requires the key to be at least as long as the hash output: 256 bits for HS256, 384 for HS384 and 512 for HS512.

  • ·Security: with a properly random key of the required length, HS256 already gives a margin far beyond any practical attack. Moving to HS512 does not fix the real-world HMAC failure, which is a short, guessable secret.
  • ·Performance: SHA-512 processes 64-bit words and is often as fast as or faster than SHA-256 on 64-bit servers without SHA extensions. For JWT-sized inputs the difference is negligible either way.
  • ·When HS512 makes sense: a compliance policy that mandates it, or consistency with other systems that already use it.

Whichever you choose, generate the secret with a cryptographic random generator; see the JWT secret key generator.

Which JWT Algorithm Is Best?

  • ·One service issues and verifies its own tokens: HS256 with a 256-bit random secret is simple and fast.
  • ·Tokens are verified by other services or third parties: an asymmetric algorithm, so verifiers only ever hold a public key. ES256 for new systems; RS256 where you need the widest library and identity-provider support; PS256 if you already run RSA keys and your stack supports it.
  • ·Whatever you pick: pin the expected algorithm in the verifier's allow-list rather than trusting the token's header, as RFC 8725 §3.1 requires.

Migrating from HS256 to RS256

If you're upgrading an existing HS256 system to RS256:

  • ·Generate an RSA or EC key pair in your auth service
  • ·Publish the public key via a JWKS endpoint at a predictable URL
  • ·Update all verifying services to fetch and cache the JWKS
  • ·Deploy a transition period where both algorithms are accepted
  • ·Once all existing HS256 tokens have expired, remove the old verification path
  • ·Revoke and destroy the HS256 shared secret
Ready to decode a token?
Use the free JWT decoder — paste any token for instant results, entirely in your browser.
Open JWT Decoder