我有一个简单的 Python TLS 客户端,在 Ubuntu 18.04 和 openssl 版本 1.1.0g 中运行。客户端支持单个密码套件。我在尝试连接到 TLS 1.0 服务器时收到错误。服务器不支持该密码套件。我知道错误的原因很可能是由于缺乏密码套件不匹配,但在这种情况下我正在为用户寻找更有意义的错误。我目前遇到的错误是指向 SSLv3,客户端和服务器都与 SSLv3 没有任何关系。客户端和服务器也禁用 SSLv3。这是错误:
[SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:833)
我的问题是:我需要一个更好的错误消息,例如(缺少密码套件不匹配或与密码套件问题相关的类似内容)。有没有?当然,我可以编写自己的消息,但套接字连接可能会因各种原因而失败,并且我不能犯一个总是显示“密码套件不匹配”的一般错误。
这是客户端脚本:
import socket,ssl
import itertools
context = ssl.SSLContext()
context.verify_mode = ssl.CERT_NONE
context.check_hostname = False
ciphers = "ECDHE-ECDSA-AES128-GCM-SHA256"
context.set_ciphers(ciphers)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
domainName = "privatedomain.com"
sslSocket = context.wrap_socket(s, server_hostname = domainName)
try:
sslSocket.connect((domainName, 443))
except (ssl.SSLError, ssl.SSLEOFError, ssl.CertificateError,ssl.SSLSyscallError, ssl.SSLWantWriteError, ssl.SSLWantReadError,ssl.SSLZeroReturnError) as e:
print("Error: ",e)
sslSocket.close()
从客户端的角度来看,除了服务器发送的消息之外,不可能收到另一条消息,在您的情况下是
handshake failure
。例如,错误消息记录在 RFC 2246 7.2 中。
您在消息中看到 SSLv3 的原因是您可能发送了 SSLv3 Hello,这是允许协商 TLS 1.0 或更高版本协议的内容。
回答迟了,但希望有帮助。 。 .
客户端和服务器必须就传输层版本达成一致,连接才能成功。考虑第一次见到一个人。该人(客户端)向您(服务器)伸出手以表示问候。如果您只是看到这个人没有洗手就从厕所出来,并且您看到(和/或闻到)一些不受欢迎的东西,您将不会伸出手来回报。
这与 SSL 握手类似。客户端说“嘿,我想通过 TLS v1.0 进行通信”。精明的服务器管理员知道 TLS v1.0 不安全,他们已在服务器上禁用它——因此服务器响应客户端:“不,但是版本 1.3 怎么样?” (即:“先去洗手”)。如果客户端接受(洗手),则握手被接受,连接建立。如果客户端拒绝,服务器会继续要求较低版本(“那么一加仑 Purell 怎么样?”),直到客户端接受或服务器没有其他版本可提供(走开)。
基本上,握手被设计为使用客户端和服务器都支持的最高版本。
此页面有一个很好的客户端和服务器版本表(大约在“SSL 上下文”部分的一半位置:
https://docs.python.org/3/library/ssl.html
请注意,TLS v1.0 不再被认为是安全的(Google“POODLE 攻击”)。如果您的服务器支持,请尽快禁用它。
对我来说:
urllib.error.URLError: <urlopen error [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1123)>
意味着我正在这样做
cipherstr = 'MEDIUM:!aNULL:!eNULL'
context = ssl._create_unverified_context()
context.set_ciphers(cipherstr)
注释掉
set_ciphers
现在就可以了。
其他要检查的事情:确保您的 OpenSSL 版本足够新。