RS256: RSA-SHA256 JWTs
RS256 signs a JWT with an RSA private key (PKCS#1 v1.5 padding, SHA-256). Anyone with the public key can verify it, but only the private-key holder can create tokens — the most widely supported asymmetric JWT algorithm.
How RS256 works
signature = RSASSA-PKCS1-v1_5-SIGN(privateKey, SHA-256(b64url(header) + "." + b64url(payload)))
verify = RSASSA-PKCS1-v1_5-VERIFY(publicKey, …)The signature is as long as the RSA modulus: 256 bytes for a 2048-bit key, which is why RS256 tokens are noticeably longer than HS256 or ES256 tokens.
Generating and formatting keys
Use at least 2048 bits (RFC 7518 §3.3); 3072 bits is a common choice for keys that live for years. You can generate a pair in the browser with the key generator, or with OpenSSL:
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out private.pem
openssl pkey -in private.pem -pubout -out public.pemJWTEncoder accepts PKCS#8 (BEGIN PRIVATE KEY), PKCS#1 (BEGIN RSA PRIVATE KEY, converted locally) and JWK private keys. Paste a public key and you get a specific explanation: signing requires the private key.
Publishing the public key (JWKS)
Verifiers usually fetch public keys from a JWK Set. Give every key a kid (the generator uses the RFC 7638 thumbprint), put that kid in the token header, and serve the JWKS at a stable HTTPS URL. During rotation, publish both old and new keys until old tokens expire.
Sign RS256 in code
import { SignJWT, importPKCS8 } from "jose";
const key = await importPKCS8(process.env.JWT_PRIVATE_KEY_PEM, "RS256");
const now = Math.floor(Date.now() / 1000);
const payload = {
iss: "https://auth.example.com/",
sub: "user-123",
aud: "api.example.com",
iat: now,
exp: now + 900,
};
const token = await new SignJWT(payload)
.setProtectedHeader({
alg: "RS256",
typ: "JWT",
kid: "2026-09",
})
.sign(key);
console.log(token);
The same RSA key pair works for PS256 (RSA-PSS). Choose PS256 when every verifier supports it.
Generate a key pair or paste your own private key, build claims and sign — with self-verification before you copy.
Create an RS256 JWT