如何让Python信任我的服务器的TLS自签名证书:ssl.SSLError:[SSL:CERTIFICATE_VERIFY_FAILED]证书验证失败。

3
这不是这篇文章的重复。我尝试了那里提供的解决方案,但在我的情况下都没有起作用。
我正在使用Windows和Python 3.6.5。我有一个用于TLS客户端的Python脚本。我需要连接到的服务器使用自签名证书。当我尝试使用我的脚本连接它时,我会得到以下错误:
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:833)

我需要解析证书。我尝试将我的服务器证书.pem的内容添加到名为cacert.pem的文件中,该文件位于C:\Python36\Lib\site-packages\certifi中,并重新运行程序。但没有任何变化。这是我的脚本,请帮助我让客户端对此服务器做出例外,因为我信任它的证书。

import socket, ssl
import itertools

context = ssl.SSLContext() 
context.verify_mode = ssl.CERT_OPTIONAL 
context.check_hostname = False

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
domain="192.168.56.3" # my server
ssl_sock = context.wrap_socket(s, server_hostname=domain)
ssl_sock.connect((domain, 443))

print("====== peer's certificate ======")
try:
    cert = ssl_sock.getpeercert()
    print(cert)
except SSLError as e:
    print("Error: ",e)
ssl_sock.close()

很难确定发生了什么,因为根据提供的信息无法重现。但是,假设代码正在使用cacert.pem文件并且您已添加了证书,则我猜测该证书不是CA证书,而只是自签名的非CA证书-这是不足够的。 - Steffen Ullrich
我认为这个问题是你其他问题的重复:https://stackoverflow.com/questions/50055935/cant-receive-peers-certificate-in-opoenssl-python-client-using-ssl-sslcontext。 - CristiFati
1个回答

3

这个问题已经闲置了一段时间,但是如果有人仍在努力通过Python ssl库连接到服务器的自签名证书,您可以使用SSLContextload_verify_locations方法来指定自定义的自签名根证书 (参见Python文档关于load_verify_locations的说明)。

以上代码可按如下方式扩展:

...

context = ssl.SSLContext() 
context.verify_mode = ssl.CERT_OPTIONAL 
context.check_hostname = False

context.load_verify_locations(cafile='/path/to/your/cacert.pem')

...

请注意,如果您想使用相同的客户端/上下文连接到其他具有公共证书的服务器,则还需要包含公共根证书(例如,您可以将内容附加到certifi根证书中,并引用该文件夹/路径)。

有关更多信息,请参阅Python文档段落:客户端操作


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接