SSLV3_ALERT_HANDSHAKE_FAILURE SNI 在 Python 2.9.10 中使用 Tornado 4.2
SSLV3_ALERT_HANDSHAKE_FAILURE with SNI using Tornado 4.2 in Python 2.9.10
我在 Python 2.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)
我做错了什么导致了这个错误?我怎样才能更改我的代码来解决这个问题?
任何 ideas/help 对此将不胜感激。
谢谢,
问候,
亚罗
没有关于服务器的矿石信息很难判断,但我会尝试:
OpenSSL 0.9.8zd 8 Jan 2015
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
您正在将协议限制为 TLS 1.0。可能是服务器需要 TLS 1.2 或 TLS 1.1 或 SSL 3.0。请注意,您使用的 OpenSSL 版本不支持 TLS 1.1+。也可能是服务器没有共享密码。
尝试连接浏览器并查看使用的是哪个 TLS 版本和使用的密码。如果这可行但需要 TLS 1.1+,请尝试使用 curl 或 wget 创建连接。如果这是 public URL 使用 SSLLabs 检查支持的协议和密码。
http_client.fetch('https://ip.to.the.server/some_url', method='GET', ssl_options=context)
如果你真的在这里使用IP地址,也可能是服务器不接受IP地址作为SNI名称的问题。如果给定的名称与配置不匹配,有些服务器会导致握手失败,而其他服务器只是 return 默认证书。除此之外,URL 中的主机名必须与证书中的名称相匹配,以便证书验证能够成功。
谢谢 Steffen,你的建议最终让我找到了解决方案。
问题不在于 TLS 版本或 OpenSSL,而是因为我没有指定密码并且必要的密码 (RC4-SHA) 不在 Python 2.7.10 的默认列表中。
context.set_ciphers('RC4-SHA')
此外,我无法将创建的上下文与 Tornado 一起使用,因为我需要提供一个特定的 server_hostname 形式,我所看到的只能在套接字对象上完成:
sock = context.wrap_socket(sock, server_hostname='virtServer')
相反,我使用了 sock.write('...') 和 sock.recv() 来发出请求并且一切正常。
我在 Python 2.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)
我做错了什么导致了这个错误?我怎样才能更改我的代码来解决这个问题?
任何 ideas/help 对此将不胜感激。
谢谢, 问候, 亚罗
没有关于服务器的矿石信息很难判断,但我会尝试:
OpenSSL 0.9.8zd 8 Jan 2015
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
您正在将协议限制为 TLS 1.0。可能是服务器需要 TLS 1.2 或 TLS 1.1 或 SSL 3.0。请注意,您使用的 OpenSSL 版本不支持 TLS 1.1+。也可能是服务器没有共享密码。
尝试连接浏览器并查看使用的是哪个 TLS 版本和使用的密码。如果这可行但需要 TLS 1.1+,请尝试使用 curl 或 wget 创建连接。如果这是 public URL 使用 SSLLabs 检查支持的协议和密码。
http_client.fetch('https://ip.to.the.server/some_url', method='GET', ssl_options=context)
如果你真的在这里使用IP地址,也可能是服务器不接受IP地址作为SNI名称的问题。如果给定的名称与配置不匹配,有些服务器会导致握手失败,而其他服务器只是 return 默认证书。除此之外,URL 中的主机名必须与证书中的名称相匹配,以便证书验证能够成功。
谢谢 Steffen,你的建议最终让我找到了解决方案。 问题不在于 TLS 版本或 OpenSSL,而是因为我没有指定密码并且必要的密码 (RC4-SHA) 不在 Python 2.7.10 的默认列表中。
context.set_ciphers('RC4-SHA')
此外,我无法将创建的上下文与 Tornado 一起使用,因为我需要提供一个特定的 server_hostname 形式,我所看到的只能在套接字对象上完成:
sock = context.wrap_socket(sock, server_hostname='virtServer')
相反,我使用了 sock.write('...') 和 sock.recv() 来发出请求并且一切正常。