RS256 (RSA-SHA256)

RS256 signs JWTs with an RSA private key and verifies them with the corresponding public key, using RSASSA-PKCS1-v1_5 with SHA-256 as defined in RFC 7518. Only your authorization service needs the private key; API gateways, microservices, and partner integrations validate tokens using PEM files or a JWKS document at /.well-known/jwks.json. This asymmetric split is the standard pattern for OAuth2 providers, multi-tenant SaaS platforms, and enterprise APIs where distributing a shared HMAC secret to every consumer is impractical or unacceptable. Implementation requires key generation, secure private key storage, and a plan to publish and rotate public keys without downtime.

Last updated July 25, 2026

How It Works

RS256 follows the same JWT compact serialization as HS256—a Base64URL header and payload joined by a dot—but the third segment is an RSA signature rather than an HMAC digest. The signer loads an RSA private key (typically PKCS#8 PEM), computes RSASSA-PKCS1-v1_5 over the SHA-256 hash of the signing input, and Base64URL-encodes the result. Verifiers parse the header, confirm alg is RS256, retrieve the matching public key (from disk, JWKS, or cached kid lookup), and perform RSA signature validation over the same hash. RFC 7518 registers RS256; RFC 7517 defines JWK and JWKS formats for publishing rsa modulus and exponent fields plus optional kid for rotation. Include a kid header when operating multiple active keys so verifiers select the correct public key during rollover. Private keys must never ship to edge services, browsers, or mobile apps; only the issuer signs. Middleware should fetch JWKS periodically with cache TTL, honor key expiration policies, and still validate exp, iss, aud, and other claims after cryptographic verification succeeds. Generate initial 2048-bit pairs with OpenSSL or /tools/rsa-key-generator, store the private key in HSM or vault-backed storage, and expose the public side through your discovery endpoint.

When to Use

Adopt RS256 when microservices, partner APIs, or SaaS tenants verify tokens without access to signing material. It fits OAuth2 authorization servers, federated identity products, and architectures where a central auth cluster signs while dozens of stateless services only validate. Choose RS256 when security policy requires private keys to remain on a hardened issuer and public distribution through JWKS is acceptable.

When Not to Use

Skip RS256 for simple single-process apps where symmetric HS256 already meets threat models and operational overhead of key pairs feels unjustified. Avoid it on extremely constrained devices if RSA verify latency dominates unless you profile and accept the cost. Do not choose RS256 if your stack lacks mature JWT RSA support or if you cannot operate JWKS rotation—half-implemented asymmetric auth is worse than a well-managed shared secret.

Key Length Requirements

Use RSA moduli of at least 2048 bits for new deployments; this aligns with NIST SP 800-57 recommendations through 2030 for general-purpose signatures. High-value or long-lived identity providers often prefer 3072 or 4096 bits for additional margin, accepting larger signatures and slower operations. The JWT signature itself is roughly 256 bytes for 2048-bit RSA regardless of payload size. Export private keys as PKCS#8 PEM, public keys as SPKI PEM or JWK with kty RSA, n, and e fields. Publish verifiers via JWKS with kid and use values matching your rotation schedule. The rsa-key-generator tool 2048-bit preset produces starter key pairs; replace automated demo keys before production and protect private PEM with filesystem permissions or cloud KMS wrap.

Security Pitfalls

  • Embedding RSA private keys in application repositories, Docker images, or client-side bundles where anyone with repo access can mint valid tokens.
  • Verifying RS256 tokens with a private key file or accepting whatever algorithm appears in the header without pinning algorithms: ['RS256'].
  • Publishing JWKS without kid headers while keeping multiple private keys active, causing verifiers to pick the wrong key and reject legitimate tokens—or accept forgeries after sloppy fallback logic.
  • Skipping JWKS cache invalidation during emergency rotation, leaving services validating against stale public keys for hours after a compromise.
  • Validating the RSA signature but ignoring issuer and audience claims, allowing tokens minted by a compromised staging issuer to access production APIs.

Code Examples

Node.js — sign with private key, verify with public key

const fs = require('fs');
const jwt = require('jsonwebtoken');

const privateKey = fs.readFileSync('private.pem');
const publicKey = fs.readFileSync('public.pem');

const token = jwt.sign(
  { sub: 'user_123', scope: 'read:orders' },
  privateKey,
  {
    algorithm: 'RS256',
    keyid: '2026-01',
    expiresIn: '15m',
    issuer: 'https://auth.example.com',
  }
);

const payload = jwt.verify(token, publicKey, {
  algorithms: ['RS256'],
  issuer: 'https://auth.example.com',
});

console.log(payload.sub);

Java — sign and verify with jjwt

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

PrivateKey privateKey = loadPrivateKey(Path.of("private.pem"));
PublicKey publicKey = loadPublicKey(Path.of("public.pem"));

String token = Jwts.builder()
    .subject("user_123")
    .issuer("https://auth.example.com")
    .signWith(privateKey, Jwts.SIG.RS256)
    .compact();

var claims = Jwts.parser()
    .verifyWith(publicKey)
    .requireIssuer("https://auth.example.com")
    .build()
    .parseSignedClaims(token)
    .getPayload();

Generate Keys

Recommended: 2048-bit

Open Rsa Key Generator

Related Comparisons

Related Terms

Related Guides

Frequently Asked Questions

How do microservices verify RS256 tokens without the private key?

Each service loads a PEM public key or fetches your JWKS endpoint and validates signatures locally with jwt.verify or equivalent middleware. Only the authorization server holds the private key and calls sign. Cache JWKS responses with a sensible TTL but refetch when verification fails with an unknown kid header.

What belongs in a JWKS endpoint for RS256?

Publish a JSON document with a keys array containing JWK objects: kty RSA, use sig, alg RS256, kid, n, and e fields derived from your public key. During rotation, list both old and new public keys until all issued tokens expire, then remove the retired kid. Document the URL in your OAuth metadata or service README so integrators configure jwt.verify against the correct issuer.

Is 2048-bit RSA still acceptable for new JWT issuers?

Yes—2048-bit RSA remains the industry default for JWT and TLS certificates in most environments through this decade. Move to 3072 or 4096 bits when regulatory guidance or internal crypto standards require longer moduli, understanding that signatures grow and CPU cost rises. Weak 1024-bit keys are obsolete and must not be used.

How does RS256 rotation differ from rotating an HS256 secret?

With RS256 you generate a new key pair, add the new public key to JWKS with a fresh kid, begin signing with the private key, and retire the old public key after outstanding tokens expire. Verifiers continue working without receiving secret material—they only refresh JWKS. HS256 rotation requires every signer and verifier to receive the new shared secret simultaneously, which is harder at scale.

Looking for a short definition?

Glossary: RS256 (RSA-SHA256)