我的开发服务器上遇到了问题,其中cURL与任何HTTP完美配合,无法正常运行任何HTTPS - 即使是完全相同的资源和不同的协议(用于测试我一直在请求google.com使用http和https)。
返回的cURL错误是35:“SSL / TLS握手中某处出现问题。”
我已经梳理了网络和SO以获得解决方案,所有这些都是将CURLOPT_SSL_VERIFYPEER设置为false,不进行任何更改,或者下载证书文件并将CURLOPT_CAINFO设置为其路径,这也不会改变任何内容。
设置证书时,我按照this tutorial和this tutorial的说明,尝试下载我请求的资源的证书,并下载证书包。
我也尝试过明确地将CURLOP_PORT设置为443.为了彻底解决我的问题,我设置的其他选项是CURLOPT_VERBOSE = true,CURLOPT_RETURNTRANSFER = true,CURLOPT_SSL_VERIFYHOST = 2(我已经尝试了1和2的每个组合VERIFYPEER都是真的和假的)。我也确定在phpinfo()中我有OpenSSL并且它已启用。
我正在使用很多旧代码,这些代码在我的上一个生产服务器上运行得非常好,所以这段代码以前都有用过。但是这个托管是共享托管,我不知道那里的大部分配置。
答案 0 :(得分:21)
Curl没有内置的根证书(就像大多数现代浏览器一样)。您需要将其明确指向cacert.pem文件:
curl_setopt($ch, CURLOPT_CAINFO, '/path/to/cert/file/cacert.pem');
如果没有这个,curl无法验证通过ssl发回的证书。每次在curl中使用SSL时,都可以使用相同的根证书文件。
您可以在此处获取cacert.pem文件:http://curl.haxx.se/docs/caextract.html
答案 1 :(得分:11)
这个怎么样?它提取了可能是HTTPS Google主页的内容。 (由于我已禁用证书验证,因此我无法真正知道它是真正的Google主页。)它应该为您解决问题。
<?PHP
// connect via SSL, but don't check cert
$handle=curl_init('https://www.google.com');
curl_setopt($handle, CURLOPT_VERBOSE, true);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false);
$content = curl_exec($handle);
echo $content; // show target page
?>
答案 2 :(得分:5)
查看您的操作系统是否包含证书目录。如果是这样,那么通常已经包含所需的CA证书。例如,在Ubuntu上,它通常是/etc/ssl/certs
。如果此目录存在,请设置CA路径参数:
curl_setopt($ch, CURLOPT_CAPATH, '/etc/ssl/certs');
或者,您可以引用单个CA证书文件。在项目中包含cacert.pem文件或将其安装在您的服务器上。从受信任的来源下载,例如cacert.org。对于单个文件,不要设置CAPATH,而只设置CAINFO:
curl_setopt($ch, CURLOPT_CAINFO, '/path/to/cacert.pem');
关闭同行和主机验证是解决实际问题的快速但不安全的解决方法。这些功能存在的原因很充分:因此您可以通过第三方信任您所连接的系统是您期望的系统。
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
答案 3 :(得分:0)
var_dump( curl_error($ch) );
会告诉您错误。可能是不同的原因。