使用urllib2进行SSLv3警报握手失败

时间:2015-06-18 14:50:58

标签: python python-2.7 ssl openssl urllib2

我在使用Python 2.7.10下的urllib2连接https时遇到了麻烦。

有什么想法我错过了吗?

Python 2.7.10 (default, Jun 18 2015, 10:53:24) 
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import ssl, urllib2
>>> ssl.HAS_SNI
True
>>> ssl.OPENSSL_VERSION
'OpenSSL 0.9.8o 01 Jun 2010'
>>> opener = urllib2.build_opener()
>>> opener.open('https://twitrss.me/')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/python2.7/lib/python2.7/urllib2.py", line 431, in open
    response = self._open(req, data)
  File "/usr/local/python2.7/lib/python2.7/urllib2.py", line 449, in _open
    '_open', req)
  File "/usr/local/python2.7/lib/python2.7/urllib2.py", line 409, in _call_chain
    result = func(*args)
  File "/usr/local/python2.7/lib/python2.7/urllib2.py", line 1240, in https_open
    context=self._context)
  File "/usr/local/python2.7/lib/python2.7/urllib2.py", line 1197, in do_open
    raise URLError(err)
urllib2.URLError: <urlopen error [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:590)>

1 个答案:

答案 0 :(得分:2)

我能够在OS X 10.10.3上复制你的问题,OS X 10.6的版本是用OpenSSL 0.9.8zd构建的2.7.6。

问题是在TLS握手中缺少Server Name Indication(SNI)扩展,twitrss.me网站显然需要:

  

服务器名称指示(SNI)是TLS计算机的扩展   客户端指示它的主机名的网络协议   正在尝试在握手过程开始时连接。

我通过使用OpenSSL编写一个小型C ++程序并插入OpenSSL调用

来验证这一点
SSL_set_tlsext_host_name(ssl, "twitrss.me");

允许成功连接而省略它失败。我还查看了数据包转储,以验证在尝试使用Python进行连接时是否缺少SNI。

Python SSL模块显然是supports SNI in Python 3may require a workaround in Python 2。似乎PEP 0466包含SNI并且在Python 2.7.9中登陆,所以你应该拥有它,但我不知道urllib2/urllib3是否在没有解决方法的情况下利用了它。