Generating CA-signed Elliptic Curve certs with OpenSSL

Elliptic-Curve Cryptography keypairs are more compact than RSA keypairs and thus allow better security without sacrificing performance. A 256 bit ECC key is equivalent to RSA 3072 bit keys (which are 50% longer, thus more secure than the 2048 bit keys commonly used today).

Generate an ECC self-signed Certificate Authority

For best portability, it is recommended to use the P-256 curve (a.k.a. "secp256r1", or "prime256v1" in openssl). The curve name is the only parameter to the ec key type; it defines both the curve characteristics and the key size.

openssl req -x509 -new -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -nodes -text -days 3650 -extensions v3_ca -out root.crt -keyout root.key -subj "/CN=My CA"
echo 00000000 > root.srl

Generate an ECC keypair signed by our CA

Without SAN

In this example the CN (Common Name) is name1, replace as neccessary:

openssl req -new -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -nodes -text -out name1.csr -keyout name1.key -subj "/CN=name1"
openssl x509 -req -CA root.crt -CAkey root.key -days 3650 -extfile /etc/ssl/openssl.cnf -extensions v3_req -in name1.csr -out name1.crt
With SAN

The SAN (Subject Alternative Name) extension is highly recommended even if there's only 1 alternative.

Preparation

Make a shell script:

echo '#!/bin/sh
if [ -z "$1" ]; then echo Usage: $0 name [ name ... ]; exit 1; fi
name=$1; san=DNS:$1; shift; for i in $@; do san=$san,DNS:$i; done
cat <<EOF >ext.tmp
[v3_req]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName=$san
EOF
openssl req -new -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -nodes -text -out $name.csr -keyout $name.key -subj "/CN=$name"
openssl x509 -req -CA root.crt -CAkey root.key -days 3650 -extfile ext.tmp -extensions v3_req -in $name.csr -out $name.crt
rm ext.tmp $name.csr
openssl x509 -text -noout -in $name.crt
' >makecert.sh
chmod +x makecert.sh
Use
./makecert.sh name1

Or with multiple alternative names:

./makecert.sh name1 name2 name3

Et voilĂ !

The next best thing after P-256 and ECDSA is Curve25519 in combination with Edwards 25519, or "ed25519" signature algorithm. It is not just another curve, but a complete replacement of ECDSA. EdDSA does not depend on a PRNG as much as ECDSA does, and is therefore more secure. It is mandatory in TLS v1.3, but browser support is somewhat lacking in comparison to P-256 (as of December 2020). It will be covered in a next post.