2

我正在尝试编写一个 python(或 Java)程序,该程序与网站建立 https 连接,然后返回 https 连接的属性。我一直在使用 python 的 ssl ( http://docs.python.org/2/library/ssl.html ),特别是 .cipher() 方法。我对输出的主要问题是它不是很具体:

('RC4-SHA', 'TLSv1/SSLv3', 128)

这是 www.amazon.com 的输出。但是当我进入浏览器并手动检查连接时,我真的可以看到它是:RC4 与 SHA1 消息身份验证、RSA 密钥交换和 TLS v1.0。事实上,.cipher() 方法为 TLS 版本 1.0、1.1 和 1.2 输出 TLSv1/SSLv3,并为 SHA1 和 SHA256 输出 SHA。

是否有任何 Python(或 Java)API 可以为我提供有关 https 连接的更多信息?

4

1 回答 1

4

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 包装器和其他 SSLTLS模块,或者你可以ctypes自己喜欢。)

于 2013-04-04T23:59:18.367 回答