RSA Key Generator

Generate RSA-OAEP key pairs and demonstrate encryption/decryption using Web Crypto API.

Back to all tools on ToolForge

More in Developer Tools

Public Key (SPKI, base64)

Private Key (PKCS#8, base64)


Encrypt (use public key)

Decrypt (use private key)

Result

About RSA Key Generator

This RSA key generator creates 2048-bit RSA-OAEP key pairs entirely in your browser using the Web Crypto API (crypto.subtle). RSA is an asymmetric cryptographic algorithm widely used for secure data transmission, digital signatures, and key exchange protocols.

RSA Algorithm Overview

RSA (Rivest-Shamir-Adleman) was invented in 1977 and remains one of the most widely used public-key cryptosystems:

RSA Key Generation:

1. Choose two large prime numbers p and q
   (For 2048-bit key, each prime is ~1024 bits)

2. Compute modulus n = p × q
   n is the public modulus used in both keys

3. Compute Euler's totient: φ(n) = (p-1)(q-1)

4. Choose public exponent e
   Common choice: e = 65537 (0x10001)
   Must be coprime to φ(n)

5. Compute private exponent d
   d = e^(-1) mod φ(n)
   (modular multiplicative inverse)

6. Public key: (n, e)
   Private key: (n, d)

Encryption: c = m^e mod n
Decryption: m = c^d mod n

Web Crypto API Implementation

JavaScript RSA Key Generation:

async function generateRSAKeyPair() {
  const keyPair = await crypto.subtle.generateKey(
    {
      name: "RSA-OAEP",
      modulusLength: 2048,
      publicExponent: new Uint8Array([1, 0, 1]), // 65537
      hash: "SHA-256"
    },
    true, // extractable
    ["encrypt", "decrypt"]
  );

  // Export public key (SPKI format)
  const pubKey = await crypto.subtle.exportKey("spki", keyPair.publicKey);
  const pubKeyBase64 = arrayBufferToBase64(pubKey);

  // Export private key (PKCS#8 format)
  const privKey = await crypto.subtle.exportKey("pkcs8", keyPair.privateKey);
  const privKeyBase64 = arrayBufferToBase64(privKey);

  return { pubKeyBase64, privKeyBase64 };
}

// RSA-OAEP Encryption
async function rsaEncrypt(publicKey, plaintext) {
  const encoder = new TextEncoder();
  const data = encoder.encode(plaintext);

  const ciphertext = await crypto.subtle.encrypt(
    { name: "RSA-OAEP" },
    publicKey,
    data
  );

  return arrayBufferToBase64(ciphertext);
}

// RSA-OAEP Decryption
async function rsaDecrypt(privateKey, ciphertextBase64) {
  const ciphertext = base64ToArrayBuffer(ciphertextBase64);

  const plaintext = await crypto.subtle.decrypt(
    { name: "RSA-OAEP" },
    privateKey,
    ciphertext
  );

  const decoder = new TextDecoder();
  return decoder.decode(plaintext);
}

RSA Key Size Comparison

Key Size Security Level Max Message (OAEP SHA-256) Status
1024-bit ~80 bits 190 bytes Broken, don't use
2048-bit ~112 bits 190 bytes Recommended minimum
3072-bit ~128 bits 190 bytes Long-term security
4096-bit ~140 bits 190 bytes High security

Padding Schemes Comparison

Scheme Security Overhead Recommendation
PKCS#1 v1.5 Vulnerable to padding oracle 11 bytes Legacy only
RSA-OAEP IND-CCA2 secure 2*hashLen + 2 Recommended
RSA-OAEP-256 IND-CCA2 secure 66 bytes (SHA-256) Best practice
Raw RSA Completely insecure None Never use

Key Format Specifications

Public Key Format (SPKI - Subject Public Key Info):
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Z3qX2BTLS4e...
(base64 encoded DER of ASN.1 structure)
-----END PUBLIC KEY-----

Private Key Format (PKCS#8):
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDZne...
(base64 encoded DER of ASN.1 structure)
-----END PRIVATE KEY-----

RSA Private Key (PKCS#1 - alternative format):
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA2Z3qX2BTLS4e...
(contains p, q, d, dp, dq, qInv for CRT optimization)
-----END RSA PRIVATE KEY-----

Hybrid Encryption

Due to RSA's size limitations, real-world systems use hybrid encryption:

Hybrid Encryption Flow:

1. Generate random symmetric key (AES-256)
   const aesKey = await crypto.subtle.generateKey(
     { name: "AES-GCM", length: 256 },
     true, ["encrypt", "decrypt"]
   );

2. Encrypt data with AES key
   const encryptedData = await crypto.subtle.encrypt(
     { name: "AES-GCM", iv: randomIV },
     aesKey,
     plaintext
   );

3. Encrypt AES key with RSA public key
   const encryptedKey = await crypto.subtle.encrypt(
     { name: "RSA-OAEP" },
     rsaPublicKey,
     exportedAesKey
   );

4. Send: encryptedData + encryptedKey + IV
   Recipient decrypts AES key with RSA private key,
   then decrypts data with AES key.

This approach combines RSA's secure key exchange
with AES's efficient bulk encryption.

RSA Security Considerations

Consideration Risk Mitigation
Small key sizes Factorization attacks Use 2048-bit minimum
Weak random primes Predictable keys Use CSPRNG (Web Crypto)
Timing attacks Key extraction Constant-time implementations
Side-channel attacks Power analysis, EM leaks Hardware countermeasures
Quantum computers Shor's algorithm Post-quantum cryptography

Common Use Cases

Limitations

Post-Quantum Considerations

RSA is vulnerable to quantum computers using Shor's algorithm. For long-term security:

How to Use RSA Key Generator

  1. Generate keys: Click "Generate Key Pair" to create a new 2048-bit RSA key pair.
  2. Copy keys: Use the Copy buttons to save your public and private keys.
  3. Encrypt: Enter a short message and click "Encrypt" to encrypt with the public key.
  4. Decrypt: Paste the encrypted ciphertext and click "Decrypt" to recover the plaintext.

Tips

Frequently Asked Questions

How does RSA encryption work?
RSA is an asymmetric cryptosystem based on the mathematical difficulty of factoring large integers. It uses a public key for encryption and a private key for decryption. The keys are generated from two large prime numbers (p and q). Security relies on the fact that while multiplying primes is easy, factoring the product back to primes is computationally infeasible for sufficiently large numbers (2048+ bits).
What is the difference between RSA-OAEP and PKCS#1 v1.5?
RSA-OAEP (Optimal Asymmetric Encryption Padding) is a more secure padding scheme that provides semantic security and is resistant to chosen-ciphertext attacks. PKCS#1 v1.5 is older and vulnerable to padding oracle attacks (Bleichenbacher attack). OAEP uses hash functions and mask generation functions for stronger security guarantees. Modern applications should use RSA-OAEP.
What key size should I use for RSA?
Minimum 2048-bit for current security (recommended). 3072-bit or 4096-bit for long-term security or high-value data. 1024-bit is considered broken and should not be used. NIST recommends 2048-bit minimum through 2030, 3072-bit+ after. Larger keys provide more security but slower operations and larger ciphertext.
What is the RSA message size limit?
RSA can only encrypt messages smaller than the key size minus padding overhead. For 2048-bit RSA-OAEP with SHA-256: max message = 256 - 2*32 - 2 = 190 bytes. This is why RSA is typically used to encrypt symmetric keys (hybrid encryption), not large messages directly.
What are SPKI and PKCS#8 formats?
SPKI (Subject Public Key Info) is the standard format for public keys defined in X.509. PKCS#8 is the standard format for private keys. Both are ASN.1 DER-encoded structures. This tool exports keys in these formats and encodes them as base64 for display. PEM format wraps these with header/footer lines.
Is browser-based RSA key generation secure?
Yes, when using the Web Crypto API (crypto.subtle). It uses the browser's cryptographically secure random number generator (CSPRNG). Keys never leave your device in this tool. However, for production use, consider: server-side generation in HSMs, proper key storage (keychains, vaults), and secure key exchange protocols.