Windows下Python Requests验证自签名CA证书异常问题求助
问题:Windows下Python Requests验证自签名CA证书异常
我使用Python requests模块调用Windows平台上.NET编写的Web API,自行搭建CA并签署了服务器CSR,已将签署后的证书部署到服务器。
测试情况
- Chrome访问本地API失败(符合预期);将自签名CA证书添加到Chrome受信任根CA列表后可正常访问(符合预期)。
- Python环境中,
requests.get的verify参数指向CA证书时验证失败,提示“证书为自签名”;指向服务器签名证书则验证成功。
补充:Ubuntu系统中,requests仅通过CA证书即可完成验证,该问题仅出现在Windows环境。
请问:
- “仅需将verify指向CA证书即可完成验证”的说法是否正确?
- 当前Windows下的表现是否为预期行为?
回答
关于“verify指向CA证书即可验证”的说法
该说法本身是正确的。正常流程中,requests通过CA证书验证服务器证书的签发链:只要服务器证书由目标CA签发,且CA证书可信,就能通过验证。
Windows下的异常是否为预期行为
这种表现不属于预期行为,问题通常源于以下几个方面:
- CA证书格式不兼容:Windows对PEM格式证书的解析逻辑与Linux有差异,如果你的CA证书仅为纯PEM格式(缺少完整证书链信息或格式不符合Windows要求),requests无法正确解析验证链;而直接指定服务器证书时,相当于跳过链验证,直接信任了服务器证书本身。
- Windows平台下requests的证书读取逻辑:requests在Windows上默认调用系统CA存储,但手动指定
verify参数后,会忽略系统存储,仅使用你提供的证书文件。若CA证书文件未包含根CA的完整必要信息(如缺失关键扩展、格式不是DER/PEM兼容的正确形式),就会触发验证失败。 - 服务器证书链配置不全:若.NET Web API未正确配置完整证书链(未将CA证书作为中间证书一起部署),Windows下的requests无法自动补全链信息,而Linux的OpenSSL环境可能能自动处理这类情况,导致跨平台表现不一致。
解决建议
- 确保CA证书是完整的PEM格式文件,包含根CA的全部必要字段与扩展,避免仅包含公钥部分。
- 尝试将CA证书安装到Windows系统的「受信任根证书颁发机构」中,调用requests时不指定
verify参数(让其自动使用系统CA存储),验证是否能正常通过。 - 检查.NET服务器的证书配置,确保握手时返回完整的证书链(服务器证书+CA证书)。
内容的提问来源于stack exchange,提问作者Targett-Adams
相关产品推荐
相关产品推荐

