我正在尝试在服务器和客户端之间创建 ssl 连接,但我不断收到 ConnectionAbortedError: [WinError 10053] 已建立的连接被主机中的软件中止
错误。
客户端.py
class Client(object):
def __init__(self):
threading.Thread(target=self.init_sock).start()
def init_sock(self):
host = 'localhost'
port = 49374
baresock = socket(AF_INET6, SOCK_STREAM)
context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
self.servsock = context.wrap_socket(baresock, server_hostname=host)
try:
self.servsock.connect((host, port)) #<--- Line error is being thrown at
logging.info("Connection Successful")
except:
logging.info("Connection Problem")
return
threading.Thread(target=self.listen_loop).start()
和server.py:
class ClientHandler(socketserver.BaseRequestHandler):
def handle(self):
pass
class Server(socketserver.ThreadingTCPServer):
srvhost = ''
srvport = 49374
def __init__(self,
request_handler_class=ClientHandler,
certfile="../scache/cert.pem",
keyfile="../scache/key.pem",
ssl_version=ssl.PROTOCOL_TLSv1_2,
bind_and_activate=True):
self.address_family = socket.AF_INET6
self.certfile = certfile
self.keyfile = keyfile
self.ssl_version = ssl_version
server_address = (self.srvhost, self.srvport)
super(Server, self).__init__(server_address, request_handler_class, bind_and_activate)
def get_request(self):
newsocket, fromaddr = self.socket.accept()
context = ssl.create_default_context()
context.load_cert_chain(certfile=self.certfile, keyfile=self.keyfile) # <------ Hanging Here
logging.info("New Request from " + fromaddr[0])
connstream = context.wrap_socket(newsocket, server_side=True)
logging.info("Socket Wrapped")
return connstream, fromaddr
当我尝试从客户端连接到服务器时,客户端抛出 WinError 10054,如上所述。当我尝试在服务器端使用调试器时,我可以根据错误找到 socketserver.py
的 _handle_request_noblock
方法,其中 request, client_address = self.get_request ()
抛出 OSError。完整追溯:
Traceback (most recent call last):
File "C:\Program Files\Anaconda3\lib\threading.py", line 916, in _bootstrap_inner
self.run()
File "C:\Program Files\Anaconda3\lib\threading.py", line 864, in run
self._target(*self._args, **self._kwargs)
File "C:/Project/src/client.py", line 36, in init_sock
self.servsock.connect((host, port))
File "C:\Program Files\Anaconda3\lib\ssl.py", line 1093, in connect
self._real_connect(addr, False)
File "C:\Program Files\Anaconda3\lib\ssl.py", line 1084, in _real_connect
self.do_handshake()
File "C:\Program Files\Anaconda3\lib\ssl.py", line 1061, in do_handshake
self._sslobj.do_handshake()
File "C:\Program Files\Anaconda3\lib\ssl.py", line 683, in do_handshake
self._sslobj.do_handshake()
ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host
是什么导致了这个错误,我该如何解决?谢谢。
为了复制它,我使用了您的代码并遇到了同样的问题,然后意识到我缺少构造函数中引用的 certfile
和 keyfile
.我生成了文件并使用以下代码将它们放在相对路径中:
from OpenSSL import SSL, crypto
CRT_PATH = "../scache/cert.pem" # self-signed certificate
KEY_PATH = "../scache/key.pem" # private key used to sign the certificate
def generate_key():
"""
Generate a private key and dump it to the key file.
:return: key
"""
key = crypto.PKey()
key.generate_key(crypto.TYPE_RSA, 4096)
with open(KEY_PATH, "w") as keyfile:
keyfile.write(bytes.decode(crypto.dump_privatekey(crypto.FILETYPE_PEM, key)))
return key
def generate_crt(key):
"""
Generate a self-signed certificate.
:return: certificate
"""
crt = crypto.X509()
crt.get_subject().C = "US"
crt.get_subject().ST = "New York"
crt.get_subject().L = "New York"
crt.get_subject().O = "CompanyName"
crt.get_subject().OU = "UnitName"
crt.get_subject().CN = "localhost"
crt.set_pubkey(key)
crt.set_serial_number(101010)
crt.gmtime_adj_notBefore(0)
crt.gmtime_adj_notAfter(10 * 365 * 24 * 60 * 60)
crt.sign(key, 'sha256') # Self-sign
with open(CRT_PATH, "w") as crtfile:
crtfile.write(bytes.decode(crypto.dump_certificate(crypto.FILETYPE_PEM, crt)))
return crt
if __name__ == "__main__":
generate_crt(generate_key())
一旦我生成了您记下的证书文件和 key 文件,OSError
就不再抛出,应用程序可以继续握手。这让我相信问题的罪魁祸首可能是 certfile/keyfile 的无效路径,或者文件无效。
您可以将路径调整为您需要的任何路径(我假设此脚本与您的 client.py 和 server.py 位于同一位置)并且您应该将证书的参数调整为您需要的任何值需要您的特定应用。
我是一名优秀的程序员,十分优秀!