Generate self-signed TLS certificates – ECDSA edition

TL;DR:

openssl ecparam -name secp384r1 -genkey -noout -out server.key
openssl req -new -x509 -key server.key -out server.crt -days 730

There’s also information on generating self-signed multi domain or subject alternative name (SAN) certificates below.

Explanation

First line generates an eliptic curve key, using the secp384r1 curve and writes it to server.key. Second line generates a self-signed public certificate valid for two years, based on that key.

openssl ecparam -name secp384r1 -genkey -noout -out server.key

Parameters:

  • -name secp384r1 : The eliptic curve to use. Wikipedia has a table showing the level of support for different eliptic curves in common libraries. However, using anything other than secp256r1 or secp384r1 will cause some browsers to block access.
  • -genkey : Ask for a key to be generated.
  • -noout : Inhibits the output of the encoded version of the parameters. In the somewhat opposite corner, there’s -param_enc explicit, which will store the EC parameters with the key. That makes it possible for systems that do not know the details of the named curve (secp384r1 in this case) to still use it.
  • -out server.key : The file to store the key in
openssl req -new -x509 -key server.key -out server.crt -days 730

Parameters:

  • -new : New certificate request. Will prompt user for the value of fields in the request, based on OpenSSL config file, if any.
  • -x509 : Generate a self-signed certificate. Omitted if the certificate will be signed by a CA
  • -key server.key : Private key used to generate the certificate
  • -out server.crt : File to store the certificate in
  • -days 730 : Certificate validity. Omitted if the certificate will be signed by a CA

Self-signed SAN (multi-domain) certificates

Generating a SAN certificate is done on the signing request. Using OpenSSL, either create a new file or copy & tweak the default OpenSSL config to have the following section or settings:

[ req ]
req_extensions = v3_req # The extensions to add to a certificate request
distinguished_name  = req_distinguished_name

[ v3_req ]
basicConstraints = CA:TRUE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment

subjectAltName = @alt_names

[ alt_names ]
DNS.1 = *.domain.name
DNS.2 = subdomain.domain.name
DNS.3 = *.subdomain.domain.name

[ req_distinguished_name ]
countryName             = Country Name (2 letter code)
countryName_default     = RO
countryName_min         = 2
countryName_max         = 2

stateOrProvinceName     = State or Province Name (full name)
stateOrProvinceName_default = 

localityName            = Locality Name (eg, city)
localityName_default    = 

0.organizationName      = Organization Name (eg, company)
0.organizationName_default = neant

organizationalUnitName  = Organizational Unit Name (eg, section)
organizationalUnitName_default  =

commonName              = Common Name
commonName_default      = neant.ro
commonName_max          = 64

emailAddress            = Email
emailAddress_default    = spamtrap@neant.ro
emailAddress_max        = 64

The marked lines are just a bonus, having those in simply provides some defaults for the questions asked when generating the signature request.

Assuming a file with the above contents saved under the name crt.conf, the following commands will generate first the private key, then the public certificate valid for three years:

openssl ecparam -name secp384r1 -genkey -noout -out server.key
openssl req -new -x509 -key server.key -out server.crt -days 1095 -extensions v3_req -config crt.cnf

Bonus: Mozilla’s SSL config generator for various web servers.