I work at a University that is a member of InCommon. One of the benefits of joining InCommon is getting access to an unlimited number of TLS (SSL) certificates (including EV, client, and code-signing certs). I recently decided that, instead of a traditional RSA cert, I wanted to get an ECC certificate. In this post, I explain how to use OpenSSL to generate an ECC certificate request, in a way that InCommon (and COMODO) will accept.
There are a number of reasons why I wanted to do this: ECC is faster to work with (because key sizes are smaller), and I did not need any older browsers. There is a valid concern that, as quantum computers become more powerful, ECC crypto will be broken. To respond to that, I plan on using the P-384 curve, in line with the NSA’s current guidance (see the CNSA Suite and Quantum Computing FAQ). And regardless of your opinions of NSA recommendations, InCommon only issues certs for keys on the P-256, P-384, and P-521 curves (so Curve25519 et al is not an option right now).
The process for generating a CSR with an ECC is a little different than the process for generating a CSR with an RSA key. With an RSA key, everything can be accomplished with one command, like so…
openssl req -new -newkey rsa:3072 -nodes -keyout key.pem -out csr.pem
With ECC, you have to generate the private key first, and then generate the CSR. You have to do this because, unlike with RSA, ECC has a ton of different curves. This is similar to working with Diffie-Hellman: When you configure Diffie-Hellman, you have to either generate your own parameters (a prime number and a generator); or you had to choose from existing parameters (known as groups), such as those in RFC 3526 (which is where “group 1” and “group 14” come from).
With ECC, there are even more parameters. There are several different forms of curves, and different primes to use (OpenSSL 1.0.2g lists 81 curves to choose from). Luckily, since we’re restricted to only thee curves, I don’t have to choose!
Now that I’ve got the curve to use, I need to generate a private key. With OpenSSL, EC key generation is handled by the command that manipulates EC parameters:
openssl ecparam -genkey -name P-384 -out key.pem
Compared to generating an RSA key, this will run very quickly, partially because we are only generating a 384-bit key, and also because the key is essentially just a random number (instead of a random prime). If you want to use a bigger key, you can use P-521
(just put that in place of P-384
). The original P-256
curve is also available.
(By the way, if you want to see the random key that was generated, you need to run openssl ec -noout -text
. Running openssl ecparam -noout -text
will only show you the curve parameters, which will be the same for both keys.)
Now that you have the private key, you can generate the CSR. The command here is the same command that you use whenever you want to make a CSR off of an existing key:
openssl req -new -key key.pem -out csr.pem
If you look at the generated CSR in text format, you’ll see an EC key being used:
openssl req -noout -text -in csr.pem
...
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (384 bit)
pub:
04:6f:9a:c8:fc:6f:c4:a0:c4:b9:68:c6:c9:fe:06:
69:e3:d7:c1:15:23:0f:fd:05:57:20:cc:0b:1d:41:
f2:47:b3:7c:69:7c:9f:5e:20:9a:eb:fc:d1:06:a0:
2d:b6:48:9c:ca:0e:5f:52:7a:96:7b:a4:ab:22:60:
a6:5d:31:8a:7e:c2:79:ed:6c:a7:f5:7a:6b:c8:92:
94:22:05:60:f1:c2:ed:7b:da:33:27:f0:e1:ff:b7:
b5:51:fb:6e:8c:b0:05
ASN1 OID: secp384r1
NIST CURVE: P-384
You’ll also see that the key has been signed with an ECDSA signature (instead of an RSA signature).
That’s it! The submission process to InCommon is exactly the same, and the cert you’ll get uses the same intermediates as an RSA cert.
Oh, by the way… If you are running CentOS/RHEL older than 7, Debian older than 9 (that is, older than Stretch), or Ubuntu older than 16.04 LTS, then your OpenSSL might only know about the P-256 curve (and it will be called prime256v1
). If you want to use one of the other curves, you can get the curve parameters from another system, and give them to the openssl ecparam
command, like so:
cat <<EOF >P-384.pem
-----BEGIN EC PARAMETERS-----
BgUrgQQAIg==
-----END EC PARAMETERS-----
EOF
openssl ecparam -genkey -in P-384.pem -out key.pem
Good Luck!