You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

为何在Windows环境下执行curl命令可永久解决Python的SSL证书验证失败问题?

为何在Windows环境下执行curl命令可永久解决Python的SSL证书验证失败问题?

这真是个挺有意思的“玄学”问题,其实背后是Windows系统证书机制在起作用,我来给你拆解清楚:

先还原你的场景

你在VMware Fusion上装了全新的Windows 11虚拟机,用winget装了Python 3.11,首次用urllib.request访问Google时,遇到了经典的SSL证书验证失败错误:

urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1006)>

但只要在PowerShell里跑一次curl https://www.google.com(哪怕只是触发了那个短暂的终端提示),之后Python的请求就永久正常了,能返回预期的200状态码。

背后的核心原因:Windows的自动根证书更新

  1. 全新系统的证书缺口
    刚装完的Windows虚拟机(尤其是VM环境),系统的「受信任的根证书颁发机构」存储里可能缺了一些常用的根CA证书——比如Google网站SSL证书对应的根颁发机构证书。

  2. 系统工具触发自动补全
    你用的PowerShellcurl其实是Invoke-WebRequest的别名(就算直接用curl.exe原生工具也一样),它们都是完全依赖Windows系统SSL栈的工具。当你第一次执行curl访问Google时:

    • 工具在验证SSL证书链时,发现缺少对应的根证书
    • 自动触发Windows的「自动根证书更新」服务(默认是开启的),这个服务会悄悄连接Microsoft的服务器,下载并安装缺失的根证书到系统的信任存储里
    • 你看到的那个一闪而过的终端提示,就是系统在后台完成证书下载、安装的过程
  3. Python后续请求的依赖逻辑
    Python的urllib.request模块在Windows上,默认使用系统的SSL库,并且会读取系统「受信任的根证书颁发机构」存储里的证书做验证。但它的首次请求逻辑不会主动触发根证书的自动更新流程,所以一开始才会报错。而当系统存储补全根证书后,后续的Python请求自然就能正常验证SSL证书了。

为什么curlcurl.exe都有效?

不管是PowerShell的curl别名(指向Invoke-WebRequest)还是原生curl.exe,它们在Windows上都调用系统级的SSL验证逻辑,都会触发根证书的自动更新机制,所以最终效果完全一致。


备注:内容来源于stack exchange,提问作者asmaier

火山引擎 最新活动