Guide Updated

RS256 JWT — RSA-SHA256 Signing & Verification

RS256 is the JWT algorithm used by Auth0, Okta, and AWS Cognito. RSA key sizes, sign/verify code, JWKS verification, and when RS256 is right.

RS256 is RSASSA-PKCS1-v1_5 with SHA-256: the asymmetric JWT signing algorithm used by every major identity provider. Auth0, Okta, AWS Cognito, Google, and Microsoft Entra ID all default to RS256. A private RSA key signs tokens; the corresponding public key verifies them. Defined in RFC 7518 §3.3.

Key facts and signature size

Property RS256
Type Asymmetric (RSA, PKCS#1 v1.5 padding)
Key 2048-bit RSA minimum (3072-bit for ~128-bit security)
Signature size Key size ÷ 8 (256 bytes for 2048-bit)
Security ~112-bit for 2048-bit keys
Compatibility Universal: the identity-provider default

When to use

Use RS256 when tokens are verified by multiple independent services or third parties, when you integrate with Auth0/Okta/AWS Cognito/Google/Microsoft, or when you need JWKS-based key rotation. The public key can be published openly; only the auth server holds the private key. This is the safe default for any distributed system that does not have a specific reason to pick another algorithm.

When not to use

RS256 produces the largest signatures (256 bytes for a 2048-bit key, 4× ES256's 64 bytes). For size-constrained contexts (cookies, header limits) and systems you control end-to-end, ES256 gives the same security with smaller tokens. For new deployments with no legacy constraints, RFC 7518 recommends PS256 (PSS padding) over RS256.

Code examples

Generate an RSA key pair

Generate an RSA key pair
# OpenSSL: 2048-bit
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out rsa-private.pem
openssl pkey -pubout -in rsa-private.pem -out rsa-public.pem

// Node.js
const { generateKeyPairSync } = require("crypto");
const { privateKey, publicKey } = generateKeyPairSync("rsa", {
  modulusLength: 2048,
  publicKeyEncoding: { type: "spki", format: "pem" },
  privateKeyEncoding: { type: "pkcs8", format: "pem" },
});

Sign and verify (Node.js: jsonwebtoken)

Sign and verify (Node.js: jsonwebtoken)
const token = jwt.sign(
  { sub: "user_123" },
  privateKey,
  {
    algorithm: "RS256",
    expiresIn: "15m",
    keyid: "rsa-key-v1",   // matches kid in JWKS
  }
);

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

Frequently asked questions

  • What is RS256 in JWT?

    RS256 is RSASSA-PKCS1-v1_5 with SHA-256: an asymmetric JWT signing algorithm. A private RSA key signs tokens; the matching public RSA key verifies them. The public key can be published at a JWKS endpoint so any service can verify tokens without the ability to forge them. RS256 is the default for Auth0, Okta, AWS Cognito, Google, and Microsoft Entra ID.

  • What RSA key size should I use for RS256?

    2048 bits is the recommended minimum for all RS/PS algorithms (~112-bit security). Use 3072 bits only if you want ~128-bit security equivalence with ES256. The SHA variant (256/384/512 in RS256/RS384/RS512) does not dictate the RSA key size: that is an independent choice. The signature size equals the key size in bytes (a 2048-bit key produces a 256-byte signature).

  • Does Auth0 use RS256 or HS256?

    Auth0 defaults to RS256 for ID tokens and publishes its public keys at /.well-known/jwks.json. Okta, AWS Cognito, Google, and Microsoft Entra ID also default to RS256. If you are validating tokens from any major identity provider, you are using RS256. Hardcode algorithms: ['RS256'] in your verification calls and fetch the public key from the provider's JWKS endpoint: never hardcode the key itself, as providers rotate keys without notice.

Related