How to optimize and tune server ssl certificate configuration

The main objective of the article it to help IT Specialists

  1. How to prepare our certificate:

most of certificate content a private key, the main certificate of the server and intermediate once. (the root certificates of certificate authority are not include in our configuration because they are already present in most browsers.)

  1. 1 Prepare our certificate request

it doesn’t matter for which server we prepare our certificate (windows or *nix) but the instruction is the same and we can find a thousand of sites one how to do it in the write way, but for our case we will use a Unix method in our article in order to understand the full steps.

Create the server’s private key (certificate)

sudo openssl genrsa -des3 -out myblog.key 2048

Create a certificate signing request

sudo openssl req -new -key myblog.key -out myblog.csr

“it’s recommended today to use 2048 bit encryption in stead of 1024 bit which is by default proposed by the system”

“it’s also recommended to use SHA-256 (SHA-2) cryptographic hashing algorithm instead on SHA-1

  1. 2 Prepare the received certificate and the intermediate one from certificate authority

most error in Chain issues are related to the order of the certificates. Create a file called myblog.crt and copy the content of the server certificate received by mail after that, you can add in the end of the file the intermadiat-1, intermadiate-2 certificate until the root certificate in the end (which is not needed in most of case)

cert-chain

finally we have two files: myblog.key and myblog.crt which will be used in order configuration

remark: Most Certificate Authorities (CAs) issue certificates in PEM format. PEM certificates typically have extensions like .pem, .crt, .cer, and .key.

  1. 3 Remove the paraphrase password in our myblog.key

Some servers don’t have a possibility to configure the paraphrase password in order to start-up, that’s why we will remove it (if needed).

sudo cp myblog.key myblog.key.orig
sudo openssl rsa -in myblog.key.orig -out myblog.key

2. Disable insecure protocols SSLv2 and SSLv3

most of IT specialists don’t pay attention on protocols used by their server  by ignorance or simply do not want to know.

in the config file of the server or in the registry of  microsoft windows, we need to disable them to avoid an attacker to force a connection to use SSLv3 and therefore disable forward secrecy. how-to on *nix

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

3. Disable the exploiting of Poodle and TLS-FALLBACK-SCSV

This is automatically enabled if you upgrade OpenSSL to the following versions:

  • OpenSSL 1.0.1 has TLSFALLBACKSCSV in 1.0.1j and higher.
  • OpenSSL 1.0.0 has TLSFALLBACKSCSV in 1.0.0o and higher.
  • OpenSSL 0.9.8 has TLSFALLBACKSCSV in 0.9.8zc and higher.

remark: it’s not the case on microsoft windows.

4. Using the right Cipher Suite

The recommended cipher suite for backwards compatibility (IE6/WinXP):

ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";

remark: for microsoft windows users, they are adjust the cipher suite in the registry

5. Allow the server cipher suite as preference

When choosing a cipher during an SSLv3 or TLSv1 handshake, normally the client’s preference is used

ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;

6. Forward Secrecy & Diffie Hellman Ephemeral Parameters

The concept of forward secrecy is simple: client and server negotiate a key that never hits the wire, and is destroyed at the end of the session. The RSA private from the server is used to sign a Diffie-Hellman key exchange between the client and the server. The pre-master key obtained from the Diffie-Hellman handshake is then used for encryption. Since the pre-master key is specific to a connection between a client and a server, and used only for a limited amount of time, it is called Ephemeral.

With Forward Secrecy, if an attacker gets a hold of the server’s private key, it will not be able to decrypt past communications. The private key is only used to sign the DH handshake, which does not reveal the pre-master key. Diffie-Hellman ensures that the pre-master keys never leave the client and the server, and cannot be intercepted by a MITM.

We need generate a stronger DHE parameter:

openssl dhparam -out dhparam.pem 4096

And then tell the server to use it for DHE key-exchange:

ssl_dhparam /etc/ssl/certs/dhparam.pem;

7. Enable OCSP Stapling

When connecting to a server, clients should verify the validity of the server certificate using either a Certificate Revocation List (CRL), or an Online Certificate Status Protocol (OCSP) record. The problem with CRL is that the lists have grown huge and takes forever to download.

OCSP is much more lightweight, as only one record is retrieved at a time. But the side effect is that OCSP requests must be made to a 3rd party OCSP responder when connecting to a server, which adds latency and potential failures. In fact, the OCSP responders operated by CAs are often so unreliable that browser will fail silently if no response is received in a timely manner. This reduces security, by allowing an attacker to DoS an OCSP responder to disable the validation.

The solution is to allow the server to send its cached OCSP record during the TLS handshake, therefore bypassing the OCSP responder. This mechanism saves a roundtrip between the client and the OCSP responder, and is called OCSP Stapling.

The server will send a cached OCSP response only if the client requests it, by announcing support for the status_request TLS extension in its CLIENT HELLO.

Most servers will cache OCSP response for up to 48 hours. At regular intervals, the server will connect to the OCSP responder of the CA to retrieve a fresh OCSP record. The location of the OCSP responder is taken from the Authority Information Access field of the signed certificate.

ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

8. Enable HTTP Strict Transport Security

add_header Strict-Transport-Security max-age=63072000;

remark: microsoft users can add the header in the configuration of their server

9. Enable HTTP Public Key Pinning Extension (Public-Key-Pins (HPKP) calculator)

SPKI Fingerprint

To get the SPKI fingerprint from a certificate we can use the following OpenSSL command

openssl x509 -noout -in myblog.crt -pubkey | openssl asn1parse -noout -inform pem -out public.key;
openssl dgst -sha256 -binary public.key | openssl enc -base64

in my case the first fingerprint look like:

LteLpibE+9tb58aOEx1Vm5SItDugiRhh6k2C+tNw2CM=

The second fingerprint are taken form the root certificate of our Certificate Authority:

fingerprint

02faf3e291435468607857694df5e45b68851868

Add command in the server block for your HTTPS configuration:

add_header Public-Key-Pins 'pin-sha256="LteLpibE+9tb58aOEx1Vm5SItDugiRhh6k2C+tNw2CM="; pin-sha256="02faf3e291435468607857694df5e45b68851868"; max-age=2592000; includeSubDomains';

10. Security Headers

Security Headers

11. Config Example

server {
       listen 443;
       ssl on;
       ssl_certificate /etc/server/ssl/myblog.crt;
       ssl_certificate_key /etc/serer/ssl/myblog.key;

       error_log /var/log/server/vhost.error.log;

       ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES$

       ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
       ssl_session_cache shared:SSL:10m;

       ssl_stapling on;
       ssl_stapling_verify on;
       resolver 8.8.4.4 8.8.8.8 valid=300s;
       resolver_timeout 10s;

       ssl_prefer_server_ciphers on;
       ssl_dhparam /etc/nginx/ssl/dhparam.pem;

       add_header Strict-Transport-Security max-age=63072000;
       add_header X-Frame-Options DENY;
       add_header X-Content-Type-Options nosniff;

       add_header Public-Key-Pins 'pin-sha256="LteLpibE+9tb58aOEx1Vm5SItDugiRhh6k2C+tNw2CM="; pin-sha256="02faf3e291435468607857694df5e45b68851868"; max-age=2592000; includeSubDomains';

       root /etc/server/html/;
       index index.html index.htm;       
       }

remark: some add_header can be used in microsoft servers.

11. Restart your server

Now use the SSL Labs test to see if you get a nice A. And, of course, have a safe, strong and future proof SSL configuration!