Converting PHP cURL SSL / TLS cipher names
First published on April 9, 2016
Web developers have started to pay more attention to secure connections due to vulnerabilities such as POODLE and the general push for HTTPS everywhere.
Some aspects of SSL / TLS are quite complex and generally not well documented for the level that most web developers work at. The issue of ciphers is one of the challenges. There is a long list of possible ciphers, and you might find yourself maintaining a limited list of ciphers that your application supports. One of the problems is that the cipher names are not the same across technologies.
If you are making PHP cURL calls, you can limit the supported ciphers using the CURLOPT_SSL_CIPHER_LIST option. However, if you want to support the cipher TLS_RSA_WITH_AES_256_CBC_SHA for example, you cannot pass PHP (or cURL directly) that identifier — it will complain that no such cipher exists. If you inspect the results of the function openssl_get_cipher_methods, you will find identifiers such as rsa_aes_256_sha, which happens to map to TLS_RSA_WITH_AES_256_CBC_SHA.
In order to find cURL’s mapping of cipher names, you have to inspect its source code! There, you will find the complete mapping, with entries such as this:
{"rsa_aes_256_sha", TLS_RSA_WITH_AES_256_CBC_SHA}
Thus, you can set the cURL cipher list in your PHP call like this:
curl_setopt_array( $curl, array( CURLOPT_SSL_CIPHER_LIST => 'rsa_aes_256_sha' ) );
(Bonus tip: you can use cURL on the command line for quicker testing: curl -I https://site.com –ciphers “rsa_aes_256_sha”)
Lastly, it is important to note whether your server is using mod_ssl or mod_nss. If you want to support multiple ciphers, the PHP documentation says to separate them with colons. However, it does not state that with mod_nss the separator is a comma!