一份修复"SSL Certificate Problem: Unable to get Local Issuer Certificate"(SSL 证书问题:无法获取本地颁发者证书)错误的简明指南。
当你尝试为 HTTPS 连接发起 cURL 请求时,可能遇到"SSL Certificate Problem: Unable to get Local Issuer Certificate"错误。即便修改或核实了 cURL 请求,仍可能面对该错误。下面我们了解一下这个 SSL 错误。
什么是"Unable to get Local Issuer Certificate"错误?
该错误通常在根证书配置不当时出现。用户发送 HTTPS 请求,此时会共享 SSL 证书以验证身份;若根证书配置不当,便会触发"Unable to get Local Issuer Certificate"错误。
导致该错误的原因
其根源是客户端与服务器在 SSL 通信期间根证书与中间证书配置错误。当你向 HTTPS 源发起请求时,根证书未能正常工作,而此时你需要出示自己的 SSL 证书做身份核验。
此外,使用自签名 SSL 证书也是一大原因。浏览器与操作系统遇到此类无法识别的证书会报错。自签名证书常用于内部服务器或测试环境。
如何修复"Unable to get Local Issuer Certificate"
针对 .PEM 与 .CRT 两种文件格式各有方案,先讲 .PEM 相关。
.PEM 格式相关方案
修改 php.ini(保持 SSL 开启)
php.ini 是 PHP 脚本运行时的配置文件,位于系统盘 PHP 安装目录内。编辑步骤如下:
- 下载 cacert.pem(可从 curl 官方 CA 证书地址获取);
- 将 cacert.pem 复制到你所用的 zend/openssl 目录;
- 打开 php.ini,添加 curl.cainfo 指向该文件;
- 重启 PHP 并检查 cURL 能否读取 HTTPS URL。
示例配置:
curl.cainfo = "/usr/local/openssl-0.9.8/certs/cacert.pem"
不修改 php.ini(保持 SSL 开启)
也可不改动 php.ini,在代码中指定证书位置:
$ch = curl_init();
$certificate_location = "/usr/local/openssl-0.9.8/certs/cacert.pem";
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $certificate_location);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $certificate_location);
禁用 SSL(不推荐)
另一种排障思路是关闭证书验证再重新开启,但即便能解决问题也不推荐。禁用 SSL 证书验证会绕过安全措施,使连接易被拦截,带来中间人攻击与数据泄露等重大风险。代码如下:
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
以上三种方案可修复 .PEM 格式的该错误,下面看 .CRT 格式相关方案。
.CRT 格式相关方案
获取 SSL 证书包(CA Bundle)
更新 CA 包,获取当前所有根证书与中间证书用于校验 SSL 连接。流程包括从可信资源获取证书颁发机构的新证书,将 CA Bundle 文件保存到服务器(建议放在服务器顶层,例如 C:/xampp/htdocs/_certs/ca-bundle.crt)。
编辑 php.ini
在 XAMPP 中可通过控制面板"Config"按钮找到 php.ini;不同服务器位置各异,默认在 /etc 目录。找到后加入以下行:
[CA Certs]
curl.cainfo="C:/xampp/htdocs/_certs/ca-bundle.crt"
openssl.cafile="C:/xampp/htdocs/_certs/ca-bundle.crt"
重启 PHP
不同服务器重启方式不同:XAMPP 在控制面板先关 Apache 再开;Linux 服务器可用 service php-fpm restart 之类命令。
Git 服务器场景的修复
多数 Git 用户也会遇到该错误,以下针对 Git 服务器给出办法。错误有时源于自签名证书(用于内部测试环境),企业也常因此类内部服务证书而触发。
修改 php.ini(cPanel)
在控制面板中可创建/编辑 php.ini,即便在虚拟主机上也容易操作:
- 登录 cPanel;
- 进入 File Manager >> PHP Software;
- 打开 php.ini 文件;
- 下载 cacert.pem 并复制到 openssl/zend 目录;
- 在 php.ini 中添加 curl.cainfo 指向该文件;
- 重启 PHP 并检查 cURL 能否读取 HTTPS URL。
将 SSL 证书加入受信任证书存储
在 GIT bash 中遇到该错误时,可尝试把 SSL 证书加入受信任证书存储:
- 复制 Git SSL 证书;
- 进入受信任证书存储(通常位于 C:\Program Files\Git\mingw64\ssl\certs);
- 打开其中的 ca-bundle.crt 文件;
- 将复制的 Git SSL 证书粘贴到 .crt 文件末尾;
- 保存文件使更改生效。
重装 Git 并选择 SSL Transport Backend
卸载 Git 后重新安装,过程中务必勾选 SSL Transport Backend 选项以正确配置。
在 VS Code 中允许仓库访问 SSL 证书或重设路径
若错误出现在 VS Code:
git config --global http.sslBackend schannel
git config --system http.sslBackend schannel
git config --global http.sslcainfo "Path"
停用 SSL 证书(不推荐)
停用 SSL 不推荐,因网络恶徒可能借机作恶。Git 可在本地或全局层面禁用:
# 本地级别
git -c http.sslVerify=false clone [URL]
# 全局级别
git config --global http.sslVerify false
# 重新启用
git config --global http.sslVerify true
总结
上述针对浏览器端与 Git 服务器的方案都能修复"SSL certificate problem: unable to get local issuer certificate"错误。与其卸载 SSL 证书,不如选用以上任一或全部方案来修复——你的网站需要防范网络威胁的保护。