【问题标题】:SSLV3_ALERT_HANDSHAKE_FAILURE with SNI using Tornado 4.2 in Python 2.9.10SSLV3_ALERT_HANDSHAKE_FAILURE 与 SNI 在 Python 2.9.10 中使用 Tornado 4.2
【发布时间】:2015-06-17 16:08:13
【问题描述】:

我在 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)

我做错了什么导致此错误?如何更改我的代码来解决这个问题?

对此的任何想法/帮助将不胜感激。

谢谢, 问候, 亚罗

【问题讨论】:

    标签: python python-2.7 ssl tornado sni


    【解决方案1】:

    没有关于服务器的矿石信息很难判断,但我会尝试:

    OpenSSL 0.9.8zd 2015 年 1 月 8 日

    上下文 = 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 创建连接。如果这是一个公共 URL,请使用 SSLLabs 检查支持的协议和密码。

    http_client.fetch('https://ip.to.the.server/some_url', method='GET',  ssl_options=context)
    

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

    【讨论】:

      【解决方案2】:

      感谢 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() 来发出请求,并且一切正常。

      【讨论】:

        猜你喜欢
        • 2022-10-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-14
        • 1970-01-01
        相关资源
        最近更新 更多