记录一次 Windows 下 curl 报错 SEC_E_UNTRUSTED_ROOT (0x80090325) 的排查与解决
前言
今天在 Windows 环境下使用 curl 请求 GitHub 接口时,突然遇到了一个证书信任报错。虽然浏览器访问 GitHub 一切正常,但命令行里的 curl 却死活连不上。
折腾了一圈后发现,问题出在 Windows 系统的“受信任根证书”未及时更新上。这里记录一下完整的排查过程和最简单的解决方法,希望能帮到遇到同样问题的朋友。
报错现象
执行命令:
curl -v https://github.com
返回如下错误信息:
* Host github.com:443 was resolved.
* IPv6: (none)
* IPv4: 20.205.243.166
* Trying 20.205.243.166:443...
* schannel: disabled automatic use of client certificate
* ALPN: curl offers http/1.1
* schannel: SEC_E_UNTRUSTED_ROOT (0x80090325) - 证书链是由不受信任的
* closing connection #0
curl: (60) schannel: SEC_E_UNTRUSTED_ROOT (0x80090325) - 证书链是由不受信任的...
排查过程
为什么浏览器正常,curl 却报错?
注意到报错里有一个关键词:schannel。这是 Windows 系统自带的 TLS/SSL 安全通道组件。
Windows 版的 curl 在编译时如果使用了 Schannel,它就会直接读取 Windows 系统内部的“受信任根证书颁发机构”存储来校验 HTTPS 证书。而我们的浏览器(如 Chrome、Edge)往往有自己独立的证书更新机制,或者会触发系统的在线更新,所以浏览器能正常打开,但 curl 用的底层证书库可能已经过期或缺漏。
解决方案
既然确认是 Windows 系统的根证书不全/过旧,最直接的方法就是让系统主动去拉取最新的根证书列表并导入。
只需以管理员身份打开 CMD 或 PowerShell,依次执行以下三行命令即可:
第一步:从 Windows Update 获取最新的根证书列表
使用系统自带的 certutil 工具生成一个包含最新受信任根证书的 .sst 文件:
certutil -generateSSTFromWU roots.sst
(执行后,当前目录下会生成一个 roots.sst 文件)
第二步:将根证书导入到系统的“受信任的根证书颁发机构”
certutil -addstore -f "Root" roots.sst
(这一步会把刚才下载的最新根证书强制写入系统的 Root 证书存储中)
第三步(可选):清理临时文件
del roots.sst
注意: 导入完成后,建议关闭并重新打开你的命令行终端,以确保新启动的进程能够重新加载最新的证书库。
再次执行curl https://github.com,问题完美解决!
看看其他吧