Python 3.4 - 仅使用TLSv1连接到imap服务器

时间:2014-12-06 01:52:19

标签: python sockets python-3.x ssl imaplib

我尝试在Python 3.4中仅使用TLSv1连接到imap邮件服务器。

经过多次故障排除(大部分都确定邮件服务器只支持TLSv1)后,我发现我可以使用openssl连接到服务器:

openssl s_client -connect mail.calpoly.edu:993 -tls1

以及Python 2.7中的套接字包:

Python 2.7.6 (default, Mar 22 2014, 22:59:56)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import ssl
>>> import socket
>>>
>>> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> ssl_sock = ssl.wrap_socket(sock=sock, ssl_version=ssl.PROTOCOL_TLSv1)
>>> ssl_sock.connect(('mail.calpoly.edu', 993))
>>> ssl_sock
<ssl.SSLSocket object at 0x7fbab6e7aed8>

但是,当我尝试使用Python 3.4进行连接时,我收到握手错误:

Python 3.4.0 (default, Apr 11 2014, 13:05:11) 
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import ssl
>>> import socket
>>> 
>>> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> ssl_sock = ssl.wrap_socket(sock=sock, ssl_version=ssl.PROTOCOL_TLSv1)
>>> ssl_sock.connect(('mail.calpoly.edu', 993))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.4/ssl.py", line 841, in connect
    self._real_connect(addr, False)
  File "/usr/lib/python3.4/ssl.py", line 832, in _real_connect
    self.do_handshake()
  File "/usr/lib/python3.4/ssl.py", line 805, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:598)

似乎Python 3.4尝试使用sslv3,即使我告诉它不要。

有谁知道为什么会这样,以及我如何解决它?

P.S。 - 我将在与服务器连接的代码中使用imaplib。我在这个例子中使用了套接字来强调这似乎只是imaplib包的一个问题。

1 个答案:

答案 0 :(得分:2)

  

...其中大部分确定邮件服务器仅支持TLSv1

这是否意味着服务器会在任何其他握手时呱呱叫?通常,客户端将以它可以使用的最佳协议(如TLSv12)开始,如果服务器不支持它,那么它将只使用较低的协议(在本例中为TLSv1)进行回复。但是,有些服务器刚刚坏掉,或者介于两者之间。

[SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure
....
It seems like Python 3.4 tries to use sslv3 even though I tell it not to.

不一定。 TLS1.0只是SSL3.1,许多TLS处理实际上是使用SSLv3功能完成的。因此,此错误消息可能会令人困惑。

使用some tool查看服务器时,看起来是

  • 将返回&#34;不支持的协议&#34;使用SSL3.0,这很好。
  • 将使用TLS1.1而不是仅使用TLS1.0返回。这意味着服务器或其间的某个中间盒严重受损。
  • 只会接受RC4-MD5作为密码并且在任何其他密码上都会出现问题。这也会让它破裂,因为它应该返回&#34;没有共享密码&#34;而不是支持的密码。

RC4-MD5也是不使用python 3.4的原因。与python 2.7相反,在python 3.4中有一个更安全的默认密码集,其中包括&#34; ..:!MD5&#34;。这意味着python 3.4客户端不会将RC4-MD5作为密码提供,因此握手将因为没有共享密码而失败。

修复将修复损坏的服务器。解决方法可能是明确设置连接的密码,即wrap_socket( ... , ciphers="RC4-MD5")或类似的