Skip to main content

RSA Key Generator

Generate RSA key pairs (2048 or 4096 bit) in PEM format using the Web Crypto API.

Reviewed by · Last reviewed

Producing an RSA Key Pair in Your Browser

  1. Pick a key size: 2048 for general-purpose modern TLS certificates and JWT signing, 4096 for long-lived keys or compliance regimes that demand the extra margin. 3072 is specified by NIST SP 800-57 as the 128-bit security-level equivalent but is less commonly offered.
  2. Click "Generate RSA Key Pair". The browser calls crypto.subtle.generateKey({name: 'RSA-OAEP', modulusLength: 2048, publicExponent: new Uint8Array([1,0,1]), hash: 'SHA-256'}, true, ['encrypt', 'decrypt']). This runs a probabilistic prime search, which takes 200ms to a few seconds at 2048 bits and up to 30 seconds at 4096.
  3. Read the two PEM blocks. The public key appears as -----BEGIN PUBLIC KEY----- (SubjectPublicKeyInfo / SPKI format, per RFC 5280); the private key appears as -----BEGIN PRIVATE KEY----- (PKCS#8 format, per RFC 5958).
  4. Copy the public key into anything that needs to verify your signatures or encrypt messages to you. It is safe to publish; post it on GitHub, embed it in certificate signing requests, or paste it into a JWT verification config.
  5. Store the private key in a secret manager immediately. Anyone with the PEM can decrypt messages intended for you or forge your signatures. Do not email it, commit it to git, or paste it into a ticket.

How the Browser Generates Primes and Assembles the Key

RSA key generation is specified in RFC 8017 (PKCS#1 v2.2) section 3. The browser picks two random primes p and q of roughly modulusLength / 2 bits each using crypto.getRandomValues-seeded Miller-Rabin testing, computes the modulus n = p * q, the totient phi(n) = (p-1)(q-1), the public exponent e = 65537, and the private exponent d = e^-1 mod phi(n) via extended Euclidean. The private key stores CRT parameters dp, dq, qinv for 4x faster decryption. Output CryptoKey objects are serialized via exportKey('spki', publicKey) and exportKey('pkcs8', privateKey), Base64-encoded, wrapped in PEM headers. BoringSSL or NSS runs in constant time where applicable to prevent timing-based key recovery.

Legitimate Uses and Why You Would Generate These

  • Requesting a TLS certificate: generate the key pair, create a CSR (Certificate Signing Request) with the public key, submit to Let\'s Encrypt or an internal CA, receive a signed certificate binding your public key to your domain.
  • JWT signing with RS256: the issuer holds the private key and signs each JWT; the verifier has only the public key, so a server breach on the verifier side cannot mint new tokens.
  • PGP/GPG keypair for encrypted email and commit signing. GitHub verifies commits signed with keys uploaded to your account profile.
  • SSH host or user authentication, though Ed25519 is the modern default here because RSA keys and signatures are larger and slower.
  • Code signing: macOS Developer ID, Microsoft Authenticode, and npm package provenance all use RSA or ECDSA; 2048-bit RSA remains accepted.
  • Asymmetric envelope encryption for sending a symmetric session key to a recipient: you encrypt a random AES key with the recipient\'s RSA public key, they decrypt it with their private key, and the bulk of the payload is AES-GCM with the session key.

Key Size, Padding Mode, and Post-Quantum Anxiety

NIST SP 800-57 Part 1 Rev 5 maps RSA sizes to symmetric levels: 2048 is 112-bit equivalent (acceptable through 2030), 3072 is 128-bit (recommended for new), 7680 is 192-bit, 15360 is 256-bit. 4096 sits between 3072 and 7680 at roughly 140-bit. The most dangerous pitfall is padding: PKCS#1 v1.5 (still used by older TLS and JWT RS256) is vulnerable to Bleichenbacher padding oracle attacks that broke real systems (ROBOT 2017 affected F5, Citrix, Cisco). RSA-OAEP is the modern encryption padding; RSA-PSS is the modern signature padding. Never use textbook RSA without padding. The looming threat is Shor\'s algorithm on a quantum computer: any RSA key becomes trivially factorizable. NIST finalized post-quantum KEM standards in 2024 (ML-KEM FIPS 203). For long-term keys, consider hybrid RSA+ML-KEM.

PEM, PKCS#1, PKCS#8, SPKI, and OpenSSH

RSA keys travel in several encodings and picking the wrong one breaks interop. PEM is the outer textual wrapper: Base64 of DER-encoded ASN.1 between BEGIN/END lines. Inside, PKCS#1 (RFC 8017 appendix A.1) is RSA-specific (BEGIN RSA PRIVATE KEY, the old openssl genrsa output). PKCS#8 (RFC 5958) is algorithm-agnostic (BEGIN PRIVATE KEY) - Web Crypto emits PKCS#8 and it is the modern preferred format. For public keys, SPKI (RFC 5280) wraps any public key type with an algorithm identifier - Web Crypto exports SPKI as BEGIN PUBLIC KEY. OpenSSH uses its own non-PEM format (ssh-rsa AAAA...) which is DER-encoded differently; convert PEM PKCS#8 with ssh-keygen -i -f input.pem -m PKCS8. Wrong format is indistinguishable from a broken key.

RSA in 2026 vs Ed25519 and ECDSA

RSA is the workhorse but is being displaced. Ed25519 (RFC 8032) produces 64-byte signatures versus RSA-2048\'s 256 bytes, signs in microseconds, and is the default for new SSH keys (ssh-keygen -t ed25519), GitHub commit signing, and several TLS libraries. ECDSA P-256 (FIPS 186-5) is the default for WebAuthn and most modern TLS certs. RSA still wins when you need encryption (Ed25519 is sign-only), interop with legacy systems, or FIPS 140-3 modules where Ed25519 was only added recently. Practical rule: generate RSA if you have a specific requirement, otherwise use elliptic-curve alternatives that are faster and smaller.

Frequently Asked Questions

Why does 4096-bit key generation take so long?

RSA key generation is a probabilistic prime search: pick random numbers of the required bit length, apply Miller-Rabin primality testing, discard composites, retry until two suitable primes are found. The probability of a random 2048-bit number being prime is roughly 1 in 1400 by the Prime Number Theorem; at 4096 bits it is 1 in 2800, so generation needs twice as many Miller-Rabin rounds on individually slower big-integer arithmetic. On a modern laptop this costs 10-30 seconds for 4096 bits versus 200-800 milliseconds for 2048. The tab stays responsive because crypto.subtle.generateKey is async and runs on a native crypto thread.

Is the private key ever transmitted to the server hosting this page?

No. crypto.subtle.generateKey runs entirely in the browser's native crypto module, and the resulting CryptoKey objects are exported to PEM via crypto.subtle.exportKey on the same thread. No fetch or XHR touches the key material. You can open DevTools Network tab, generate a 4096-bit key, and observe zero outgoing requests containing key data. The only way the private key leaves your machine is if you explicitly paste it somewhere; treat the clipboard and screen as the trust boundary.

Is 2048-bit RSA still secure in 2026?

Yes, through 2030 per NIST SP 800-57 Part 1 Rev 5, which places 2048-bit RSA at 112-bit symmetric-equivalent security. The best known attacks on factoring (General Number Field Sieve) have not crossed the 2048-bit threshold. For keys intended to remain secure past 2030 or to survive harvest-now-decrypt-later threats from future quantum computers, use 3072 bits or hybrid with ML-KEM. For short-lived keys (TLS certificates rotating every 90 days via ACME), 2048 bits is more than adequate.

Why is the public exponent always 65537?

Performance and compatibility. 65537 = 2^16 + 1 has only two bits set in binary, which makes RSA encryption and signature verification fast. It is prime, which simplifies computing d. And it has been the de-facto standard since the late 1990s, so every library, smartcard, and HSM handles it correctly. Smaller exponents like 3 are cryptanalytically fine with correct padding but have caused real vulnerabilities (Bleichenbacher's 2006 e=3 signature forgery). 65537 is the safe default.

What is RSA-OAEP and why does it matter?

RSA-OAEP (RFC 8017 section 7.1) is the modern RSA encryption padding. It adds structured randomness so encrypting the same message twice produces different ciphertexts, and resists Bleichenbacher padding oracle attacks (ROBOT 2017 broke PKCS#1 v1.5). This tool generates keys with RSA-OAEP and SHA-256 mask hash. Never use raw RSA or PKCS#1 v1.5 for new encryption.

Should I worry about quantum computers breaking this key?

For frequently-rotating keys, no - a cryptographically relevant quantum computer is not expected before 2030. For long-term secrets (encrypted archives, compliance email), yes: an attacker today can intercept RSA traffic and decrypt later once quantum hardware arrives. NIST finalized ML-KEM (FIPS 203) in 2024 as the standard post-quantum KEM. For long-lived data, hybrid RSA+ML-KEM is current best practice.

Can I encrypt a large file directly with the public key?

No. RSA can only encrypt messages shorter than the modulus minus padding overhead - roughly 214 bytes for 2048-bit RSA with OAEP-SHA-256. For larger data, use hybrid encryption: generate a random AES-GCM key, encrypt your file with AES-GCM, then encrypt the AES key with the recipient's RSA public key. This is the pattern in PGP, S/MIME, and TLS handshake. The companion AES-GCM tool on this site handles the symmetric half.

How does this compare to openssl genpkey?

Functionally equivalent output. openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 produces a PKCS#8 PEM private key identical in format; openssl rsa -in key.pem -pubout extracts the matching SPKI public key. The CLI wins on scriptability and FIPS-validated builds; this tool wins on browser-local generation. For automated pipelines, openssl or language bindings (Python cryptography, Node crypto.generateKeyPairSync) are the right answer.

More Security & Privacy