There exist another type of certificate, based on Elliptical Curve cryptography. You may see this referenced as ECC or, for web sites, ECDSA. An ECDSA certificate is smaller than an RSA cert (eg a 256bit ECDSA cert is roughly the equivalent of a 3072bit RSA one). This makes it quicker to send, although at present RSA signatures are quicker to verify than ECDSA.
I use LetsEncrypt for my certificates, although
(for complicated reasons) I don’t use their standard
Instead I use Dehydrated.
I like this client because it just puts the certs into a directory and
then you can do whatever you like with them (in my case I use
to distribute to lots of different endpoints).
The Dehydrated client also supports ECDSA certificates (indeed, in the
current version it defaults to
secp384r1 to generate 384bit certs).
Configuring Dehydrated for both cert types
I want to use both RSA and ECDSA certificates on this site but Dehydrated can only handle one type at a time. Fortunately it has a work around; you can create a second certificate directory and have that override the cert type.
So in my case I configured the app to default to
rsa and then created
% cat domains.txt *.sweharris.org sweharris.org > sweharris *.sweharris.org sweharris.org > sweharris_ecdsa % grep KEY_ALGO config KEY_ALGO=rsa % cat certs/sweharris_ecdsa/config KEY_ALGO="secp384r1"
With this setup when I run the “refresh” command (
dehydrated -c) it
will place the RSA cert in the
sweharris directory and ECDSA cert in
% openssl x509 -noout -text -in certs/sweharris/cert.pem | grep Public.Key.Algo Public Key Algorithm: rsaEncryption % openssl x509 -noout -text -in certs/sweharris_ecdsa/cert.pem | grep Public.Key.Algo Public Key Algorithm: id-ecPublicKey
certs directory we will find four files of interest. These
are always symbolic links to the latest version, so that provides a
consistent name for us to use:
This is the public key for the server certificate
This is the private key for the server.
This file contains the “chaining” certificates needed to generate a chain of trust to the root.
This file contains the chaining certificates and the server public key. Sometimes this can be easier to use.
We’ll see, next, how these files are used.
I have two primary server types in my environment. They’re either based on CentOS 7 or CentOS 8. The configuration is slightly different.
For CentOS 8 it’s pretty simple, we can use the full chain file:
SSLCertificateFile /etc/httpd/conf/sweharris/fullchain.pem SSLCertificateKeyFile /etc/httpd/conf/sweharris/privkey.pem SSLCertificateFile /etc/httpd/conf/sweharris_ecdsa/fullchain.pem SSLCertificateKeyFile /etc/httpd/conf/sweharris_ecdsa/privkey.pem
Now if you try that on CentOS 7 it seems to work, but SSLtest complains about missing chain certificates and small DH key sizes. Not sure why that happens. But fortunately we can use a slightly different path
SSLCertificateFile /etc/httpd/conf/sweharris/cert.pem SSLCertificateKeyFile /etc/httpd/conf/sweharris/privkey.pem SSLCertificateFile /etc/httpd/conf/sweharris_ecdsa/cert.pem SSLCertificateKeyFile /etc/httpd/conf/sweharris_ecdsa/privkey.pem SSLCertificateChainFile /etc/httpd/conf/sweharris/chain.pem
This works because both certs are signed by LetsEncrypt via the same chain (same intermediate, same root). If that wasn’t the case then we’d need to work a little harder to ensure the chain file had everything that was necessary.
The previous cipher list I provided only selected RSA options; after all, why bother with ECDSA options if you don’t have the right certificate? But now we do. As with the RSA certificates there’s a small number that can be considered “strong”. Indeed, we’ll stick with two
There are others which maybe considered (e.g. CHACHA-POLY based), but I don’t believe the oldish versions of openssl on CentOS currently support them.
This results in a cipher suite configuration of:
You may notice that i no longer have
DHE-RSA-AES256-GCM-SHA384 listed as
a cipher, but I still have a couple of CBC based ones there.
The CBC ciphers are still needed because, as we previously saw, older versions of Safari need them, and these old versions don’t work with ECDSA
Safari 6 / iOS 6.0.1 Safari 7 / iOS 7.1 Safari 7 / OS X 10.9 Safari 8 / iOS 8.4 Safari 8 / OS X 10.10
The good news is that we still get an A+ rating! The report also shows the two options for the certificates.
It correctly reports the 6 ciphers as being available
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c) ECDH secp256r1 (eq. 3072 bits RSA) FS 256 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030) ECDH secp256r1 (eq. 3072 bits RSA) FS 256 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b) ECDH secp256r1 (eq. 3072 bits RSA) FS 128 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f) ECDH secp256r1 (eq. 3072 bits RSA) FS 128 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xc028) ECDH secp256r1 (eq. 3072 bits RSA) FS WEAK 256 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027) ECDH secp256r1 (eq. 3072 bits RSA) FS WEAK 128
Of course the two CBC ciphers are still flagged as weak, but we’re aware of this and they’re needed for Safari compatibility.
Digging further into the report I noticed that most of the clients negotiated ECDSA mode. Only a handful did RSA mode!
Chrome 49 / XP SP3 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 Safari 6 / iOS 6.0.1 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 Safari 7 / iOS 7.1 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 Safari 7 / OS X 10.9 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 Safari 8 / iOS 8.4 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 Safari 8 / OS X 10.10 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Literally everything else that SSLtest emulates that can work with with TLS1.2 all negotiated ECDSA. Interestingly “IE 11 / Win Phone 8.1” previously needed a CBC cipher but it can do ECDSA in GCM mode!
Although this doesn’t impact me, in an enterprise environment the support for multiple certificate types may be impacted by middleware boxes such as load balancers that do TLS termination (so they can inspect the traffic and do sticky sessions or similar). It’s not much point in doing ECDSA if other devices can’t support it! Similarly you may need the DHE based ciphers to handle limitations of those devices. But the list provided here should be a good starting point.
This didn’t take too long to figure out, once I stopped fighting the
CentOS 7 build and attempting to use the
fullchain.pem file there.
It’s now possible, even for the relatively old CentOS 7, to support modern ciphers and modern public key cryptography. Every cipher used supports forward secrecy and large key sizes. We just need to be careful about any future CBC Oracle attacks!
Of course ECDSA isn’t resilient against quantum computing attacks, but I really don’t think that’s going to be a practical concern for a long time.
Note the full report includes a
secondary domain (
*.spuddy.org) so doesn’t quite match what I’ve
written. I didn’t include a description of that because it’s unnecessary
complication. In this case a client without SNI (are there any that
also support TLS1.2?) would get a cert for a different virtual host and
so get an error. That’s also not relevant to this post :-)