SSL/TLS 握手中的某个位置出现问题

2022-08-30 19:06:41

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

返回的 cURL 错误为 35:

SSL/TLS 握手时出现问题。

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

设置证书时,我按照本教程本教程的说明进行操作,尝试为我请求的资源下载证书,并下载证书捆绑包。

我还尝试将CURLOP_PORT显式设置为443。为了彻底解决问题,我设置的其他选项是CURLOPT_VERBOSE=true,CURLOPT_RETURNTRANSFER=true和CURLOPT_SSL_VERIFYHOST=2(我已经尝试了1和2的所有组合,VERIFYPEER都真和假)。我还确保我有OpenSSL并且它已启用。phpinfo()

我使用了很多旧代码,这些代码在我上一个生产服务器上工作得很好,所以这段代码以前也工作过。但是那个托管是共享托管,我不知道那里的大部分配置。


答案 1

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


答案 2

怎么样。它获取可能是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
?>

推荐