cURL错误60:SSL证书:无法获得本地颁发者证书

时间:2015-04-23 11:54:21

标签: php ssl curl wamp stripe-payments

我在本地开发环境中使用WAMP,并尝试从信用卡收费但收到错误消息:

  

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

我在Google上搜索了很多,很多人都建议我下载这个文件:cacert.pem,把它放在某处并在我的php.ini中引用它。这是我的php.ini中的一部分:

curl.cainfo = "C:\Windows\cacert.pem"

然而,即使多次重启我的服务器并更改路径,我也会得到相同的错误消息。

我使用Apache Modules中的WAMP并启用了ssl_module。从PGP扩展我启用了php_curl。

仍然是相同的错误消息。为什么会这样?

现在我正在关注此问题:How to fix PHP CURL Error 60 SSL

这表明我将这些行添加到我的cURL选项中:

curl_setopt($process, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem');
curl_setopt($process, CURLOPT_SSL_VERIFYPEER, true);

我在哪里为cURL添加选项?显然不是通过命令行,因为我的CLI没有找到命令" curl_setopt"

修改

这是我正在运行的代码:

public function chargeStripe()
{
    $stripe = new Stripe;
    $stripe = Stripe::make(env('STRIPE_PUBLIC_KEY'));

    $charge = $stripe->charges()->create([
        'amount'   => 2900,
        'customer' => Input::get('stripeEmail'),
        'currency' => 'EUR',
    ]);

    dd($charge);

    // echo $charge[Input::get('stripeToken')];


    return Redirect::route('step1');
}

22 个答案:

答案 0 :(得分:439)

工作解决方案:

  • 假设在Windows上
  

XAMPP服务器

与其他环境类似 - 在这里下载并解压缩cacert.pem(一个干净的文件格式/数据)

  

https://curl.haxx.se/docs/caextract.html

  • 把它放在这里
  

C:\ XAMPP \ PHP \额外\ SSL \ cacert.pem

    你在php.ini中的
  • 把这一行放在这一部分(" c:\ xampp \ php \ php.ini"):
;;;;;;;;;;;;;;;;;;;;
; php.ini Options  ;
;;;;;;;;;;;;;;;;;;;;

curl.cainfo = "C:\xampp\php\extras\ssl\cacert.pem"
  • 重新启动您的网络服务器/ apache

问题解决了!

(来源:https://laracasts.com/discuss/channels/general-discussion/curl-error-60-ssl-certificate-problem-unable-to-get-local-issuer-certificate

答案 1 :(得分:37)

如果你使用带有Guzzle的PHP 5.6,Guzzle已经转而使用PHP库自动检测证书而不是它的进程(ref)。 PHP概述了更改here

找出PHP / Guzzle在哪里寻找证书

您可以转储PHP正在使用的位置:

 var_dump(openssl_get_cert_locations());

获取证书包

对于OS X测试,您可以使用自制软件安装openssl brew install openssl,然后在php.ini或Zend Server设置中使用openssl.cafile=/usr/local/etc/openssl/cert.pem(在OpenSSL下)。

卷曲网站上的curl / Mozilla也提供了证书包:https://curl.haxx.se/docs/caextract.html

告知证书

的PHP

一旦你有了一个捆绑包,要么把它放在PHP已经看的地方(你在上面找到)或者在php.ini中更新openssl.cafile。 (通常,Unix上为/etc/php.ini/etc/php/7.0/cli/php.ini/etc/php/php.ini。)

答案 2 :(得分:27)

注意Wamp / Wordpress / windows用户。我有几个小时这个问题,甚至没有正确的答案是为我做的,因为我正在编辑错误的php.ini文件,因为问题是回答XAMPP而不是WAMP用户,即使问题是针对WAMP。

这就是我做的事情

下载certificate bundle.

将其放在C:\wamp64\bin\php\your php version\extras\ssl

确保文件mod_ssl.so位于C:\wamp64\bin\apache\apache(version)\modules

之内

在Apache目录mod_ssl

内的httpd.conf中启用C:\wamp64\bin\apache\apache2.4.27\conf

php_openssl.dll中启用php.ini。请注意我的问题是我有两个php.ini文件,我需要在这两个文件中执行此操作。第一个可以位于您的WAMP任务栏图标内。

enter image description here

,另一个位于C:\wamp64\bin\php\php(Version)

找到两个php.ini文件的位置,找到第curl.cainfo =行并为其指定一条路径

curl.cainfo = "C:\wamp64\bin\php\php(Version)\extras\ssl\cacert.pem"

现在保存文件并重新启动服务器,你应该好好去

答案 3 :(得分:13)

cartalyst/stripe使用的Guzzle将执行以下操作以查找适当的证书存档以检查服务器证书:

  1. 检查php.ini文件中是否设置了openssl.cafile
  2. 检查php.ini文件中是否设置了curl.cainfo
  3. 检查/etc/pki/tls/certs/ca-bundle.crt是否存在(Red Hat,CentOS,Fedora;由ca-certificates包提供)
  4. 检查/etc/ssl/certs/ca-certificates.crt是否存在(Ubuntu,Debian;由ca-certificates包提供)
  5. 检查/usr/local/share/certs/ca-root-nss.crt是否存在(FreeBSD;由ca_root_nss包提供)
  6. 检查/usr/local/etc/openssl/cert.pem(OS X;由自制软件提供)
  7. 检查C:\windows\system32\curl-ca-bundle.crt是否存在(Windows)
  8. 检查C:\windows\curl-ca-bundle.crt是否存在(Windows)
  9. 您需要确保通过执行简单测试正确定义前两个设置的值:

    echo "openssl.cafile: ", ini_get('openssl.cafile'), "\n";
    echo "curl.cainfo: ", ini_get('curl.cainfo'), "\n";
    

    或者,尝试将文件写入#7或#8指示的位置。

答案 4 :(得分:10)

如果您无法更改php.ini,您还可以从以下代码中指向cacert.pem文件:

$http = new GuzzleHttp\Client(['verify' => '/path/to/cacert.pem']);
$client = new Google_Client();
$client->setHttpClient($http);

答案 5 :(得分:6)

我所做的是在任何php脚本中使用var_dump(openssl_get_cert_locations()); die;,这给了我本地php正在使用的默认信息:

array (size=8)
  'default_cert_file' => string 'c:/openssl-1.0.1c/ssl/cert.pem' (length=30)
  'default_cert_file_env' => string 'SSL_CERT_FILE' (length=13)
  'default_cert_dir' => string 'c:/openssl-1.0.1c/ssl/certs' (length=27)
  'default_cert_dir_env' => string 'SSL_CERT_DIR' (length=12)
  'default_private_dir' => string 'c:/openssl-1.0.1c/ssl/private' (length=29)
  'default_default_cert_area' => string 'c:/openssl-1.0.1c/ssl' (length=21)
  'ini_cafile' => string 'E:\xampp\php\extras\ssl\cacert.pem' (length=34)
  'ini_capath' => string '' (length=0)

您可以注意到,我已经设置了ini_cafile或ini选项curl.cainfo。但在我的情况下,curl会尝试使用不存在的“default_cert_file”。

我将文件从https://curl.haxx.se/ca/cacert.pem复制到“default_cert_file”(c:/openssl-1.0.1c/ssl/cert.pem)的位置,我能够让它工作。

这是我唯一的解决方案。

答案 6 :(得分:5)

我找到了一个适合我的解决方案。我从最新的guzzle降级到版本~4.0并且它有效。

在composer.json中添加" guzzlehttp / guzzle":" ~4.0"

希望它有助于某人

答案 7 :(得分:5)

有一天,当Guzzle(5)脚本试图通过SSL连接到主机时,我出现了这个问题。当然,我可以在Guzzle / Curl中禁用VERIFY选项,但这显然不是正确的方法。

我在这里和类似的线程中尝试了所有,然后最终使用openssl进入终端来测试我尝试连接的域:

openssl s_client -connect example.com:443 

...并收到前几行表示:

CONNECTED(00000003)
depth=0 CN = example.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = example.com
verify error:num=21:unable to verify the first certificate
verify return:1 

...虽然在尝试其他目的地时一切正常(例如:google.com等)

这促使我联系了我一直试图连接的域名,事实上,他们在THEIR END上遇到了问题。它已经解决,我的脚本又恢复了工作。

所以...如果你要拔掉头发,请给openssl一个镜头,看看你试图连接的位置是否有任何响应。也许这个问题并非如此“本地化”。毕竟有时候。

答案 8 :(得分:1)

我刚刚使用Laravel 4 php框架遇到了同样的问题,该框架使用了guzzlehttp/guzzle composer包。出于某种原因,邮件枪的SSL证书突然停止验证,我收到了相同的“错误60”消息。

如果像我一样,您在无法访问php.ini的共享主机上,则无法使用其他解决方案。在任何情况下,Guzzle都有这个客户端初始化代码,很可能会使php.ini效果无效:

// vendor/guzzlehttp/guzzle/src/Client.php
    $settings = [
        'allow_redirects' => true,
        'exceptions'      => true,
        'decode_content'  => true,
        'verify'          => __DIR__ . '/cacert.pem'
    ];

这里Guzzle强制使用自己的内部cacert.pem文件,该文件现在可能已过时,而不是使用cURL's environment提供的文件。更改此行(至少在Linux上)将Guzzle配置为使用cURL的默认SSL验证逻辑并修复我的问题:

        'verify'          => true

如果您不关心SSL连接的安全性,也可以将其设置为false,但这不是一个好的解决方案。

由于vendor中的文件并非意图被篡改,因此使用configure the Guzzle client时会有更好的解决方案,但这在Laravel 4中实在太难了。

希望这可以节省其他人几个小时的调试时间......

答案 9 :(得分:1)

对于那些试图在本地计算机上使用 Wordpress 应用程序密码功能的人。您需要更新 wp-includes\certificates\ca-bundle.crt

在文本编辑器中打开此文件并附加您的服务器证书。

  1. 打开您的自签名证书 (.crt) 文件并

  2. 复制所有之间和包括

----BEGIN CERTIFICATE-----

-----结束证书-----

  1. 粘贴在 wp-includes\certificates\ca-bundle.crt 的末尾

答案 10 :(得分:1)

Guzzle 版本 5

这个默认配置对我来说很好用。它将禁用需要 https。

  $options = [
    'defaults' => ['verify' => false],
  ];
  new GuzzleClient($options);

其他情况要设置ca的路径,改为:

['verify' => '/path/to/cacert.pem']

答案 11 :(得分:1)

我使用 Centos 7 和免费版的 virtualmin。使用 Virtualmin,您可以创建一个 wordpress 网站。有一些功能会自动为您更新您的 ssl 证书。我注意到 /etc/httpd/conf/httpd.conf 不包含 SSLCertificateChainFile 的条目。应该将其设置为 /home/websitename/ssl.combined 之类的内容。相应地更新该文件并重新启动 apache 为我解决了这个问题。我在尝试为 wordpress 安装 jetpack 插件时发现了我的问题。在互联网上搜索使我意识到 I didn't have SSL Configured。我关注了 Redhat's instructions 如何安装证书。我希望这对某人有用。

答案 12 :(得分:1)

我花了太多时间为我解决这个问题。

我有PHP 5.5版,我需要升级到5.6。

在版本< 5.6 Guzzle将使用它自己的cacert.pem文件,但在更高版本的PHP中,它将使用系统的cacert.pem文件。

我还从这里https://curl.haxx.se/docs/caextract.html下载了文件,并在php.ini中设置了它。

在Guzzles StreamHandler.php文件中找到答案https://github.com/guzzle/guzzle/blob/0773d442aa96baf19d7195f14ba6e9c2da11f8ed/src/Handler/StreamHandler.php#L437

        // PHP 5.6 or greater will find the system cert by default. When
        // < 5.6, use the Guzzle bundled cacert.

答案 13 :(得分:1)

这可能是一个边缘情况,但在我的情况下问题不是客户端配置(我已经在 {中配置了 curl.cainfo {1}} ),而是未正确配置远程服务器:

它没有在链中发送任何中间证书。使用Chrome浏览网站时没有错误,但使用PHP时出现以下错误。

  

cURL错误60

在远程网络服务器配置中包含 Intermediate Certs 后,它就可以了。

您可以使用此站点检查服务器的SSL配置:

https://whatsmychaincert.com/

答案 14 :(得分:1)

确保您通过Window Explorer直接打开php.ini文件。 (在我的情况下:C:\DevPrograms\wamp64\bin\php\php5.6.25)。

请勿在系统托盘的Wamp / Xamp图标菜单中使用php.ini的快捷方式。在这种情况下,此快捷方式不起作用。

然后编辑php.ini

curl.cainfo ="C:/DevPrograms/wamp64/bin/php/cacert.pem" 

openssl.cafile="C:/DevPrograms/wamp64/bin/php/cacert.pem"

保存php.ini后,您不需要重新启动所有服务&#34;在Wamp图标中或关闭/重新打开CMD。

答案 15 :(得分:0)

当我运行'var_dump(php_ini_loaded_file());'时 我在我的页面上得到了这个输出 'C:\Development\bin\apache\apache2.4.33\bin\php.ini' (length=50)'

并让php加载我的证书文件我必须编辑此路径中的php.ini 'C:\Development\bin\apache\apache2.4.33\bin\php.ini' 并添加openssl.cafile="C:/Development/bin/php/php7.2.4/extras/ssl/cacert.pem"我已下载的位置,并从https://curl.haxx.se/docs/caextract.html

放置我的证书文件

am on Windows 10,使用drupal 8,wamp和php7.2.4

答案 16 :(得分:0)

所有答案都是正确的; 但最重要的是,您必须找到正确的php.ini文件。 在cmd中检查此命令“ php --ini”不是找到正确的php.ini文件的正确答案。

如果您编辑

curl.cainfo ="PATH/cacert.pem"

并检查

var_dump(openssl_get_cert_locations()); 

然后curl.cainfo应该有一个值。 如果不是,那不是正确的php.ini文件;

**我建议您在wamp / bin或xxamp / bin或您使用的任何服务器中搜索* .ini,并逐一更改并进行检查。 *

答案 17 :(得分:0)

我对此问题有正确的解决方案,让我们尝试了解此问题的根本原因。当无法使用系统证书存储区中的根证书来验证远程服务器ssl或未将远程ssl与链证书一起安装时,就会出现此问题。如果您的Linux系统具有root ssh访问权限,那么在这种情况下,您可以尝试使用以下命令更新证书存储:

update-ca-certificates

如果仍然无法运行,则需要在证书存储中添加远程服务器的根证书和临时证书。您可以下载根证书和中间证书,并将它们添加到 / usr / local / share / ca-certificates 目录中,然后运行命令 update-ca-certificates 。这应该可以解决问题。同样,对于Windows,您可以搜索如何添加根证书和中间证书。

解决此问题的另一种方法是要求远程服务器团队将ssl证书添加为域根证书,中间证书和根证书的捆绑包。

答案 18 :(得分:0)

对于WAMP,这终于对我有用。
尽管与其他类似,但此页面上提到的解决方案以及网络上的其他位置均无效。一些“次要”细节有所不同。
保存PEM文件的位置很重要,但是指定的位置不够清楚。
或要编辑的php.ini文件不正确。或两者兼有。
我正在Windows 10计算机上运行2020年的WAMP 3.2.0安装。

链接以获取pem文件:

http://curl.haxx.se/ca/cacert.pem
复制整个页面并将其另存为:cacert.pem,在下面提到的位置。

将PEM文件保存在此位置

<wamp install directory>\bin\php\php<version>\extras\ssl
例如保存的文件和路径:“ T:\ wamp64 \ bin \ php \ php7.3.12 \ extras \ ssl \ cacert.pem”

* (我最初将其保存在其他位置(并在php.ini文件中指出了保存的位置,但这没用)。 可能有也可能没有其他位置。这是推荐的位置-我不知道为什么。)

位置
<wamp install directory> = WAMP安装的路径。
例如:T:\wamp64\

WAMP正在运行的php的

<php version> :(要查找,请转到WAMP icon tray -> PHP <version number>
如果显示的版本号是7.3.12,则目录为:php7.3.12)
例如:php7.3.12

要编辑哪个php.ini文件

要打开正确的php.ini文件进行编辑,请转到:WAMP icon tray -> PHP -> php.ini
例如:T:\wamp64\bin\apache\apache2.4.41\bin\php.ini
注意:它不是php目录中的文件!

更新
当它看起来像我在编辑文件时,{em> :T:\wamp64\bin\apache\apache2.4.41\bin\php.ini
实际上是在编辑该文件的符号链接目标:T:/wamp64/bin/php/php7.3.12/phpForApache.ini

请注意,如果按照上述说明进行操作,则不是直接编辑php.ini文件。您实际上是在编辑phpForApache.ini文件。 (有关symlinks的信息)

如果您阅读了各个WAMP目录中php.ini文件的 some 顶部的注释,则会特别声明不要编辑该特定文件。
确保您打开供编辑的文件不包含此警告。

安装扩展名Link Shell Extension后,我可以通过添加的选项卡在文件“属性”窗口中查看符号链接的目标。这是我的SO answer,其中包含有关此扩展程序的更多信息。

如果您在不同时间运行各种版本的php,则可能需要将PEM文件保存在每个相关的php目录中。

要在php.ini文件中进行的修改:

在以下位置粘贴PEM文件的路径。

  • 取消注释;curl.cainfo =,然后粘贴到PEM文件的路径。
    例如:curl.cainfo = "T:\wamp64\bin\php\php7.3.12\extras\ssl\cacert.pem"

  • 取消注释;openssl.cafile=,然后粘贴到PEM文件的路径。
    例如:openssl.cafile="T:\wamp64\bin\php\php7.3.12\extras\ssl\cacert.pem"

积分:

虽然不是官方资源,但这是指向YouTube视频的链接,其中为我整理了最后的详细信息:https://www.youtube.com/watch?v=Fn1V4yQNgLs

答案 19 :(得分:0)

你试过..

curl_setopt($process, CURLOPT_SSL_VERIFYPEER, false);

如果您正在使用受信任的来源,可以说您不需要验证SSL证书。

答案 20 :(得分:-1)

当您使用Windows时,我认为您的路径分隔符是&#39; \&#39; (以及&#39; /&#39;在Linux上)。 尝试使用常量DIRECTORY_SEPARATOR。您的代码将更加便携。

尝试:

curl_setopt($process, CURLOPT_CAINFO, dirname(__FILE__) . DIRECTORY_SEPARATOR . 'cacert.pem');

编辑:并写出完整路径。我有一些相对路径的问题(也许curl是从另一个基本目录执行的?)

答案 21 :(得分:-1)

如果您使用WAMP,您还应该在php.ini中为Apache添加证书行(除了默认的php.ini文件):

[curl]
curl.cainfo = C:\your_location\cacert.pem

适用于php5.3 +