首页 > 解决方案 > “[SSL: CERTIFICATE_VERIFY_FAILED] 证书验证失败:自签名证书”和“[SSL: TLSV1_ALERT_UNKNOWN_CA] tlsv1 alert unknown ca”

问题描述

我正在尝试创建一个使用 ssl 保护聊天通信的程序,我使用 OpenSsl 作为证书,这个想法是添加越来越多的加密,我知道我将如何去做,但是当我添加 ssl 时建立连接时给我一个错误(我对 SSL 不太了解)

服务器.py:

from socket import *
from threading import *
from ssl import *

context = SSLContext(PROTOCOL_TLSv1)
context.load_cert_chain(certfile="cert.pem", keyfile="cert.pem")



host = '127.0.0.1'
port = int(input("Enter a port: "))

server = socket(AF_INET, SOCK_STREAM)

server.bind((host,port))
server.listen()
print(f"Server running on {host}:{port}")

clients = []
usernames = []

def broadcast(msg, _client):
    for client in clients:
        if client != _client:
            client.send(msg)
        
def handle_messages(client,address):
    while True:
        try:
            msg = client.recv(1024)
            broadcast(msg, client)
        except:
            index = clients.index(client)
            username = usernames[index]
            broadcast(f"ChatBot: {username} disconnected".encode('utf-8'),client)
            clients.remove(client)
            usernames.remove(username)
            client.close()
            print(f"{username} disconnected from {str(address)}")
            break

def recive_conn():
    while True:
        client, address = server.accept()
        ssl_client = context.wrap_socket(client, server_side=True, ciphers="ADH-AES256-SHA")
        ssl_client.send("@username!".encode('utf-8'))
        username = ssl_client.recv(1024).decode('utf-8')

        clients.append(ssl_client)
        usernames.append(username)

        print(f"{username} connected from {str(address)}")

        msg = f'ChatBot: {username} joined the chat.'.encode('utf-8')
        broadcast(msg, ssl_client)
        ssl_client.send("Successful connection".encode('utf-8'))

        thread = Thread(target=handle_messages, args=(ssl_client,address))
        thread.start()

recive_conn()

客户端.py:

from socket import *
from threading import *
from playsound import playsound
from ssl import *

ACCEPTED_CHARS = ('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9','0','_','.')
NOTIFICATION = 'notification.mp3'
ctl = 0

while True:
    user = input("Enter your username: ")
    for i in user:
        if i not in ACCEPTED_CHARS:
            ctl += 1
    if ctl != 0:
        print('Error: invalid character(s)')
    else:
        break

host = input("Enter an ip: ")
while True:
    try:
        port = int(input("Enter a port: "))
        break
    except:
        print("Error: Invalid port")

context = SSLContext(PROTOCOL_TLSv1)
context.verify_mode = CERT_REQUIRED
context.check_hostname = True
context.load_default_certs()
context.load_cert_chain(certfile="cert.pem", keyfile="cert.pem")

client = socket(AF_INET, SOCK_STREAM)
ssl_client = context.wrap_socket(client, server_hostname=host, ciphers="ADH-AES256-SHA")
ssl_client.connect((host,port))
    

def recive_msg():
    while True:
        try:
            msg = ssl_client.recv(1024).decode('utf-8')
            if msg == "@username!":
                ssl_client.send(user.encode('utf-8'))

            else:
                print(msg)
                playsound(NOTIFICATION)
        except:
            print("An unexpected error has occurred!")
            ssl_client.close()
            break

def write_msg():
    while True:
        entry = input('')
        msg = f'@{user}: {entry}'
        ssl_client.send(msg.encode('utf-8'))

recv_thread = Thread(target=recive_msg)
recv_thread.start()

write_thread = Thread(target=write_msg)
write_thread.start()

但是在连接时我收到以下错误

服务器.py:

Traceback (most recent call last):
  File "C:\Users\delaf\OneDrive\Escritorio\armadillo\server.py", line 63, in <module>
    recive_conn()
  File "C:\Users\delaf\OneDrive\Escritorio\armadillo\server.py", line 47, in recive_conn
    ssl_client = context.wrap_socket(client, server_side=True)
  File "C:\Users\delaf\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 500, in wrap_socket
    return self.sslsocket_class._create(
  File "C:\Users\delaf\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 1040, in _create
    self.do_handshake()
  File "C:\Users\delaf\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 1309, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: TLSV1_ALERT_UNKNOWN_CA] tlsv1 alert unknown ca (_ssl.c:1129)

客户端.py:

Traceback (most recent call last):
  File "C:\Users\delaf\OneDrive\Escritorio\armadillo\client.py", line 48, in <module>
    ssl_client.connect((host,port))
  File "C:\Users\delaf\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 1342, in connect
    self._real_connect(addr, False)
  File "C:\Users\delaf\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 1333, in _real_connect
    self.do_handshake()
  File "C:\Users\delaf\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 1309, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate (_ssl.c:1129)

那么现在将证书安装在受信任的证书文件夹中,现在我得到了:

服务器.py:

Traceback (most recent call last):
  File "C:\Users\delaf\OneDrive\Escritorio\armadillo\server.py", line 61, in <module>
    recive_conn()
  File "C:\Users\delaf\OneDrive\Escritorio\armadillo\server.py", line 45, in recive_conn
    ssl_client = context.wrap_socket(client, server_side=True)
  File "C:\Users\delaf\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 500, in wrap_socket
    return self.sslsocket_class._create(
  File "C:\Users\delaf\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 1040, in _create
    self.do_handshake()
  File "C:\Users\delaf\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 1309, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: SSLV3_ALERT_BAD_CERTIFICATE] sslv3 alert bad certificate (_ssl.c:1129)

客户端.py:

Traceback (most recent call last):
  File "C:\Users\delaf\OneDrive\Escritorio\armadillo\client.py", line 47, in <module>
    ssl_client.connect((host,port))
  File "C:\Users\delaf\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 1342, in connect
    self._real_connect(addr, False)
  File "C:\Users\delaf\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 1333, in _real_connect
    self.do_handshake()
  File "C:\Users\delaf\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 1309, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: IP address mismatch, certificate is not valid for '127.0.0.1'. (_ssl.c:1129)

标签: pythonsocketssslopensslpython-multithreading

解决方案


推荐阅读