Chapter 6 ■ tLS/SSL
112
But the behavior of the “safe” script changes considerably if you place it in the role of a client because of the
theory, discussed earlier, that it is really the server that is responsible for deciding how secure the connection should
be, while client authors generally just want things to work if they can possibly do so without completely exposing the
data. Remember that the safe server, when tested earlier, would refuse to speak RC4. Watch what happens when you
instead try the tls_safe.py client with RC4. First, close any server that you already have running and run the test
script as the server, setting the cipher with -C.
$ /usr/bin/python3.4 test_tls.py -C 'RC4' -s localhost.pem '' 1060
Interface where we are listening.... ('', 1060)
Then go to another terminal window and try connecting with the safe_tls.py script that uses Python 3.4’s
default context.
$ /usr/bin/python3.4 safe_tls.py -a ca.crt localhost 1060
Even using the safe default context, the connection happens successfully! Over in the server window, you will
see that RC4 was indeed chosen as the streaming cipher. However, by providing the –C option with different strings,
you can confirm that RC4 is as low as the safe script is willing to stoop. Ciphers or algorithms like MD5 will be rejected
outright as not even reasonable for a client that is trying to ensure maximum compatibility with any server with which
the user might want to communicate.
Consult the ssl module documentation and then the official OpenSSL documentation to learn more about
crafting a custom choice of protocol and cipher. A helpful tool as you experiment is the native OpenSSL command
line, if your system includes it, which can print out all of the ciphers that match a particular cipher string—the same
string that you might provide to Listing 6-3 with its –C option or specify with the set_cipher() method in your
own code. Plus, the command line will let you test how various cipher rules change their effect through time as
cryptography continues to advance and OpenSSL on your system is upgraded. At the moment, to show one example
of its use, here are the ciphers that match the ECDH+AES128 cipher string when it is used here on the Ubuntu laptop on
which I am typing this:
$ openssl ciphers -v 'ECDH+AES128'
ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(128) Mac=AEAD
ECDHE-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(128) Mac=AEAD
ECDHE-RSA-AES128-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(128) Mac=SHA256
ECDHE-ECDSA-AES128-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(128) Mac=SHA256
ECDHE-RSA-AES128-SHA SSLv3 Kx=ECDH Au=RSA Enc=AES(128) Mac=SHA1
ECDHE-ECDSA-AES128-SHA SSLv3 Kx=ECDH Au=ECDSA Enc=AES(128) Mac=SHA1
AECDH-AES128-SHA SSLv3 Kx=ECDH Au=None Enc=AES(128) Mac=SHA1
ECDH-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AESGCM(128) Mac=AEAD
ECDH-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AESGCM(128) Mac=AEAD
ECDH-RSA-AES128-SHA256 TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AES(128) Mac=SHA256
ECDH-ECDSA-AES128-SHA256 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AES(128) Mac=SHA256
ECDH-RSA-AES128-SHA SSLv3 Kx=ECDH/RSA Au=ECDH Enc=AES(128) Mac=SHA1
ECDH-ECDSA-AES128-SHA SSLv3 Kx=ECDH/ECDSA Au=ECDH Enc=AES(128) Mac=SHA1