(updated: Dec 2021)
There are several very good articles about hardening OpenSSL ciphers. Over the years I’ve combined lessons learned from others, my own research of standards and best practices, and my own real-life experiences to come up with the OpenSSL cipher string that I’ve found works best. My goal with this string is to provide the best security while minimizing the number of ciphers to maximize handshake performance.
Only TLS1.2 and TLS1.3 with only ECDHE and primarily AES ciphers in GCM mode. A CBC cipher is included and only necessary to support Microsoft’s legacy browser (Internet Explorer). CBC will show up as weak on Qualys’ SSL Server Test but the weakness does not actually exist unless certain Poodle vulnerabilities also exist; so make sure to keep your server software up to date. I also include the ChaCha20-Poly1305 cipher for supported browsers on mobile devices and other systems that do not have hardware acceleration.
You can test is on your OpenSSL installation
openssl ciphers -v 'ECDH+CHACHA20:ECDH+AESGCM+AES128:ECDH+AESGCM:ECDH+AES128:ECDH+AES256:!aNULL:!SHA1:!AESCCM'
It should result in the following cipher suites in the following order. You notice that the TLSv1.3 ciphers (the first three) do not follow the priority we defined to put AES128 above AES256.
TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256 TLS_AES_128_GCM_SHA256 ECDHE-ECDSA-CHACHA20-POLY1305 ECDHE-RSA-CHACHA20-POLY1305 ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-ECDSA-AES256-SHA384 ECDHE-RSA-AES256-SHA384
- AESGCM ciphers are normally preferred over everything else.
- CHACHA20 is preferred to AESGCM on browsers that support it. Without this top preference, the systems that would benefit most (mobile devices) would not normally use it.
- AES-128 is preferred to AES-256. AES-256 provides little improvement to security, while AES-128 is faster making it less taxing in virtual server environments and more resistant to timing attacks.
- CCM ciphers are secure, but very poor performers and not widely used.
- SHA1 is vulnerable to attacks, so no SHA1 based ciphers
Apache has a separate config entry for TLSv1.3 cipher suite order.
SSLEngine on SSLProtocol -All +TLSv1.2 +TLSv1.3 SSLCipherSuite ECDH+CHACHA20:ECDH+AESGCM+AES128:ECDH+AESGCM:ECDH+AES128:ECDH+AES256:!aNULL:!SHA1:!AESCCM SSLCipherSuite TLSv1.3 TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384 SSLHonorCipherOrder On
Nginx also has a separate config entry for TLSv1.3 cipher suite order.
ssl_prefer_server_ciphers On; ssl_protocols TLSv1.2 TLSv1.3; ssl_conf_command Ciphersuites TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384; ssl_ciphers ECDH+CHACHA20:ECDH+AESGCM+AES128:ECDH+AESGCM:ECDH+AES128:ECDH+AES256:!aNULL:!SHA1:!AESCCM;
more to come…