Python Programming

Python SSL证书验证失败错误排查

Spread the love

互联网上的安全通信严重依赖于安全套接字层 (SSL) 证书。当您的 Python 代码遇到“SSL CERTIFICATE_VERIFY_FAILED”错误时,表示未能验证服务器 SSL 证书的真实性。本综合指南将剖析此错误的原因并提供切实可行的解决方案。

目录

了解 SSL 证书

SSL 证书是一种数字凭证,用于验证网站的身份,从而实现安全的 HTTPS 通信。它利用公钥加密技术来加密客户端(您的 Python 程序)和服务器之间交换的数据。在 HTTPS 连接期间,您的 Python 代码(或浏览器)会通过检查其有效性、颁发者和吊销状态来验证服务器的证书。

SSL CERTIFICATE_VERIFY_FAILED 的根本原因

令人头疼的“SSL CERTIFICATE_VERIFY_FAILED”错误出现在此验证过程失败时。几个因素可能导致此问题:

  • 自签名证书:由网站所有者而不是受信任的证书颁发机构 (CA) 颁发的证书通常会被标记。Python 默认情况下只信任众所周知的 CA。
  • 证书过期:过期的证书会使连接不可靠。
  • 系统时钟不准确:证书有效性对时间敏感;不正确的系统时钟会导致验证失败。
  • 证书被吊销:被入侵的证书可能会被其颁发者吊销。
  • 主机名不匹配:证书的通用名称 (CN) 或主题备用名称 (SAN) 必须与您连接到的主机名匹配。
  • CA 链问题:证书颁发机构信任链中的问题会中断验证。证书需要可验证的信任链才能追溯到受信任的根 CA。
  • 网络连接问题:网络中断可能会阻碍证书验证。

有效的故障排除策略

解决方案取决于根本原因。以下是一种结构化的方法:

  1. 验证证书(谨慎操作):对于自签名证书或不受信任的证书,您可以暂时禁用验证(强烈建议不要在生产环境中这样做):
    
    import ssl
    import urllib.request
    
    context = ssl._create_unverified_context()
    response = urllib.request.urlopen('https://your-website.com', context=context)
    # ... 处理响应 ...
      
  2. 将证书添加到您的受信任存储区:对于自签名证书,将其添加到您的系统受信任证书存储区。此过程因操作系统而异。
  3. 校正系统时间:确保您的系统时钟准确。
  4. 验证主机名:仔细检查代码中的主机名是否与证书的 CN 或 SAN 匹配。
  5. 使用 requests 库(推荐):requests 库提供强大的 SSL 处理功能。verify=True(默认值)启用正确的验证。对于自定义 CA 捆绑包:
    
    import requests
    
    try:
        response = requests.get('https://your-website.com', verify=True) 
        response.raise_for_status() # 为错误的响应 (4xx 或 5xx) 抛出 HTTPError
        # ... 处理响应 ...
    except requests.exceptions.RequestException as e:
        print(f"发生错误:{e}")
    
    # 使用自定义 CA 捆绑包:
    response = requests.get('https://your-website.com', verify='/path/to/your/ca_bundle.pem')
      
  6. 检查网络连接:排除网络问题。

安全连接的最佳实践

优先使用来自受信任 CA 的有效证书。使用 requests 库并进行正确的验证 (verify=True)。除非在受控测试期间,否则避免禁用验证。定期更新系统的证书和时钟以获得最佳安全性。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注