The Python ssl
module is just a wrapper around OpenSSL, and it can't provide any more information than the library provides. But really, I don't think you're missing any information. It is being specific. You're just always getting TLSv1.0 and SHA1.
First, TLSv1/SSLv3
in OpenSSL 0.9 means TLSv1.0. It cannot mean 1.1 or 1.2, because OpenSSL 0.9 does not support those protocols. (And you are probably using OpenSSL 0.9. For example, the 3.3.0 64-bit Mac binary installer I just got off Python.org uses 0.9.8r.) You can check this from Python with ssl.OPENSSL_VERSION
.
Second, RC4-SHA
means SHA1, not SHA256. RC4-SHA
is just the OpenSSL name for the TLSv1.0 cipher suite TLS_RSA_WITH_RC4_128_SHA
. That's a complete specification of the cipher; there are different ciphers with SHA256
on the end of their names. You can see the list of cipher suites specified in RFC 2246 and its addenda for TLS 1.0 (it's RFC4346 for 1.1 and RFC 5246 for 1.2). I don't think the mapping from OpenSSL names to RFC names is specified anywhere except inside the code, but if you have the command-line OpenSSL tools you can type openssl ciphers
to dump out the list of OpenSSL names for all suggested cipher suites it will send, and then you can match them up to the values sent in the handshake. (To see the handshake, openssl s_client -connect www.amazon.com:443 -msg
, or try -debug
or other flags instead of/in addition to -msg
.)
So, why does your browser show TLSv1.2 or SHA256 for some of those same sites? Because your browser has a completely different SSL library (or a newer OpenSSL), and therefore does a completely different handshake with the server, and ends up agreeing on different cipher suites, and therefore it reports different information.
So, it's not that Python is negotiating TLSv1.2 or SHA256 and just hiding that from you; it's negotiating TLSv1.0 and SHA1 with the same server, and telling you what it's done.
If you want to use a different library that can handle things OpenSSL 0.9 can't, there are lots of choices. If you install OpenSSL 1.0.1 or later and build PyOpenSSL against that, I believe (I haven't tested) that you should be able to negotiate newer protocols and ciphers and find out that you've done so. It might even rework if you rebuild Python, or the standalone ssl
module, against it. (If neither of those works, there are a zillion more OpenSSL wrappers and other SSL or TLS modules at PyPI, or you can just ctypes
your favorite yourself.)
ssl
module? – abarnert