Curl 错误 60,SSL 证书问题:证书链中的自签名证书

Posted

技术标签:

【中文标题】Curl 错误 60,SSL 证书问题:证书链中的自签名证书【英文标题】:Curl error 60, SSL certificate issue: self signed certificate in certificate chain 【发布时间】:2014-02-06 21:42:12 【问题描述】:

我尝试使用正确的 APP_ID、APP_SECRET 等发送 curl 请求到

  https://oauth.vk.com/access_token?client_id=APP_ID&client_secret=APP_SECRET&code=7a6fa4dff77a228eeda56603b8f53806c883f011c40b72630bb50df056f6479e52a&redirect_uri=REDIRECT_URI 

我需要从中获取 access_token,但获取 FALSE 和 curl_error() 否则打印下一条消息:

60: SSL certificate problem: self signed certificate in certificate chain

我的代码是:

    // create curl resource
    $ch = curl_init();

    // set url
    curl_setopt($ch, CURLOPT_URL, $url);
    //return the transfer as a string
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

    // $output contains the output string
    $output = curl_exec($ch);
    if ( ! $output) 
        print curl_errno($ch) .': '. curl_error($ch);
    

    // close curl resource to free up system resources
    curl_close($ch);

    return $output;

当我手动移动到上面的链接时,我得到了 access_token。为什么它不适用于 curl?请帮忙。

【问题讨论】:

也许我需要获得带有.crt 扩展名的证书?但我不知道如何得到他 请避免 [broken] 接受的答案。请改用@erlangsec 的答案。另见The most dangerous code in the world: validating SSL certificates in non-browser software。 【参考方案1】:

不应接受建议禁用CURLOPT_SSL_VERIFYPEER 的答案。问题是“为什么它不适用于 cURL”,正如 Martijn Hols 正确指出的那样,这是危险的。

该错误可能是由于没有最新的 CA 根证书捆绑包引起的。这通常是一个带有一堆加密签名的文本文件,curl 使用它来验证主机的 SSL 证书。

您需要确保您的 php 安装有这些文件之一,并且它是最新的(否则在这里下载一个:http://curl.haxx.se/docs/caextract.html)。

然后set in php.ini:

curl.cainfo = <absolute_path_to> cacert.pem

如果您在运行时设置,请使用 (where $ch = curl_init();):

curl_setopt ($ch, CURLOPT_CAINFO, dirname(__FILE__)."/cacert.pem");

【讨论】:

谢谢,但我正在寻找使用外部 API 的建议。因此,提出@SabujHassan 的建议是可行的,而且据我所知,我使用的 API 不提供 SSL。 像魔术一样工作。这应该是答案,“接受的答案”很简单,但出于安全原因,这是一种不好的方式。 我有一个 Letsencrypt 证书可以很好地与 FileZilla 配合使用,有没有办法让 curl 来代替它? 值得注意的是 curl.cainfo 不会出现在 PHP 7.1/7.2 的 phpinfo() 中,但是 openssl.cafile 会出现。 php.net/manual/en/curl.configuration.php 如果我们不使用最新版本更新 cacert.pem 怎么办?如果 pem 文件中的任何证书过期怎么办?我们应该多久更新一次服务器上的 cacert.pem?【参考方案2】:

此解决方法危险不推荐

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

禁用 SSL 对等验证不是一个好主意。这样做可能会将您的请求暴露给 MITM 攻击者。

事实上,您只需要一个最新的 CA 根证书包。安装一个更新的很简单:

    从cURL website 下载最新的cacert.pem 文件和

    在您的 php.ini 文件中设置它的路径,例如在 Windows 上:

    curl.cainfo=c:\php\cacert.pem

就是这样!

保持安全。

【讨论】:

如果您无权编辑全局php.ini文件,也可以在代码中设置此选项:curl_setopt ($curl_ch, CURLOPT_CAINFO, dirname(__FILE__)."/cacert.pem"); 适合在开发环境中测试 这是一个可怕的建议,应该删除答案。 @miken32 是的,然后我建议使用替代安全解决方案来替代危险的解决方法。一直读到最后。 @AliKhosro 它是你在代码中初始化时从curl_init()返回的curl资源处理程序。【参考方案3】:

如果您的系统中没有正确安装 SSL 证书,您可能会收到以下错误:

cURL 错误 60:SSL 证书问题:无法获取本地颁发者 证书。

您可以通过以下方式解决此问题:

从https://curl.haxx.se/ca/cacert.pem下载包含更新后证书列表的文件

将下载的cacert.pem 文件移动到系统中的某个安全位置

更新您的php.ini 文件并配置该文件的路径:

【讨论】:

另外,您可能需要在 php.ini 中设置 openssl.cafile="C:/dev/ssl/mywebsite.local.crt"­【参考方案4】:

重要提示:这个问题让我发疯了几天,我无法弄清楚我的 curl 和 openssl 安装发生了什么。我终于发现是我的 intermediate 证书(在我的例子中是 GoDaddy)已经过时了。我回到我的 godaddy SSL 管理面板,下载了新的中间证书,问题就消失了。

我确定这对你们中的一些人来说是个问题。

显然,由于安全问题,GoDaddy 在某个时候更改了他们的中间证书,因为他们现在显示以下警告:

“请务必使用下载包中包含的新 SHA-2 中间证书。”

希望这对你们中的一些人有所帮助,因为我快疯了,这解决了我所有服务器上的问题。

【讨论】:

虽然与问题不完全相关,但总体上可能提供可行的信息。 curl 产生的错误消息有时可能是神秘的和误导性的,我敢肯定,由于我引用的怪癖,一些收到“自签名证书”错误的人会得到它。我还想补充一点,在构建 curl 时,我使用了配置字符串: ./configure --with-ca-bundle=/etc/ssl/certs/ca-bundle.crt 我还使用了 perl 脚本 lib/mk -ca-bundle.pl 生成一个漂亮的新鲜 ca-bundle.crt 文件。我使用的是 apache 网络服务器,但我没有用 Godaddy 更新的证书替换我现有的中间证书。【参考方案5】:

错误:SSL 证书问题:证书中的自签名证书 链

Solution:
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);    
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_FAILONERROR, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

【讨论】:

以上是关于Curl 错误 60,SSL 证书问题:证书链中的自签名证书的主要内容,如果未能解决你的问题,请参考以下文章

cURL 错误 60:SSL 证书问题:证书已过期

如何解决 youtube data api V3 中的 curl 错误 60:ssl 证书问题?

facebook auth cURL 错误 60:SSL 证书

XAMPP 配置 cURL 错误 60:SSL 证书

WORDPRESS : cURL 错误 60: SSL 证书

cURL 错误 60 - SSL 证书问题 - 无法获取本地颁发者