跳到主要内容
ecdsa.com
Python ssl module (OpenSSL)Python cryptography 库

错误信息

[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired

搭配 OpenSSL 1.1.1、3.0 和 3.5 的 Python 中措辞完全相同,后面跟着源代码位置,例如“(_ssl.c:1082)”。有效期尚未开始的证书会报“certificate is not yet valid”。

Python ssl module (OpenSSL) — ssl.SSLCertVerificationError, X509_V_ERR_CERT_HAS_EXPIRED (10)

含义

OpenSSL 在证书链中发现了一张证书,其有效期截止时间早于本机的当前时间。通常是服务器证书没有续期,或者续期后的新证书没有被实际提供;有时是客户端通过过时 CA 证书包中已过期的根证书构建了路径,或者客户端的时钟不准。

原因

修复方法

  1. 1.

    查看服务器实际提供的证书

    在关闭验证的情况下获取一次证书,只用于读取,然后检查 notAfter(把证书粘贴到解码器中)。不要把这个未经验证的连接用于其他任何用途。

    python
    import socket, ssl
    
    # Read the served certificate without verifying it, to see its dates
    ctx = ssl.create_default_context()
    ctx.check_hostname = False
    ctx.verify_mode = ssl.CERT_NONE
    with socket.create_connection(("api.example.com", 443)) as raw:
        with ctx.wrap_socket(raw, server_hostname="api.example.com") as tls:
            der = tls.getpeercert(binary_form=True)
    print(ssl.DER_cert_to_PEM_cert(der))   # paste into a certificate decoder
  2. 2.

    更新 certifi 或操作系统的证书包

    如果服务器自身的证书没有问题,就更新客户端的根证书:对于使用 certifi 的库,运行 pip install --upgrade certifi;对于系统证书包,更新 ca-certificates 软件包。

    bash
    python3 -m pip install --upgrade certifi
    python3 -c "import certifi; print(certifi.__version__, certifi.where())"
  3. 3.

    校正系统时钟

    在客户端上启用 NTP(如果是容器,则在宿主机上启用)。

    bash
    date -u
    sudo timedatectl set-ntp true

相关错误

浏览完整的签名错误库