我试图用Stripe发送一个API请求,但得到错误消息:

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

这是我正在运行的代码:

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',
    ]);

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

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

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

然而,即使在重新启动服务器几次并更改路径之后,我仍然得到相同的错误消息。

我在Apache中启用了ssl_module,在我的php.ini中启用了php_curl。

我还尝试了这个修复:如何修复PHP CURL错误60 SSL

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

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

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


当你在使用Windows时,我认为你的路径分隔符是'\'(在Linux上是'/')。 尝试使用常量DIRECTORY_SEPARATOR。您的代码将更易于移植。

Try:

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

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


你试过…

curl_setopt($process, CURLOPT_SSL_VERIFYPEER, false);

如果你想冒着被中间人攻击的风险,你可以跳过验证。


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

Check if openssl.cafile is set in your php.ini file. Check if curl.cainfo is set in your php.ini file. Check if /etc/pki/tls/certs/ca-bundle.crt exists (Red Hat, CentOS, Fedora; provided by the ca-certificates package) Check if /etc/ssl/certs/ca-certificates.crt exists (Ubuntu, Debian; provided by the ca-certificates package) Check if /usr/local/share/certs/ca-root-nss.crt exists (FreeBSD; provided by the ca_root_nss package) Check if /usr/local/etc/openssl/cert.pem (OS X; provided by homebrew) Check if C:\windows\system32\curl-ca-bundle.crt exists (Windows) Check if C:\windows\curl-ca-bundle.crt exists (Windows)

你需要通过一个简单的测试来确保前两个设置的值是正确定义的:

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

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


我找到了一个适合我的解决办法。我把最新的版本降级到4.0,它是有效的。

在作曲家。添加“guzzlehttp/guzzle”:“~4.0”

希望它能帮助到别人


如果你在Guzzle中使用PHP 5.6, Guzzle已经切换到使用PHP库自动检测证书,而不是它的进程(参考)。PHP在这里概述了这些变化。

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

你可以使用下面的PHP命令转储PHP正在寻找的地方:

 var_dump(openssl_get_cert_locations());

获取证书包

对于OS X测试,可以先使用homebrew安装openssl,再使用openssl.cafile=/usr/local/etc/openssl/cert。在您的php.ini或Zend服务器设置(在OpenSSL下)中的pem。

证书包也可以从curl/Mozilla的curl网站上获得:https://curl.haxx.se/docs/caextract.html

告诉PHP证书在哪里

一旦你有了一个bundle,要么把它放在PHP已经在寻找的地方(上面你已经发现了),要么更新openssl。php.ini中的Cafile。(一般在Unix上是/etc/php.ini或/etc/php/7.0/cli/php.ini或/etc/php/php.ini)


如何解决这个问题:

下载并提取cacert。请参考https://curl.se/docs/caextract.html上的说明 将它保存在文件系统的某个地方(例如,XAMPP用户可能使用C:\ XAMPP \php\extras\ssl\cacert.pem) 在你的php.ini中,把这个文件的位置放在[curl]部分(把它放在[openssl]部分也是一个好主意):

[curl]
curl.cainfo = "C:\xampp\php\extras\ssl\cacert.pem"

[openssl]
openssl.cafile = "C:\xampp\php\extras\ssl\cacert.pem"

重启您的web服务器(例如Apache)和PHP FPM服务器(如果适用)

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


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

我在类似的线程中尝试了这里列出的所有内容,然后最终使用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等)时,一切都很好

这促使我联系了我一直试图连接的域名,事实上,他们在他们的一端有一个问题,已经悄然出现。问题解决了,我的剧本又开始运作了。

所以…如果您非常着急,请尝试openssl,并查看您试图连接的位置的响应是否有任何变化。也许有时候这个问题并不那么“地方性”。


如果你无法更改php.ini,你也可以指向cacert。Pem文件的代码如下:

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

我所做的是使用var_dump(openssl_get_cert_locations());死;在任何PHP脚本中,它给了我关于本地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. cannfo。但在我的情况下,curl将尝试使用“default_cert_file”,它并不存在。

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

这是我唯一的解决办法。


请确保您直接通过windows资源管理器打开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" 

and

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

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


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

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

适用于php5.3+


我刚刚在使用guzzlehttp/guzzle composer包的Laravel 4 php框架中遇到了同样的问题。出于某种原因,mailgun的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环境提供的文件。修改这一行(至少在Linux上)配置Guzzle使用cURL的默认SSL验证逻辑,并解决了我的问题:

由于vendor中的文件并不意味着被篡改,一个更好的解决方案是在使用时配置Guzzle客户端,但这在Laravel 4中太难做到了。

希望这为其他人节省了几个小时的调试时间……


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

以下是我所做的:

Download the certificate bundle. Put it inside of C:\wamp64\bin\php\your php version\extras\ssl Inside of C:\wamp64\bin\apache\apache(version)\modules, make sure the file mod_ssl.so is there Inside of Apache directory C:\wamp64\bin\apache\apache2.4.27\conf, enable mod_ssl in httpd.conf Enable php_openssl.dll in php.ini. Be aware my problem was that I had two php.ini files and I need to do this in both of them. First one can be located inside of your WAMP taskbar icon here. And the other one is located in C:\wamp64\bin\php\php(Version) Find the location for both of the php.ini files and find the line curl.cainfo = and give it a path like this curl.cainfo = "C:\wamp64\bin\php\php(Version)\extras\ssl\cacert.pem" Now save the files and restart your server and you should be good to go


这可能是一个边缘情况,但在我的情况下,问题不是客户端配置(我已经有卷曲。在php.ini中配置了cfo),而不是远程服务器没有正确配置:

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

卷曲度错误60

在远程web服务器配置中包含中级证书后,它工作了。

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

https://whatsmychaincert.com/


当我运行'var_dump(php_ini_loaded_file());' 我在页面上得到这个输出 “C: \开发\ bin \ apache \ apache2.4.33 \ bin \ php . ini”(长度= 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. exe "。pem”,我从https://curl.haxx.se/docs/caextract.html下载并放置了证书文件

我在Windows 10,使用drupal 8, wamp和php7.2.4


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

我的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或更高版本将默认找到系统证书。当 // < 5.6,使用Guzzle捆绑cacert。


所有答案都是正确的;但最重要的是你必须找到正确的php.ini文件。 在CMD中检查这个命令“PHP——ini”不是找到正确的PHP .ini文件的正确答案。

如果你编辑

curl.cainfo ="PATH/cacert.pem"

并检查

var_dump(openssl_get_cert_locations()); 

然后旋度。fo应该有一个值。如果不是,那么这是不对的php.ini文件;

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


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

update-ca-certificates

如果仍然不起作用,那么您需要在证书存储中添加远程服务器的根证书和临时证书。您可以先下载根证书和中间证书,添加到/usr/local/share/ca-certificates目录下,然后执行update-ca-certificates命令。这应该能奏效。类似地,对于windows,您可以搜索如何添加根证书和中间证书。

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


对于WAMP,这是最终为我工作的方法。 虽然它与其他类似,但本页上提到的解决方案以及网络上的其他位置都不起作用。一些“小”细节有所不同。 保存PEM文件的位置很重要,但没有明确地指定。 或者要编辑的php.ini文件不正确。或两者兼而有之。 我正在一台Windows 10机器上运行WAMP 3.2.0的2020年安装。

获取pem文件的链接:

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

将PEM文件保存在此位置

<wamp安装目录>\bin\php\php<版本>\extras\ssl eg保存的文件和路径:“T:\wamp64\bin\php\php7.3.12\extras\ssl\cacert.pem”

*(我最初将它保存在其他地方(并在php.ini文件中指示保存位置,但这不起作用)。 可能有,也可能没有,其他位置也可以。这是推荐的地点——我不知道为什么。)

在哪里 <wamp安装目录> = wamp安装的路径。 T: \ wamp64 \

WAMP正在运行的php的>版本:(要找到,转到:WAMP图标托盘-> php的版本号> 如果显示的版本号是7.3.12,那么目录将是:php7.3.12) 例如:php7.3.12

要编辑哪个php.ini文件

要打开适当的PHP .ini文件进行编辑,请转到:WAMP图标托盘-> PHP -> PHP .ini。 例如:T: \ wamp64 \ bin \ apache \ apache2.4.41 \ bin \ php . ini 注意:它不是php目录下的文件!

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

注意,如果你按照上面的说明,你不是直接编辑一个php.ini文件。你实际上是在编辑phpForApache.ini文件。(一篇关于符号链接的文章)

如果您阅读不同WAMP目录中某些php.ini文件顶部的注释,它会特别声明不编辑该特定文件。 请确保打开进行编辑的文件不包含此警告。

安装扩展Link Shell扩展允许我在文件属性窗口中通过添加的选项卡看到符号链接的目标。这里是我的一个关于这个扩展的更多信息的SO答案。

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

要在php.ini文件中进行的编辑:

将该路径粘贴到PEM文件的以下位置。

取消注释,旋度。并粘贴到PEM文件的路径。 旋度。cenfo = "T:\wamp64\bin\php\php7.3.12\extras\ssl\cacert.pem" 取消注释,openssl。cafile=并粘贴到PEM文件的路径。 如:openssl.cafile = " T: \ wamp64 \ bin \ php \ php7.3.12 \配件\ ssl \ cacert.pem”

学分:

虽然不是官方资源,但这里有一个YouTube视频的链接,为我澄清了最后的细节:https://www.youtube.com/watch?v=Fn1V4yQNgLs。


I'm using Centos 7 with the free version of virtualmin. With Virtualmin you can create a wordpress website. There is functionality that will automatically update your ssl certificate for you. I noticed that /etc/httpd/conf/httpd.conf did not contain an entry for SSLCertificateChainFile. Which should be set to something like /home/websitename/ssl.combined. Updating that file accordingly and restarting apache fix this problem for me. I discovered my issue trying to install a jetpack plugin for wordpress. A search on the internet led me to realize that I didn't have SSL Configured. I followed Redhat's instructions on how to install a certificate. I hope this was useful to someone.


狂饮版5

这个默认配置对我的工作很好。它将禁用https要求。

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

在其他情况下,您要设置ca的路径,更改为:

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

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

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

打开自签名证书(.crt)文件 复制所有之间和包括

——开始证书

——结束证书

粘贴到wp-includes\certificates\ca-bundle.crt文件的末尾