ecdsa.com

Generate a key pair · OpenSSL

How to generate an ECDSA key pair with OpenSSL

openssl genpkey is the modern command to generate an ECDSA key: it writes a PKCS#8 private key that every current stack loads directly. The older ecparam form still appears in tutorials and produces a different container — worth recognizing on sight.

Tested with OpenSSL 3.6.

Same recipe in:Node.jsPythonGoOpenSSLWebCrypto
generate a P-256 key pair (modern form)
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out key.pem
openssl pkey -in key.pem -pubout -out pub.pem
openssl pkey -in key.pem -text -noout # inspect curve and key material
the legacy form you will meet in older docs
# SEC1 container: "BEGIN EC PRIVATE KEY"
openssl ecparam -name prime256v1 -genkey -noout -out legacy.pem
 
# convert legacy SEC1 → modern PKCS#8
openssl pkey -in legacy.pem -out key-pkcs8.pem
encrypted private key
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 \
-aes-256-cbc -out key-enc.pem # prompts for a passphrase

How it works

  1. genpkey writes PKCS#8 (BEGIN PRIVATE KEY) — the format Node.js, Go, Python and WebCrypto all read without conversion.
  2. -pkeyopt ec_paramgen_curve: accepts P-256, P-384, P-521 and secp256k1; ecparam -name wants the OpenSSL spelling prime256v1.
  3. pkey -pubout derives the SPKI public key — the private key file contains everything needed.
  4. openssl ecparam -list_curves prints every curve name this build supports — the quickest answer to "what do I type after ec_paramgen_curve:".

Gotchas

  • ecparam -genkey without -noout prepends an EC PARAMETERS block to the file — some parsers choke on it. The modern genpkey form avoids the issue entirely.
  • BEGIN EC PRIVATE KEY (SEC1) and BEGIN PRIVATE KEY (PKCS#8) are different containers for the same key. WebCrypto accepts only PKCS#8 — convert with openssl pkey rather than editing headers.
  • P-256 has three names that all mean the same curve: P-256 (NIST), prime256v1 (OpenSSL/X9.62), secp256r1 (SEC). But secp256k1 is a genuinely different curve, not a fourth alias.

Related recipes