我最近为客户开发了一个复杂的系统,其中涉及 PHP、cURL 和与第三方供应商的 SSL 连接。第三方供应商将验证源(我创建的系统)的安全证书并允许或拒绝访问。我的代码如下所示:
$ch = curl_init(); curl_setopt($ch,CURLOPT_URL,'https://thirdparty.com/token.php'); //not the actual site curl_setopt($ch,CURLOPT_TIMEOUT,60); curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); curl_setopt($ch,CURLOPT_POST,1); curl_setopt($ch,CURLOPT_POSTFIELDS,'customer_id='.$cid.'&password='.$pass); curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,true); curl_setopt($ch,CURLOPT_CAINFO,'ca-bundle.crt'); /* problem here! */ $result = curl_exec($ch); if(empty($result)) { /* error: nothing returned */ } else { /* success! */ } curl_close($ch);
不幸的是,我一直收到以下错误消息:
错误:14090086:SSL 例程:SSL3_GET_SERVER_CERTIFICATE:证书验证失败
错误:14090086:SSL 例程:SSL3_GET_SERVER_CERTIFICATE:证书验证失败
事实证明,我使用的 SSL 捆绑文件是旧的,旧版本的 cURL 共享托管服务器附带的默认捆绑包也是如此。
本质上,第三方不相信系统的 SSL 证书是有效的。
我下载了 Mozilla 的捆绑文件,将其命名为 mozilla.pem 并将我的 PHP 代码更改为:
$ch = curl_init(); curl_setopt($ch,CURLOPT_URL,'https://thirdparty.com/token.php'); //not the actual site curl_setopt($ch,CURLOPT_TIMEOUT,60); curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); curl_setopt($ch,CURLOPT_POST,1); curl_setopt($ch,CURLOPT_POSTFIELDS,'customer_id='.$cid.'&password='.$pass); curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,true); curl_setopt($ch,CURLOPT_CAINFO,'mozilla.pem'); /* fixed! */ $result = curl_exec($ch); if(empty($result)) { /* error: nothing returned */ } else { /* success! */ } curl_close($ch);
我与您分享这个是因为它花了我三个多小时。希望这会在将来节省一些人的时间和挫败感。