Keypair Generator (RSA, EC, Ed25519)
Generate an RSA, ECDSA, ECDH, Ed25519 or X25519 keypair in your browser and export it as PKCS#8 and SPKI PEM or as JWK.
How to use
- Choose the algorithm. ECDSA on P-256 is a good default; Ed25519 if the other end supports it; RSA when something requires it.
- For RSA, set the modulus length, the hash and whether the key is for signing or for OAEP encryption.
- Press generate and copy what you need — the public SPKI PEM to hand out, the private PKCS#8 PEM or JWK to keep.
About this tool
ShowHide
Pick an algorithm, press the button, and get a fresh keypair in the four shapes tooling actually asks for: the private key as a PKCS#8 PEM, the public key as an SPKI PEM, and both as JWK. Generation uses the browser's own WebCrypto, so the private key is created in the page and never crosses the network — which also means it is gone the moment you close the tab, so copy it before you leave.
A detail that surprises people: for RSA, the exported key does not record what you intended to do with it. Choosing PKCS#1 v1.5 signing, PSS signing or OAEP encryption changes which WebCrypto algorithm generates the key, but all three export with the rsaEncryption object identifier, so openssl asn1parse reads them as ordinary RSA keys and the PEM files are structurally identical. The intent survives only in the JWK, which carries alg: "RS256" or alg: "PS256" as a hint. If you need a key file that pins the padding, that is a property of the certificate or the protocol around it, not of the key.
Which algorithm to reach for is mostly a question of what the other end accepts. Ed25519 gives you a 32-byte public key, fast signatures and no parameters to get wrong, which is why SSH and modern protocols prefer it — but browser support arrived at different times, so this reports plainly when your browser cannot generate one rather than failing silently. The P-curves are the safe interoperable default, with P-256 sufficient for almost everything. RSA is what you use when something old insists on it, and the cost shows: a 4096-bit key takes seconds to generate where P-256 is instant, and its public key is thirty times larger.
Keep the two halves straight. The SPKI PEM opens with -----BEGIN PUBLIC KEY----- and is the half you hand out; the PKCS#8 PEM opens with -----BEGIN PRIVATE KEY----- and contains the private scalar or the RSA primes. There is no passphrase on the private key here, because WebCrypto's export has no encryption option — if you need one, run the PEM through openssl pkcs8 -topk8 -v2 aes-256-cbc afterwards.
Frequently asked questions
Why do the PKCS#1 and PSS keys look identical?
Because they are, as files. WebCrypto exports every RSA key with the rsaEncryption algorithm identifier regardless of which padding you asked for, so the PEM carries no record of the intended scheme — openssl asn1parse shows the same OID for both. Only the JWK differs, where the alg field says RS256 or PS256. The padding is decided by whatever verifies the signature, not by the key.
Is the private key safe to generate here?
It is generated by the browser and never sent anywhere, which is why this page works offline. What it is not is a substitute for a key you intend to protect seriously: the value sits in a browser tab, passes through your clipboard, and has no passphrase. For a throwaway test key or a JWT signing key you are about to put in a secret manager, that is fine. For a long-lived root, generate it on the machine that will hold it.
How do I put a passphrase on the private key?
Not here — WebCrypto has no encrypted-export option, so a PKCS#8 PEM from this page is always unencrypted. Run it through openssl afterwards: openssl pkcs8 -topk8 -v2 aes-256-cbc -in key.pem -out key.enc.pem. That wraps the same key in PKCS#8 encrypted form, which is what most servers expect when they prompt for a password.
Why can I not generate Ed25519?
Because your browser does not implement it yet. Ed25519 and X25519 were specified for WebCrypto long after the P-curves and shipped at different times across engines, so a browser can be current and still refuse. The tool reports that case explicitly instead of showing an empty result; P-256 is the interoperable fallback.
Can I use this to make an SSH key?
For Ed25519 and RSA the key material is right, but the format is not: OpenSSH wants its own -----BEGIN OPENSSH PRIVATE KEY----- container for private keys and a single-line ssh-ed25519 AAAA… form for public ones. Convert with ssh-keygen -i -m PKCS8 -f key.pub for the public half; for the private half it is usually less work to run ssh-keygen -t ed25519 in the first place.
Related tools
JWK to PEM Converter (and back)
Turn a JWK or a whole JWKS into PEM public keys and back, with the RFC 7638 thumbprint for each — computed in your browser.
Developer
Ed25519 Sign & Verify (RFC 8032)
Sign a message with an Ed25519 key or verify a signature in the browser, with the public key derived from the seed and R and S shown.
Developer
SSH Public Key Inspector
Read an SSH public key, authorized_keys or known_hosts line: algorithm, key size, SHA256 and MD5 fingerprints, comment and options.
Developer
HKDF Key Derivation (RFC 5869, extract-expand)
Derive keys with HKDF and see both halves: the PRK from extract, every T block from expand, and the OKM in hex and base64. RFC 5869 cases built in.
Developer
AES-GCM Encrypt / Decrypt (key, nonce, AAD)
Encrypt and decrypt with AES-GCM in your browser: hex key and nonce, optional AAD, selectable tag length, and the ciphertext and tag kept apart.
Developer
PKCS#12 Keystore Inspector
Open a .p12 or .pfx in your browser: MAC and ciphers before the password, then the certificate chain, the private key, and whether they match.
Developer