Skip to content
AZ Tools

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

  1. Choose the algorithm. ECDSA on P-256 is a good default; Ed25519 if the other end supports it; RSA when something requires it.
  2. For RSA, set the modulus length, the hash and whether the key is for signing or for OAEP encryption.
  3. 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

Show

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