Python - SSL - 错误的版本号

Posted

技术标签:

【中文标题】Python - SSL - 错误的版本号【英文标题】:Python - SSL - wrong version number 【发布时间】:2012-04-15 08:34:35 【问题描述】:

这可能只是另一个未解决的线程,但我还是会填写一些信息。

我什至一秒钟都无法将我的 SSL 打包在一起。 对我的 wrap_socket() 和 do_handshake() 做错了什么有任何想法吗?

关键文件似乎是 100% 完美的,我在握手之前尝试了使用 AND 而没有 .recv()。 这只是根据我放置recv()的位置生成这些:

SSL3_GET_CLIENT_HELLO:版本号错误

SSL3_GET_RECORD:版本号错误

class Server():
    def __init__(self, listen = '', port = 8080, ssl = False):
        self.sock = socket.socket()
        self.sock.bind((listen, port))
        self.sock.listen(5)

    def accept(self):
        newsocket, fromaddr = self.sock.accept()
        newsocket.recv(32)
        newsocket.setblocking(0)
        sslsock = ssl.wrap_socket(newsocket,
                                    server_side=True,
                                    certfile="./kernel/sock/server.crt",
                                    keyfile="./kernel/sock/server.key",
                                    cert_reqs=ssl.CERT_NONE,
                                    ssl_version=ssl.PROTOCOL_TLSv1,
                                    do_handshake_on_connect=False,
                                    suppress_ragged_eofs=True)
        sslsock.do_handshake()
        return sslsock, fromaddr

为了记录,如果不是很明显或者我错了,那就是握手失败了:)

我稍微修改了代码,尝试使用 SSLv3 并稍微改变了换行的位置:

import socket, ssl, time, select

class Server():
    def __init__(self, listen = '', port = 443, ssl = False):
        self.sock = socket.socket()
        self.sock.bind((listen, port))
        self.sock.listen(5)

    def accept(self):
        self.sock = ssl.wrap_socket(self.sock,
                                    server_side=True,
                                    certfile="./kernel/sock/server.crt",
                                    keyfile="./kernel/sock/server.key",
                                    cert_reqs=ssl.CERT_NONE,
                                    ssl_version=ssl.PROTOCOL_SSLv3,
                                    do_handshake_on_connect=False,
                                    suppress_ragged_eofs=True)

        newsocket, fromaddr = self.sock.accept()

        print [newsocket.recv(32)]
        newsocket.setblocking(False)
        newsocket.do_handshake()

        return newsocket, fromaddr

s = Server()
ns, na = s.accept()
print ns.recv(1024)

现在我得到了 newsocket.recv(32):

ssl.SSLError: [Errno 1] _ssl.c:1331: 错误:140940E5:SSL 例程:SSL3_READ_BYTES:ssl 握手失败

和没有:

ssl.SSLError: [Errno 2] _ssl.c:490: 操作未完成(读取)

另外:我拒绝使用 Twisted

缩小规模:

import socket, ssl, time, select
from OpenSSL import SSL

class Server():
    def __init__(self, listen = '', port = 443, ssl = False):
        ctx = SSL.Context(SSL.SSLv23_METHOD)
        ctx.use_privatekey_file("server.pem")
        ctx.use_certificate_file("server.pem")
        self.sock = SSL.Connection(ctx, socket.socket())

        self.sock.bind((listen, port))
        self.sock.listen(5)

    def accept(self):
        newsocket, fromaddr = self.sock.accept()
        return newsocket, fromaddr

s = Server()
ns, na = s.accept()
print ns.recv(1024)

这与“本机”ssl 库一样好用。 但是现在我得到了这个错误:

OpenSSL.SSL.Error: [('SSL routines', 'SSL23_READ', 'ssl handshake failure')]


这是我现在的位置:

import socket, ssl, time #, select

class Server():
    def __init__(self, listen = '', port = 443, ssl = False):
        self.sock = socket.socket()
        self.sock.bind((listen, port))
        self.sock.listen(5)

    def accept(self):
        self.ssl_sock = None
        while not self.ssl_sock:
            self.ssl_sock = ssl.wrap_socket(self.sock,
                server_side=True,
                certfile=r"C:\moo.pem",
                keyfile=r"C:\moo.key",
                cert_reqs=ssl.CERT_NONE,
                ssl_version=ssl.PROTOCOL_TLSv1)

        newsocket, fromaddr = self.ssl_sock.accept()

        print([newsocket.recv()])

        return newsocket, fromaddr

s = Server()
ns, na = s.accept()
print(ns.recv(1024))

这在 Firefox 中“完美”工作,但在 Google Chrome 中。 为什么?有什么不同? -.-

【问题讨论】:

【参考方案1】:

如果你的代码有问题,我根本不会告诉你。 错误很明显。客户端支持SSLv3,你的服务器只支持TLSv1。 因此,您应该启用对SSLv3 的支持或升级您的客户端。

这一行似乎是问题所在:ssl_version=ssl.PROTOCOL_TLSv1。也许您也可以在这里添加SSLv3

更新: 我看到你在浏览器之间有问题。查看 Crome 中是否启用了 SSLv3。 例如,在 IE 中,这是在 Internet Options-> Advanced Tab 下。 类似的东西应该在 Chrome 中。禁用SSv3 并改为启用TLSv1

【讨论】:

SSL 例程:SSL3_GET_RECORD:wrong version number 在握手之前使用 recv(),没有它我得到 _ssl.c:490: The operation未完成(读取) 使用 ssl_version=ssl.PROTOCOL_SSLv3, 在 FireFox 中删除 SSLv3 有效。 SSLv3 比 TLSv1 旧,所以我宁愿坚持使用 TLSv1 取决于。您可以同时支持 SSLv23 和 TLSv1,也可以放弃弱协议以支持 TLSv1。如果您的安全要求很强,那么指定“客户端”没有问题如果未启用最新的 TLS,则可能是连接问题 SSLv23 不代表 SSL 2 和 SSL 3。它特指所有支持的协议。

以上是关于Python - SSL - 错误的版本号的主要内容,如果未能解决你的问题,请参考以下文章

为 SSL / TLS 配置 Proton 引发 openssl 错误版本号和 gRPC 客户端错误

Node.js SSL 错误:错误的版本号:../deps/openssl/openssl/ssl/record/ssl3_record.c:332

Apache:cURL:ssl3_get_record:apache2 ssl 的版本号错误

错误:写入 EPROTO 4455222784:错误:1408F10B:SSL 例程:ssl3_get_record:错误的版本号:../deps/openssl/openssl/ssl/record

C中的OpenSSL-例程:ssl3_get_record:尝试使用TLS1_2连接到服务器时版本号错误

python2.7安装MySQLdb