RSA Key Generator
Generate an RSA, EC or Ed25519 keypair in your browser and download it as PKCS#8 and SPKI PEM.
Public half — safe to publish
Public key — SPKI PEM
Nothing generated yet.
Public JWK
Nothing generated yet.
Private half — keep this secret
Private key — PKCS#8 PEM
Nothing generated yet.
Private JWK
Nothing generated yet.
The kid is the RFC 7638 thumbprint of the public JWK. Generating again produces a different key and a different kid.
What this tool does not do
- No certificates and no certificate signing requests.
- No OpenSSH key formats — this page emits PKCS#8 and SPKI PEM.
- No passphrase-encrypted private keys.
- No random passwords, tokens or other secrets.
Press ? for shortcuts · Nothing is kept between visits: no key, no option, no reveal state. Reloading loses the keypair.
Keys are generated here in your browser with Web Crypto. Nothing is uploaded.
Do it offline:$ openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out key.pem
How to use it
- Pick a family. RSA is the safe default for anything old; EC gives you a far smaller key at comparable strength; Ed25519 is the smallest of the three and needs Chrome/Edge 137+, Firefox 130+, Safari 17+.
- Pick the size: 2048, 3072 or 4096 bits for RSA, or P-256, P-384 or P-521 for EC. Ed25519 has exactly one size, so that row disappears.
- Press Generate, or ⌘/Ctrl + Enter. RSA 4096 is the slow row — the cards hold their size and count elapsed milliseconds, because WebCrypto reports no progress a bar could honestly draw.
- Copy or download the public block freely. Reveal the private block deliberately, and treat what you see as live key material from that moment on.
- Take the JWK pair beside the PEM cards if that is what your stack wants — same key, JSON spelling, with an RFC 7638 thumbprint filled in as kid.
Choose RSA 2048, 3072 or 4096, an EC curve, or Ed25519, then press Generate. Your browser's WebCrypto mints the pair and this page armors it into the two blocks openssl and every PKI library read: a PKCS#8 private key and a SubjectPublicKeyInfo public key. The private half stays masked until you ask for it, and no key is stored here or sent anywhere.
Examples
RSA · 2048 → public key, SPKI PEM-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuMOIWxnA1yqCPW9gLrV6
tebKgRVoZqF82E0+nmZJfvw7w6ASIAk11Ge95JQq2psIUxfTXjDEqkamiS4ntonb
mTZuojRc7EtDii2vUlIX12FssV1J6PRjNMwk7DgMQ7YC7p2g9GdhCjBV7H2clDi6
lcHQjwjmlkG1/m7+sT0hIe/dKAIo5Lf8GTtFHHLxBfHlA7Nab4zQ41Y8c7cn4CiL
w69uyuCqBYtsYTi78iJGpiuOneAOnO1FXECIoBo6gYKDw6aZL4sSyQXuzVUAzP5y
kNYxue9Dm6znjoG0k8Ph2APBi23wVdrPCc5pQs7h4cyGMr3dqaVr9D7L00oigT3I
rwIDAQAB
-----END PUBLIC KEY-----The public card, exactly as it prints: 64-column base64 between two fences. Its private partner is a 26-line PKCS#8 block behind the reveal and is not shown here. Every key is random, so the test re-reads these bytes rather than expecting them again.
Ed25519 → both halves, and a 48-byte private key-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIO6QDLcqEPZtAbgCFn1qDI/D4cxMzYdsImqVS88di773
-----END PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEATlP5WLLfIQNNwYFivixJSB2q9xObvih54kTZ1ZiHi00=
-----END PUBLIC KEY-----Both blocks fit on one line each: the DER inside them is 48 and 44 bytes, where the public half of an RSA 2048 key alone takes 294. This sample is spent — it was generated to be printed and belongs to nobody.
Ed25519 on a browser that has none (edge case)No key was generated: this browser's WebCrypto has no Ed25519 — Unrecognized algorithm name. It needs Chrome/Edge 137+, Firefox 130+, Safari 17+. RSA and EC still work here.The option is offered, refused with a reason, and never silently swapped for another algorithm. The clause after the dash is whatever the platform itself said — this one was captured by asking a real WebCrypto for an algorithm it does not implement, and an older browser words it differently.
Every example on this page is executed against the same engine that powers the tool, on every build.
Gotchas worth knowing
The exponent is 65537 and is not a setting
Every RSA key here uses the public exponent 65537 (0x010001, three bytes). WebCrypto accepts other values; nothing downstream expects them, so the choice is not offered.
P-521 is included, and its numbers are 66 bytes
The largest curve is offered alongside P-256 and P-384. Its private scalar and each coordinate run 66 bytes, an odd width that surprises consumers written for 32-byte values.
Ed25519 needs a recent browser
Ed25519 arrived in Web Crypto after the other families: Chrome and Edge 137, Firefox 130, Safari 17. Below that floor the row refuses with the platform's reason instead of quietly producing something else.
These PEMs are not tied to one operation
PKCS#8 and SubjectPublicKeyInfo carry the key and its algorithm, not a purpose. The same RSA block can sign with PKCS#1 v1.5, sign with PSS, or encrypt with OAEP, so nothing here is labelled a signing key.
The JWK cards drop ext and key_ops
Those two members describe the handle this browser holds, not the key, so they are left out of both JWKs and a note says which ones went. The kid beside them is the RFC 7638 §3.1 thumbprint, computed from the key itself.
A new press means a new key, and no way back
There is no seed box and no history: pressing Generate replaces what is on screen with unrelated material. Download or copy before you move on: a shared link carries your family, your size and the JWK toggle, and no key at all.
Common errors
No key was generated: family "EC", modulusLength 2048 is not one of this generator's rows. Accepted rows are RSA 2048, RSA 3072, RSA 4096, EC P-256, EC P-384, EC P-521, Ed25519. RSA takes a modulus length, EC takes a curve, and Ed25519 takes neither.- A curve family with a bit length attached — the pairing you get by hand-editing a shared link. The refusal prints the rows that do exist and generates nothing in the meantime.
No key was generated: this browser's WebCrypto has no Ed25519 — Unrecognized algorithm name. It needs Chrome/Edge 137+, Firefox 130+, Safari 17+. RSA and EC still work here.- Seen on browsers below the floor. The reason after the dash comes from the platform, so the wording varies while the code and the floor do not.
No key was generated: WebCrypto is unavailable here (crypto.subtle is missing). Key generation needs a secure context — HTTPS, or localhost during development.- Browsers withhold crypto.subtle outside a secure context, so on plain http away from localhost there is no generator to call and the form says so rather than failing quietly.
FAQ
Can I use this key with ssh?
Not as it stands. OpenSSH wants its own container for the private half and a single-line authorized_keys entry for the public half; both are produced by the SSH key generator page. This page emits the PKCS#8 and SubjectPublicKeyInfo blocks that openssl, TLS stacks and PKI libraries read.
Does the private key ever leave my device?
No. It is created by WebCrypto in this tab, held in memory, and written nowhere: no upload, no third-party origin, no storage that survives the tab. The test suite reads the engine, the island and the worker and fails if a request call appears in any of them.
Can I get a certificate, a CSR or a passphrase on the key?
None of the three, here. Certificates and certificate signing requests are not built yet, and Web Crypto has no way to write the encryption OpenSSH and openssl use for passphrase-protected private keys. Random strings, passwords and API keys are three separate pages, not this one.
Keyboard shortcuts
- ⌘/Ctrl + Enter
- Generate a new keypair with the current selection
- ⌘/Ctrl + Shift + C
- Copy the focused card, revealed or not
- ? or ⌘/Ctrl + /
- Keyboard shortcuts