Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
742 views
in Technique[技术] by (71.8m points)

python - SSLv3 alert handshake failure with urllib2

I'm having troubles connecting with https using urllib2 under Python 2.7.10.

Any thoughts what I'm missing?

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)>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I was able to duplicate your problem on OS X 10.10.3, whose stock Python is 2.7.6 built with OpenSSL 0.9.8zd.

The problem is the lack of the Server Name Indication (SNI) extension in the TLS handshake, which the twitrss.me site apparently requires:

Server Name Indication (SNI) is an extension to the TLS computer networking protocol by which a client indicates which hostname it is attempting to connect to at the start of the handshaking process.

I verified this by writing a small C++ program with OpenSSL, and inserting the OpenSSL call

SSL_set_tlsext_host_name(ssl, "twitrss.me");

allows a successful connection while omitting it fails. I also looked at packet dumps to verify that SNI was missing when attempting connection using Python.

The Python SSL module apparently supports SNI in Python 3 but may require a workaround in Python 2. It appears that PEP 0466 includes SNI and landed in Python 2.7.9, so you should have it, but I don't know if urllib2/urllib3 take advantage of that without the workaround.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...