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

Posted

技术标签:

【中文标题】如何让 python 信任我服务器的 TLS 自签名证书:ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] 证书验证失败【英文标题】:How to allow python to trust my server's TLS self-signed certificate: ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed 【发布时间】:2018-10-08 01:14:34 【问题描述】:

这不是 this post 的重复项。我在那里尝试了解决方案,但在我的情况下没有任何效果。

我使用的是 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 证书——这还不够,跨度> 我认为这个问题是你另一个问题的重复:***.com/questions/50055935/…。 【参考方案1】:

这个问题已经闲置了一段时间,但如果有人仍在努力通过 Python ssl 库连接到具有自签名证书的服务器:

您可以使用SSLContextload_verify_locations 方法指定自定义自签名根证书(请参阅Python Docs for 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')

...

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

有关更多信息,另请参阅此 Python 文档段落:client-side operations。

【讨论】:

以上是关于如何让 python 信任我服务器的 TLS 自签名证书:ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] 证书验证失败的主要内容,如果未能解决你的问题,请参考以下文章

如何让信任锚在 Android API 级别 16-19 上正常工作

https 请求:底层连接已关闭:无法为 SSL/TLS 安全通道建立信任关系

是否可以在本地服务器中设置受信任的 TLS 证书?

WCF 服务无法为具有权限的 SSL/TLS 安全通道建立信任关系

如何添加自签名SSL证书 自签名SSL证书存风险

WCF 无法为具有 iis 权限的 SSL/TLS 安全通道建立信任关系