通过cURL登录HTTPS网站时SSL本地颁发者证书获取失败求助
解决PHP cURL SSL证书错误:unable to get local issuer certificate error
首先,我们来分析你的问题:你已经配置了php.ini的.pem路径,也在代码里指定了CA证书,但还是遇到了证书验证失败的报错。这通常和证书链不完整、路径错误或权限问题有关,下面是具体的排查和解决步骤:
问题重现
你使用的代码及报错:
$fields['username'] = "Pass@1234"; $fields['password'] = "harsha"; // set postfields using what we extracted from the form $POSTFIELDS = http_build_query($fields); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://website.com'); curl_setopt($ch, CURLOPT_POSTFIELDS,$POSTFIELDS); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_COOKIEJAR, "cookies.txt"); curl_setopt($ch, CURLOPT_COOKIEFILE, "cookies.txt"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt($ch, CURLOPT_CAINFO, getcwd() . "/abc.crt"); curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3"); curl_setopt($ch, CURLOPT_REFERER, "https://website.com"); $page = curl_exec($ch) or die(curl_error($ch)); echo $page;报错信息:
SSL certificate problem unable to get local issuer certificate error
解决步骤
1. 确认CA证书是完整的证书链
你代码里指定的abc.crt可能只包含了目标网站的服务器证书,缺少中间证书和根证书。cURL需要完整的证书链才能验证证书的发行方(issuer)是否可信。
- 操作方法:
- 用浏览器访问
https://website.com,点击地址栏的锁图标,查看证书详情,导出包含根证书、中间证书和服务器证书的完整链(选择PEM格式保存)。 - 替换你当前的
abc.crt文件为这个完整的证书链文件。
- 用浏览器访问
2. 验证证书文件路径是否正确
getcwd()返回的是PHP当前工作目录,这个目录可能和你预期的不一样(比如Web服务器的根目录和脚本所在目录不同)。
- 操作方法:
- 在代码里临时添加一行
echo getcwd();,运行脚本后确认路径是否包含abc.crt文件。 - 如果路径不对,直接使用绝对路径指定证书文件,比如:
curl_setopt($ch, CURLOPT_CAINFO, "/var/www/html/abc.crt");(根据你的实际路径调整)。
- 在代码里临时添加一行
3. 排查php.ini配置与代码的冲突
你提到已经在php.ini里配置了.pem文件,但代码里又用CURLOPT_CAINFO指定了另一个证书,这会优先使用代码里的设置,而忽略php.ini的配置。
- 操作方法:
- 如果你想依赖php.ini的配置,删除代码中的
CURLOPT_CAINFO行。 - 确保php.ini里的
curl.cainfo和openssl.cafile指向的是完整的CA证书包(比如Mozilla官方维护的CA证书集合),修改后必须重启Web服务器和PHP-FPM才能生效。
- 如果你想依赖php.ini的配置,删除代码中的
4. 检查证书文件的权限
运行PHP的Web服务器进程(比如Apache的www-data用户)可能没有读取abc.crt的权限,导致无法加载证书。
- 操作方法:
- 执行命令修改权限:
chmod 644 /path/to/abc.crt - 调整文件所有者:
chown www-data:www-data /path/to/abc.crt(根据你的服务器用户调整)
- 执行命令修改权限:
5. 临时调试(仅用于排查,禁止生产环境)
如果以上步骤都无效,可以临时关闭SSL验证来确认问题是否出在证书环节:
// 仅用于调试,生产环境绝对不能启用 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
如果关闭后能正常请求,说明问题确实在证书验证,回到前面的步骤重新排查证书链和路径。
内容的提问来源于stack exchange,提问作者harsha ambadkar
相关产品推荐
相关产品推荐

