2.7 Testing Cipher Suite Configuration
It’s not very likely that you will be spending a lot of time testing cipher suite configuration using OpenSSL on the command line. This is because you can effectively test for only one suite at a time; testing for more than 300 cipher suites that are supported by TLS 1.2 and earlier protocol revisions would take a considerable amount of time. This is a perfect opportunity to use those handy tools that automate the process.
Still, there will be times when you will need to probe servers to determine if they support a particular suite or a cryptographic primitive, or if the preference is correctly configured.
The introduction of TLS 1.3 made testing in this area slightly more complicated, but it’s still manageable. Because of the differences between this protocol version and all other revisions, it’s usually best to split your tests into two groups. When testing TLS 1.3, always use the -ciphersuites
switch in combination with -tls1_3
. The usual approach is to specify only one suite to determine if it’s supported:
$ echo | openssl s_client -connect www.hardenize.com:443 -tls1_3 -ciphersuites TLS_AES_128_GCM_SHA256 2>/dev/null| grep New
New, TLSv1.3, Cipher is TLS_AES_128_GCM_SHA256
The output will naturally be different if you pick a suite that is not supported:
$ echo | openssl s_client -connect www.hardenize.com:443 -tls1_3 -ciphersuites TLS_AES_128_CCM_SHA256 2>/dev/null | grep New
New, (NONE), Cipher is (NONE)
When you’re testing the configuration of TLS 1.2 and earlier protocol versions, use the -cipher
switch in combination with -no_tls1_3
(assuming you’re using a version of OpenSSL that supports TLS 1.3):
$ echo | openssl s_client -connect www.hardenize.com:443 -no_tls1_3 -cipher AESGCM 2>/dev/null | grep New
New, TLSv1.2, Cipher is ECDHE-ECDSA-AES128-GCM-SHA256
As you can see in the previous example, when testing TLS 1.2 and earlier you don’t have to specify only one cipher suite, but in that case you will need to observe what has been negotiated. If you want to probe further, you can always tweak the command line to remove the previously negotiated suite:
$ echo | openssl s_client -connect www.hardenize.com:443 -no_tls1_3 -cipher 'AESGCM:!ECDHE-ECDSA-AES128-GCM-SHA256' 2>/dev/null | grep New
New, TLSv1.2, Cipher is ECDHE-ECDSA-AES256-GCM-SHA384
Even though you won’t be testing for a great many suites manually, there is a quick way to determine if a particular server supports any of the many bad cryptographic primitives. To do this, use your old OpenSSL version and list all the bad cipher suite keywords, like this:
$ echo | openssl s_client -connect example.com:443 -cipher '3DES DES RC2 RC4 IDEA SEED CAMELLIA MD5 aNULL eNULL EXPORT LOW' 2>/dev/null | grep New
New, TLSv1/SSLv3, Cipher is DHE-RSA-CAMELLIA256-SHA
Another good test is to see if a server supports the RSA key exchange that doesn’t support forward secrecy:
$ echo | /opt/openssl-1.0.2g/bin/openssl s_client -connect example.com:443 -cipher kRSA 2>/dev/null | grep New
New, TLSv1/SSLv3, Cipher is AES128-GCM-SHA256
Ideally, you’d get a handshake failure here, but it’s not terrible if you don’t, provided the server uses the RSA key exchange only as a matter of last resort. You can check this by offering suites with forward secrecy as your least preferred option:
$ echo | /opt/openssl-1.0.2g/bin/openssl s_client -connect example.com:443 -cipher 'DHE ECDHE kRSA +kECDHE +kDHE' 2>/dev/null | grep New
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256