Pythonssl
模块只是 OpenSSL 的一个包装器,它不能提供比库提供的更多信息。但实际上,我认为您没有遗漏任何信息。它是具体的。你总是得到 TLSv1.0 和 SHA1。
首先,TLSv1/SSLv3
在 OpenSSL 0.9 中意味着 TLSv1.0。它不能表示 1.1 或 1.2,因为 OpenSSL 0.9 不支持这些协议。(您可能使用的是 OpenSSL 0.9。例如,我刚从 Python.org 下载的 3.3.0 64 位 Mac 二进制安装程序使用 0.9.8r。)您可以使用ssl.OPENSSL_VERSION
.
其次,RC4-SHA
表示 SHA1,而不是 SHA256。RC4-SHA
只是 TLSv1.0 密码套件的 OpenSSL 名称TLS_RSA_WITH_RC4_128_SHA
。这是密码的完整规范;他们的名字末尾有不同的密码SHA256
。您可以查看RFC 2246中指定的密码套件列表及其 TLS 1.0 的附录(1.1的RFC4346和 1.2 的RFC 5246)。我不认为从 OpenSSL 名称到 RFC 名称的映射是在代码内部以外的任何地方指定的,但是如果您有命令行 OpenSSL 工具,您可以键入openssl ciphers
以转储所有建议的密码套件的 OpenSSL 名称列表,它将发送,然后您可以将它们与握手中发送的值匹配。(要查看握手openssl s_client -connect www.amazon.com:443 -msg
,或尝试-debug
或其他标志而不是/除了-msg
。)
那么,为什么您的浏览器会为其中一些相同的站点显示 TLSv1.2 或 SHA256?因为您的浏览器具有完全不同的 SSL 库(或更新的 OpenSSL),因此与服务器进行完全不同的握手,最终同意不同的密码套件,因此它报告不同的信息。
所以,并不是 Python 正在协商 TLSv1.2 或 SHA256 并且只是对你隐藏它;它正在与同一台服务器协商 TLSv1.0 和 SHA1,并告诉你它做了什么。
如果你想使用一个不同的库来处理 OpenSSL 0.9 不能处理的事情,有很多选择。如果您安装OpenSSL 1.0.1 或更高版本并针对它构建PyOpenSSL,我相信(我尚未测试)您应该能够协商更新的协议和密码,并发现您已经这样做了。如果您ssl
针对它重建 Python 或独立模块,它甚至可能会返工。(如果这些都不起作用,那么 PyPI 上还有无数的OpenSSL 包装器和其他 SSL或TLS模块,或者你可以ctypes
自己喜欢。)