ECDSA Key Pair Generator — P-256 / P-384 / P-521, PEM & JWK
Generate elliptic-curve key pairs (P-256, P-384, P-521) for ECDSA signatures or ECDH key agreement. Exports PKCS#8 / SPKI PEM, JWK, and DER (hex/base64). Perfect for ES256/ES384/ES512 JWTs. 100% local via the Web Crypto API — the private key never leaves your browser.
Last updated:
CommentsPick a curve (P-256 / P-384 / P-521) and click Generate. You get an ECDSA public + private key pair in PEM (SPKI + PKCS#8), JWK, and DER formats — small, fast, and modern. Generated locally via the Web Crypto API.
Key generation uses the native Web Crypto API entirely in your browser. Elliptic-curve keys are dramatically smaller than RSA at equivalent strength (256-bit EC ≈ 3072-bit RSA).
What is ECDSA Key Generator?
An ECDSA Key Generator produces elliptic curve key pairs used for signing (JWT ES256/384/512, SSH keys, TLS 1.3 certificates, cryptocurrency wallets). ECDSA gives the same security as much larger RSA keys: P-256 ≈ RSA-3072 in strength while being ~10x faster to sign and producing ~8x smaller signatures. That's why every modern spec — WebAuthn, TLS 1.3, JWS — prefers EC keys over RSA.
How to generate an ECDSA key pair
- 1Choose a curve. P-256 (also called `prime256v1` / `secp256r1`) is the default — the same curve used by TLS 1.3 and WebAuthn.
- 2P-384 for higher-security workloads (equivalent to RSA-7680). P-521 for maximum strength (equivalent to RSA-15360). P-256 is enough for 99% of use cases.
- 3Click Generate. Signing runs in-browser via `crypto.subtle.generateKey`, so private keys never leave your machine.
- 4Export the private key as SEC1 (`-----BEGIN EC PRIVATE KEY-----`) or PKCS#8 (`-----BEGIN PRIVATE KEY-----`) PEM.
- 5Export the public key as SPKI PEM (`-----BEGIN PUBLIC KEY-----`) or JWK — this is the safe half to publish, e.g. in your JWKS.
Use Cases
Sign JWTs with ES256
ES256 (ECDSA on P-256 with SHA-256) is the recommended algorithm for new JWT-based auth systems — smaller tokens, faster signing, and no risk of RSA algorithm-confusion attacks.
TLS server certificates
Generate a P-256 key, produce a CSR, get it signed by a CA (or use it for a self-signed dev cert). TLS 1.3 with ECDHE + ECDSA is the modern default handshake.
SSH keys
`ssh-keygen -t ecdsa -b 256` produces a P-256 key by default. Use this tool as a browser-side alternative if you don't have OpenSSH handy. Note: for SSH, Ed25519 is often even better — smaller and faster than ECDSA.
Cryptocurrency wallets
Bitcoin and Ethereum use `secp256k1` (a different curve). This tool generates the P-256 family, which is the correct choice for TLS/JWT/WebAuthn. Don't reuse curves across ecosystems.
Code Examples
Equivalent with OpenSSL
# Generate a P-256 private key
openssl ecparam -name prime256v1 -genkey -noout -out ec-private.pem
# Extract the public key
openssl ec -in ec-private.pem -pubout -out ec-public.pemGenerate in Node.js
import { generateKeyPair } from "node:crypto";
import { promisify } from "node:util";
const { publicKey, privateKey } = await promisify(generateKeyPair)("ec", {
namedCurve: "P-256",
publicKeyEncoding: { type: "spki", format: "pem" },
privateKeyEncoding: { type: "pkcs8", format: "pem" },
});Generate in Python (cryptography)
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import serialization
key = ec.generate_private_key(ec.SECP256R1())
pem = key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption(),
)Generate in Go
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
)
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)Key Concepts
- P-256 / P-384 / P-521
- NIST-standardized curves. Also known as prime256v1 / secp256r1, secp384r1, and secp521r1. The number is the bit-length of the underlying prime field, not the security level. Security level is roughly half: P-256 gives ~128-bit security.
- ECDSA vs. EdDSA (Ed25519)
- Ed25519 uses a different curve family (Edwards curves) and is generally preferred where supported — deterministic signatures (no RNG-failure risk), constant-time by design, smaller keys (32 bytes). JWT doesn't standardize Ed25519 for JWS yet (EdDSA is defined in RFC 8037 but adoption is uneven), so ECDSA remains the practical default.
- SEC1 vs. PKCS#8
- SEC1 (`-----BEGIN EC PRIVATE KEY-----`) is the older EC-specific format. PKCS#8 (`-----BEGIN PRIVATE KEY-----`) is the modern generic format and what Web Crypto emits. Convert with `openssl pkcs8 -topk8 -in sec1.pem -out pkcs8.pem -nocrypt`.
- Curve must match algorithm
- ES256 requires exactly P-256, ES384 requires P-384, ES512 requires P-521 (not P-512 — that's a common footgun). Using the wrong curve produces a valid-looking key that any verifier will reject.
Tips & Best Practices
- ▸For new work, prefer ES256 (P-256 + SHA-256) over RS256. Same security, ~8x smaller signatures, ~10x faster signing — no downsides for anyone using a modern library.
- ▸Never sign the same message with the same nonce twice. If your library exposes a `k` value, use RFC 6979 deterministic ECDSA — it removes the RNG requirement entirely.
- ▸Store the private key with `PrivateFormat.PKCS8`. If you must use SEC1 for legacy compatibility, know that PKCS#8 is a strict superset and better in every way.
- ▸When publishing to JWKS, remove `d` (the private component) — leaving it in exposes the entire private key. Our JWKS Generator strips it automatically.
Frequently Asked Questions
Which curve should I pick?
P-256 (also called secp256r1 or prime256v1) is the default — fast, widely supported, and provides 128-bit security. Use it unless you have a specific reason to go higher. P-384 gives 192-bit security and is required by some government profiles (Suite B TOP SECRET). P-521 is rarely necessary and has slightly awkward performance because 521 bits doesn't align to word boundaries.
What's the difference between ECDSA and ECDH?
Same key material, different math. ECDSA uses the key pair to produce and verify signatures. ECDH uses two key pairs (yours + the peer's) to derive a shared secret without ever transmitting it — that shared secret is then usually fed into a KDF (HKDF, PBKDF2) and used as a symmetric key. If you need signing, pick ECDSA; if you need key agreement / hybrid encryption, pick ECDH.
How do these curves map to JWT algorithms?
P-256 → ES256, P-384 → ES384, P-521 → ES512. Most JWT libraries detect this automatically from the JWK 'crv' field. Note that ES256K (secp256k1, Bitcoin's curve) is NOT included here — the Web Crypto API doesn't expose it. If you need secp256k1, use a dedicated library like noble-curves.
Why are EC keys so much shorter than RSA keys?
Because elliptic-curve cryptography reaches equivalent security with far smaller keys. A 256-bit EC key gives roughly the same security as a 3072-bit RSA key. Smaller keys mean smaller signatures, less bandwidth, faster handshakes — which is why TLS, SSH, and modern JWTs increasingly default to EC.
Is my private key sent anywhere?
No. crypto.subtle.generateKey() runs entirely in your browser. You can verify with DevTools Network panel — Generate produces no network traffic. Once you close the tab, the private key is gone.
Try Next
RSA Key Generator
Generate RSA key pairs (2048, 3072, or 4096 bits) online for OAEP encryption, PSS signing, or RS256 JWTs. Exports PKCS#8 private key + SPKI public key as PEM, JWK, or DER (hex/base64). 100% local — the Web Crypto API runs in your browser, private keys never leave the tab.
Related Tools
HMAC Generator
Compute HMAC signatures with SHA-1, SHA-256, SHA-384, or SHA-512 online. Verify API requests, sign webhooks, and authenticate messages. Free, no signup — signing runs locally via the Web Crypto API, secrets never leave your browser.
JWT Decoder
Decode JSON Web Tokens (JWT) to inspect the header, payload, and signature. Runs entirely in your browser — tokens are never sent to any server.
Hash Generator
Generate MD5, SHA-1, SHA-256, and SHA-512 hashes of any text online. Free, no signup — all hashing runs entirely in your browser via the Web Crypto API, so nothing is uploaded.
HMAC-SHA1
Compute HMAC-SHA1 signatures with any secret key. Outputs hex, base64, and base64url. Still used by OAuth 1.0, AWS S3 signature v2, and some older webhook schemes. 100% local via Web Crypto API.
OTP Generator
Generate time-based one-time passwords (TOTP RFC 6238) from a Base32 secret. Real-time counter with 30-second expiry. Perfect for 2FA testing and authenticator app debugging. 100% local.
AES Encrypt / Decrypt
Encrypt and decrypt text with AES (128 / 192 / 256, GCM authenticated or CBC legacy) using a password. PBKDF2 key derivation with 200,000 iterations. 100% local — the Web Crypto API runs entirely in your browser.