22

我在我的开发服务器上遇到了问题,其中 cURL 虽然可以完美地与任何 HTTP 一起工作,但不能与任何 HTTPS 一起正常工作——即使是具有不同协议的完全相同的资源(为了测试我一直在使用两种 HTTP 请求 google.com和 HTTPS)。

返回的 cURL 错误为 35:

SSL/TLS 握手中某处出现问题。

我已经梳理了网络和 SO 的解决方案,所有这些都是将 CURLOPT_SSL_VERIFYPEER 设置为 false,这不会改变任何内容,或者下载证书文件并将 CURLOPT_CAINFO 设置为其路径,这也不会改变任何内容。

设置证书时,我按照本教程本教程的说明,尝试下载我请求的资源的证书,并下载证书包。

我还尝试将 CURLOP_PORT 显式设置为 443。为了我的问题的彻底性,我设置的其他选项是 CURLOPT_VERBOSE=true、CURLOPT_RETURNTRANSFER=true 和 CURLOPT_SSL_VERIFYHOST=2(我已经尝试了 1 和 2 的每种组合以及 VERIFYPEER 都为 true和错误的)。我还确保phpinfo()我有 OpenSSL 并且它已启用。

我使用了很多在我的最后一个生产服务器上完美运行的旧代码,所以这段代码以前也可以运行。但是那个主机是共享主机,我不知道那里的大部分配置。

4

4 回答 4

25

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

于 2013-07-01T16:36:05.503 回答
12

这个怎么样。它获取可能是 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
?>
于 2012-03-21T01:35:51.643 回答
6

查找您的操作系统是否包含证书目录。如果是这样,那么通常已经包含所需的 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');

关闭对等和主机验证是解决实际问题的快速但不安全的解决方法。这些功能的存在是有充分理由的:因此您可以通过第 3 方相信您正在连接的系统是您所期望的。

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
于 2017-06-05T15:23:52.240 回答
0
var_dump( curl_error($ch) );

会告诉你错误。可能是不同的原因。

于 2019-12-02T22:03:53.213 回答