使用Python 2.9.10中的Tornado 4.2与SNI进行SSLV3警报握手失败

使用Python 2.9.10中的Tornado 4.2与SNI进行SSLV3警报握手失败,python,python-2.7,ssl,tornado,sni,Python,Python 2.7,Ssl,Tornado,Sni,我在Python2.7.10中使用ssl.SSLContext正确设置SNI标志时遇到问题,每次握手都会失败,我不知道为什么 下面是我如何尝试的: import ssl import socket if ssl.HAS_SNI: print "SNI is available" print(ssl.OPENSSL_VERSION) context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) context.load_cert_chain('cacrt.p

我在Python2.7.10中使用ssl.SSLContext正确设置SNI标志时遇到问题,每次握手都会失败,我不知道为什么

下面是我如何尝试的:

import ssl
import socket

if ssl.HAS_SNI:
    print "SNI is available"
print(ssl.OPENSSL_VERSION)

context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
context.load_cert_chain('cacrt.pem', 'cakey.pem', 'password')

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock = context.wrap_socket(sock, server_hostname='virtServer')
sock.connect(('ip.to.the.server', 443))

http_client = tornado.httpclient.HTTPClient()
http_client.fetch('https://ip.to.the.server/some_url', method='GET',  ssl_options=context)
这是我得到的结果:

SNI is available
OpenSSL 0.9.8zd 8 Jan 2015
Traceback (most recent call last):
  File "test/steps/test.py", line 37, in <module>
    sock.connect(('10.59.71.242', 443))
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py", line 844, in connect
    self._real_connect(addr, False)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py", line 835, in _real_connect
    self.do_handshake()
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py", line 808, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:590)
SNI可用
OpenSSL 0.9.8zd 2015年1月8日
回溯(最近一次呼叫最后一次):
文件“test/steps/test.py”,第37行,在
插座连接('10.59.71.242',443))
文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py”,第844行,在connect中
self.\u real\u connect(地址,错误)
文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py”,第835行,在_real\u connect中
self.do_握手
文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py”,第808行,在do_握手中
赛尔夫:握手
ssl.SSLError:[ssl:SSLV3\u警报\u握手失败]SSLV3警报握手失败(\u ssl.c:590)
我做错了什么导致了这个错误?如何更改代码以解决此问题

如果您对此有任何想法/帮助,我们将不胜感激

谢谢, 当做
Yaro

如果没有服务器的详细信息,很难判断,但我会尝试:

OpenSSL 0.9.8zd 2015年1月8日

context=ssl.SSLContext(ssl.PROTOCOL_TLSv1)

您正在将协议限制为TLS 1.0。服务器可能需要TLS 1.2或TLS 1.1或SSL 3.0。请注意,您使用的OpenSSL版本不支持TLS1.1+。也可能是服务器没有共享密码

尝试与浏览器连接,查看所使用的TLS版本和密码。如果这是可行的,但需要TLS 1.1+尝试使用curl或wget创建连接。如果这是一个公共URL,则用于检查支持的协议和密码


如果您确实在这里使用IP地址,那么服务器不接受IP地址作为SNI名称也可能是一个问题。如果给定的名称与配置不匹配,则某些服务器会导致握手失败,而其他服务器只返回默认证书。除此之外,URL中的主机名必须与证书中的名称匹配,这样证书验证才能成功。

谢谢Steffen,您的建议最终让我找到了解决方案。 问题不在于TLS版本或OpenSSL,而在于我没有指定密码,并且必要的密码(RC4-SHA)不在Python 2.7.10的默认列表中

context.set_ciphers('RC4-SHA')
此外,我无法将创建的上下文用于Tornado,因为我需要提供一个特定的服务器主机名,我所看到的服务器主机名只能在套接字对象上执行:

sock = context.wrap_socket(sock, server_hostname='virtServer')
相反,我使用sock.write(“…”)和sock.recv()发出请求,一切都很顺利

sock = context.wrap_socket(sock, server_hostname='virtServer')