Python 3.13+ ssl modulePython cryptography 库
错误信息
[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Missing Authority Key Identifier
Python 3.13 及更高版本(默认开启严格模式)以及 openssl verify -x509_strict 会显示这条消息。Python 还会附加源代码位置,例如“(_ssl.c:1082)”。
Python 3.13+ ssl module — VERIFY_X509_STRICT in create_default_context(), X509_V_ERR_MISSING_AUTHORITY_KEY_IDENTIFIER
含义
Python 3.13+ 会执行 OpenSSL 的严格 X.509 检查,而 RFC 5280 要求由 CA 签发的证书带有 authorityKeyIdentifier 扩展,用来标识颁发者的密钥。你的证书链中有一张证书缺少这个扩展,因此即使签名和信任锚都没有问题,验证仍会失败。
原因
签发工具不添加密钥标识符
常见手写的 OpenSSL 扩展配置文件、某些脚本以及较旧的内部 CA 软件,签发的证书不带 authorityKeyIdentifier(往往也不带 subjectKeyIdentifier)。
客户端升级到了 Python 3.13+
常见Python 3.12 及更早版本不执行严格检查,所以这些证书以前能正常使用。
早期 PKI 配置下签发的长期证书
偶见多年前、在证书模板修正之前签发的设备证书和服务证书,会一直使用到过期为止。
修复方法
- 1.
确认缺少的扩展
输出叶子证书和中间证书的密钥标识符扩展,并运行 openssl verify -x509_strict,列出所有严格模式下的问题。
bash openssl x509 -in server.pem -noout -ext authorityKeyIdentifier,subjectKeyIdentifier openssl verify -x509_strict -CAfile ca.pem server.pem - 2.
带上密钥标识符重新签发证书
在签发模板中添加 subjectKeyIdentifier = hash 和 authorityKeyIdentifier = keyid:always,然后重新签发受影响的证书。
bash # Issue leaves with both key identifiers printf 'subjectKeyIdentifier=hash\nauthorityKeyIdentifier=keyid:always\nsubjectAltName=DNS:api.example.com\n' > leaf.ext openssl x509 -req -in server.csr -CA ca.pem -CAkey ca.key -days 90 -extfile leaf.ext -out server.pem - 3.
临时规避方案:清除 VERIFY_X509_STRICT
保留证书链、日期和主机名的验证,但在这个上下文中跳过 RFC 5280 的证书规范检查;重新签发后应去掉这项设置。
python # Temporary workaround until certificates are reissued import ssl ctx = ssl.create_default_context(cafile="ca.pem") ctx.verify_flags &= ~ssl.VERIFY_X509_STRICT