Python ssl套接字服务器SSLV3_ALERT_CERTIFICATE_UNKNOWN问题

Lij*_*iju 3 python sockets ssl tcp server

我正在使用 ssl 编写一个 python 套接字服务器,并且在 ssl 握手期间遇到证书未知错误。

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes我自己用命令创建了私钥和证书。
该服务器旨在在我的电脑的内联网(wifi下)中运行,用户将使用他们的浏览器联系我的电脑IP地址。因此我没有向任何 CA 注册此证书。我认为这对我来说不是强制性的。
下面更详细..

回声服务器.py

import socket
import ssl
import threading
class echoserver:
    def __init__(self,i,p):
        self.ip=i
        self.port=p
    def handler(self,c,a):
        msg=c.recv(1024)
        c.send(msg)
    def serve(self):
        echoserver = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        echoserver = ssl.wrap_socket(echoserver, keyfile='keys/key.pem', certfile='keys/cert.pem', server_side=True)
        echoserver.bind((self.ip, self.port))
        echoserver.listen()
        while True:
            (c,a)=echoserver.accept()
            threading.Thread(target=self.handler, args=(c,a)).start()

es=echoserver('192.168.43.124',443) #My PC's ip assigned under wifi network
es.serve()

#Connecting from mobile phone within same network as https://192.163.43.124
Run Code Online (Sandbox Code Playgroud)

ssl 握手期间服务器出错

        self._sslobj.do_handshake()      
    ssl.SSLError: [SSL: SSLV3_ALERT_CERTIFICATE_UNKNOWN] sslv3 alert certificate unknown (_ssl.c:1108)
Run Code Online (Sandbox Code Playgroud)

我尝试过的

  • 在wrap_socket函数中添加 cert_reqs=ssl.CERT_NONE 和 ca_certs="/location/to/keys" 参数。
    似乎不起作用。我认为这些选项适用于客户端。
  • 在Chrome中的wrap_socket函数中添加do_handshake_on_connect = False
    ,当连接的服务器抛出相同的错误并且线程/连接因异常关闭时。chrome似乎再次立即发送相同的连接请求,并且第二个请求完美地工作!
    在 Firefox 中,第一个连接因相同错误而关闭,并且没有第二个请求。
  • 在证书中分配与 IP 地址相同的公用名
    不起作用。
  • 在这里检查了ietf规范中的certificate_unknown错误。除了这个解释之外,它没有给出任何线索 certificate_unknown: Some other (unspecified) issue arose in processing the certificate, rendering it unacceptable.

我注意到的另一件事是ThreadedHTTPServer,如果我以与下面相同的方式使用内置,它会工作得很漂亮,没有我上面提到的任何问题。

        self._sslobj.do_handshake()      
    ssl.SSLError: [SSL: SSLV3_ALERT_CERTIFICATE_UNKNOWN] sslv3 alert certificate unknown (_ssl.c:1108)
Run Code Online (Sandbox Code Playgroud)

我不确定为什么会发生这种情况以及我应该如何处理。不确定内置服务器模块如何正常工作。

感谢任何线索。谢谢。

下面的 Python 内置 HTTPServer 与 ssl 一起工作正常,没有显示任何错误。不知道如何?

httpd = self.ThreadedHTTPServer((self.ip, self.port), self.handler)
httpd.socket = ssl.wrap_socket(httpd.socket, keyfile='keys/key.pem', certfile='keys/cert.pem', server_side=True)
Run Code Online (Sandbox Code Playgroud)

Ste*_*ich 6

ssl.SSLError: [SSL: SSLV3_ALERT_CERTIFICATE_UNKNOWN] sslv3 alert certificate unknown (_ssl.c:1108)
Run Code Online (Sandbox Code Playgroud)

这意味着客户端(浏览器)不信任您的证书,因为它是由未知实体颁发的。如果您想使用自签名证书,您必须将这些证书显式导入为您要使用的所有客户端的可信证书。

这是没有办法解决的。TLS 中的证书是为了确保连接是与预期的服务器完成的,而不是中间有人声称是预期的服务器。如果客户端信任任意证书,那么它也会信任中间人攻击者创建的证书。

下面的 Python 内置 HTTPServer 与 ssl 一起工作正常,没有显示任何错误。不知道如何?

浏览器仍然会抱怨。唯一的区别是服务器捕获了异常,因此不会崩溃而是继续。您可以在代码中执行相同的操作:

    while True:
        try:
            (c,a)=echoserver.accept()
            threading.Thread(target=self.handler, args=(c,a)).start()
        except:
            pass # ignore error
Run Code Online (Sandbox Code Playgroud)