Interactive RSA-OAEP public-key encryption experiment. Generate a 2048-bit key pair, encrypt a message with the public key, and decrypt it with the private key — entirely in-browser using the Web Crypto API. No data ever leaves your browser.
RSA (Rivest–Shamir–Adleman) is an asymmetric encryption algorithm. Asymmetric means there are two mathematically linked keys:
This experiment uses RSA-OAEP (Optimal Asymmetric Encryption Padding) with a 2048-bit key and SHA-256 hashing — the modern standard for RSA encryption.
Clicking Generate RSA-OAEP Key Pair calls crypto.subtle.generateKey() and produces:
BEGIN PUBLIC KEY)BEGIN PRIVATE KEY)Key generation typically takes 100–500 ms depending on your device. The timing badge shows actual milliseconds.
Enter plaintext (up to 190 UTF-8 bytes — the RSA-OAEP/SHA-256 limit for 2048-bit keys) and click Encrypt with Public Key.
The output ciphertext is always 344 base64 characters (256 raw bytes) regardless of input length. This is a property of RSA: the ciphertext is always the same size as the key modulus.
The ciphertext textarea is pre-filled from Step 2. Click Decrypt with Private Key to recover the original plaintext.
You can also paste any externally generated RSA-OAEP ciphertext here — as long as you have the matching private key.
Try with Wrong Key generates a fresh ephemeral key pair and attempts decryption, which always fails. This demonstrates that without the correct private key, decryption is computationally infeasible — RSA security is based on the hardness of factoring large numbers.
The ciphertext (?ct=...) is synced to the URL for shareability. Keys and plaintext are never included in the URL — only ciphertext. When you open a shared URL, the ciphertext is pre-loaded into Step 3, but no keys are present (you need to generate a new key pair or already have the matching private key).
crypto.subtle) is only available in secure contexts.// Generate key pair
crypto.subtle.generateKey(
{ name: "RSA-OAEP", modulusLength: 2048,
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
hash: "SHA-256" },
true, ["encrypt", "decrypt"]
)
// Encrypt
crypto.subtle.encrypt({ name: "RSA-OAEP" }, publicKey, plainBytes)
// Decrypt
crypto.subtle.decrypt({ name: "RSA-OAEP" }, privateKey, cipherBytes)