๐๏ธ RSA Key Pair Generator
Generate RSA key pairs locally in your browser โ keys never leave your device.
RSA Key Pairs: What They Actually Are and How to Generate Them Safely
RSA is one of the oldest asymmetric cryptographic algorithms still in active, widespread use. Designed in 1977 by Rivest, Shamir, and Adleman, it underpins SSH authentication, TLS handshakes, JWT signing, PGP email encryption, and dozens of other protocols you rely on every day without thinking about it. Yet most developers who use RSA keys regularly have a vague mental model of where they come from and why the parameters matter. This article closes that gap โ covering exactly what the tool above generates, how the keys are structured, and what you should (and should not) do with them.
The Mathematical Foundation in Plain Terms
RSA security rests on a deceptively simple asymmetry: multiplying two large prime numbers together is fast and easy for any computer. Factoring the resulting product back into its two prime components, however, becomes computationally intractable as the number grows. An RSA key pair is built by choosing two secret primes p and q, computing their product n = p ร q (called the modulus), and then deriving a matched pair of exponents โ one public, one private โ that have a special mathematical relationship through Euler's totient function.
The public key contains just two values: the modulus n and the public exponent e. Nearly every implementation in the world uses e = 65537 (which is 2ยนโถ + 1 in binary, a Fermat prime with efficient exponentiation properties). The private key contains the modulus n, the private exponent d (the modular inverse of e), and as an optimization the original primes and precomputed CRT coefficients for faster decryption. This is why a private key file is always much larger than a public key file for the same bit size.
2048-bit vs 4096-bit: A Practical Decision
The "bit size" of an RSA key refers to the bit-length of the modulus n. A 2048-bit key means n is a 617-digit number. Doubling to 4096 bits squares the difficulty of factoring roughly (it actually grows faster than linear with key size). As of 2025, the best publicly known factoring algorithms cannot factor a 2048-bit RSA modulus in any practical timeframe โ the estimates run to millions of CPU-years. NIST recommends 2048-bit as the minimum through 2030 and 3072-bit or higher for data requiring protection beyond that horizon.
4096-bit keys are not meaningless overkill, but their benefits must be weighed against real costs. RSA private-key operations (signing, decryption) scale roughly with the cube of the key bit-length โ a 4096-bit operation takes about eight times as long as a 2048-bit one. For a high-traffic TLS terminator or a JWT issuer processing thousands of tokens per second, this matters. For a personal SSH key used a few dozen times per day, it does not. The tool above generates 4096-bit keys correctly; the correct choice for most users today is still 2048-bit unless you have a specific long-term archival reason to go higher.
One practical note: if you are starting fresh and primarily care about future-proofing, consider whether you need RSA at all. Elliptic Curve Cryptography (Ed25519 for signing, X25519 for key exchange) provides comparable security to RSA-3072 with a 256-bit key, much faster operations, and shorter key material. RSA's advantage is universal compatibility โ every SSH server, every TLS library, every HSM in existence supports it. Ed25519 is now nearly as universal, but RSA remains the safe default when you are unsure about the target environment.
What PEM Format Actually Contains
PEM (Privacy Enhanced Mail, a name inherited from a long-defunct email standard) is a base64-encoded wrapper around DER (Distinguished Encoding Rules) binary structures defined by ASN.1. The tool generates two distinct PEM types:
The public key uses SubjectPublicKeyInfo (SPKI) format, labeled -----BEGIN PUBLIC KEY-----. This is the modern, algorithm-agnostic format defined in RFC 5480 and RFC 5958. It encodes an algorithm identifier (OID for rsaEncryption: 1.2.840.113549.1.1.1) followed by the actual RSAPublicKey structure containing n and e. Some older tools produce -----BEGIN RSA PUBLIC KEY----- which is the raw PKCS#1 format without the algorithm wrapper โ these are not interchangeable without conversion.
The private key uses PKCS#8 format, labeled -----BEGIN PRIVATE KEY-----. This is the unencrypted PrivateKeyInfo structure from RFC 5958. Older OpenSSL-generated keys used the legacy PKCS#1 format labeled -----BEGIN RSA PRIVATE KEY-----. PKCS#8 is preferred in modern tooling because it is algorithm-agnostic and supports encrypted wrapping (becoming -----BEGIN ENCRYPTED PRIVATE KEY----- with a passphrase). The keys this browser tool generates are unencrypted PKCS#8 โ suitable for direct use, but you should add passphrase protection before storing them anywhere sensitive.
How the Browser Generates Keys (and Why It's Safe)
The tool uses the Web Crypto API (window.crypto.subtle), which is a W3C-standardized cryptographic primitive layer built into every modern browser. The generateKey() call with extractable: true triggers the browser's internal cryptographic engine โ in Chromium this is BoringSSL, in Firefox it is NSS (Network Security Services), in Safari it is the Apple Security framework. These are the same battle-tested C libraries used in your OS's TLS stack, not JavaScript reimplementations of RSA math.
The critical security property here is that key generation never touches any network stack. The SubtleCrypto API operates entirely in the browser process. No XHR, no WebSocket, no service worker intercept can capture keys during generation. You can disconnect from the internet before clicking "Generate" and the tool functions identically โ which is a useful sanity check if you are paranoid (and you should be, with private keys).
The resulting keys are exported in raw DER binary (SPKI for public, PKCS#8 for private) via exportKey(), then base64-encoded in the browser using btoa() with 64-character line wrapping to produce the familiar PEM text.
Using Generated Keys: Common Scenarios
SSH authentication: The PEM public key from this tool needs conversion for SSH authorized_keys format. OpenSSH uses its own wire format for public keys, not bare SPKI/PEM. Run ssh-keygen -i -m PKCS8 -f public_key.pem or use a library to convert. The private key in PKCS#8 PEM is directly accepted by modern OpenSSH clients as an identity file.
JWT RS256/RS512 signing: JWT libraries that support RSA (like jsonwebtoken in Node.js, PyJWT in Python, or golang-jwt) accept PKCS#8 PEM private keys and SPKI PEM public keys exactly as generated here. Point the signing function at your private key file and the verification function at your public key file.
TLS/SSL certificates: A Certificate Signing Request (CSR) embeds the public key. Generate a CSR from the private key using openssl req -new -key rsa_private_key.pem -out request.csr. The resulting certificate will contain your public key signed by a CA.
Asymmetric encryption: If you selected "Encryption (OAEP)" in the tool, the key pair is set up for RSA-OAEP rather than signing. RSA encryption is almost never used to encrypt data directly โ it is used to encrypt a symmetric key (AES-256), which then encrypts the actual payload. This is called a hybrid encryption scheme and is the basis of how PGP and CMS/S-MIME work.
Protecting Your Private Key
The private key file downloaded from this tool is unencrypted. Anyone who obtains the file can impersonate you for SSH, forge JWTs, or decrypt messages encrypted to your public key. Store it with filesystem permissions set to 600 (owner read-only) at minimum. For anything beyond personal experimentation, encrypt it with a passphrase using openssl pkcs8 -in rsa_private_key.pem -topk8 -out rsa_private_key_encrypted.pem -v2 aes-256-cbc. For production systems, private keys should live in hardware security modules (HSMs), cloud KMS services (AWS KMS, Google Cloud KMS, Azure Key Vault), or at minimum an OS keychain โ not in plaintext files on disk or committed to version control.
The public key, by contrast, is meant to be distributed. Publish it in your SSH authorized_keys, embed it in certificates, share it with JWT verification services. There is no security implication to making a public key public โ that is, quite literally, its purpose.