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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29822686/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 00:37:03  来源:igfitidea点击:

cURL error 60: SSL certificate: unable to get local issuer certificate

phpsslcurlwampstripe-payments

提问by LoveAndHappiness

I use WAMP on a local development environment and am trying to charge a credit card but get the error message:

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

cURL error 60: SSL certificate problem: unable to get local issuer certificate

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

I searched a lot on Google and lots of people are suggesting that I download this file: cacert.pem, put it somewhere and reference it in my php.ini. This is the part in my php.ini:

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

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

Yet, even after restarting my server several times and changing the path, I get the same error message.

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

I use WAMP from the Apache Modules and have the ssl_module enabled. And from the PGP extensions I have php_curl enabled.

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

Still the same error message. Why is that happening?

还是一样的错误信息。为什么会这样?

Now I am following this fix: How to fix PHP CURL Error 60 SSL

现在我正在关注此修复程序:如何修复 PHP CURL 错误 60 SSL

Which suggests that I add these lines to my cURL options:

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

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

Where do I add options to my cURL? Apparently not through the command line, since my CLI doesn't find the command "curl_setopt"

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

EDIT

编辑

This is the code I am running:

这是我正在运行的代码:

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');
}

回答by Dung

Working solution assuming your on Windows using XAMPP:

假设您在 Windows 上使用 XAMPP 的工作解决方案:

XAMPP server

XAMPP 服务器

  1. Similar for other environment
    • download and extract for cacert.pem here (a clean file format/data)
  1. 其他环境类似
    • 在此处下载并提取 cacert.pem(干净的文件格式/数据)

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

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

  1. Put it here in the following directory.
  1. 把它放在下面的目录中。

C:\xampp\php\extras\ssl\cacert.pem

C:\xampp\php\extras\ssl\cacert.pem

  1. In your php.ini put this line in this section ("c:\xampp\php\php.ini"):
  1. 在您的 php.ini 中,将此行放在此部分(“c:\xampp\php\php.ini”):
;;;;;;;;;;;;;;;;;;;;
; php.ini Options  ;
;;;;;;;;;;;;;;;;;;;;

curl.cainfo = "C:\xampp\php\extras\ssl\cacert.pem"
;;;;;;;;;;;;;;;;;;;;
; php.ini Options  ;
;;;;;;;;;;;;;;;;;;;;

curl.cainfo = "C:\xampp\php\extras\ssl\cacert.pem"
  1. Restart your webserver/apache

  2. Problem solved!

  1. 重新启动您的网络服务器/apache

  2. 问题解决了!

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

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

回答by Rami Nour

Attention Wamp/Wordpress/windows users. I had this issue for hours and not even the correct answer was doing it for me, because i was editing the wrong php.ini file because the question was answered to XAMPP and not for WAMP users, even though the question was for WAMP.

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

here's what i did

这是我所做的

Download the certificate bundle.

下载证书包。

Put it inside of C:\wamp64\bin\php\your php version\extras\ssl

放在里面 C:\wamp64\bin\php\your php version\extras\ssl

Make sure the file mod_ssl.sois inside of C:\wamp64\bin\apache\apache(version)\modules

确保文件mod_ssl.soC:\wamp64\bin\apache\apache(version)\modules

Enable mod_sslin httpd.confinside of Apache directory C:\wamp64\bin\apache\apache2.4.27\conf

mod_sslhttpd.confApache 目录中启用C:\wamp64\bin\apache\apache2.4.27\conf

Enable php_openssl.dllin 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.

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

enter image description here

在此处输入图片说明

and the other one is located in C:\wamp64\bin\php\php(Version)

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

find the location for both of the php.inifiles and find the line curl.cainfo =and give it a path like this

找到这两个php.ini文件的位置并找到该行curl.cainfo =并给它一个这样的路径

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

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

现在保存文件并重新启动您的服务器,您应该很高兴

回答by Loren

If you are using PHP 5.6 with Guzzle, Guzzle has switched to using the PHP libraries autodetect for certificates rather than it's process (ref). PHP outlines the changes here.

如果您将 PHP 5.6 与 Guzzle 一起使用,Guzzle 已切换到使用 PHP 库自动检测证书而不是它的过程 ( ref)。PHP 概述了此处的更改。

Finding out Where PHP/Guzzle is Looking for Certificates

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

You can to dump where PHP is looking using:

您可以使用以下命令转储 PHP 正在查找的位置:

 var_dump(openssl_get_cert_locations());

Getting a Certificate Bundle

获取证书包

For OS X testing, you can use homebrew to install openssl brew install openssland then use openssl.cafile=/usr/local/etc/openssl/cert.pemin your php.ini or Zend Server settings (under OpenSSL).

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

A certificate bundle is also available from curl/Mozilla on the curl website: https://curl.haxx.se/docs/caextract.html

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

Telling PHP Where the Certificates Are

告诉 PHP 证书在哪里

Once you have a bundle, either place it where PHP is already looking (which you found out above) or update openssl.cafilein php.ini. (Generally, /etc/php.inior /etc/php/7.0/cli/php.inior /etc/php/php.inion Unix.)

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

回答by Ja?ck

Guzzle, which is used by cartalyst/stripe, will do the following to find a proper certificate archive to check a server certificate against:

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

  1. Check if openssl.cafileis set in your php.ini file.
  2. Check if curl.cainfois set in your php.ini file.
  3. Check if /etc/pki/tls/certs/ca-bundle.crtexists (Red Hat, CentOS, Fedora; provided by the ca-certificates package)
  4. Check if /etc/ssl/certs/ca-certificates.crtexists (Ubuntu, Debian; provided by the ca-certificates package)
  5. Check if /usr/local/share/certs/ca-root-nss.crtexists (FreeBSD; provided by the ca_root_nss package)
  6. Check if /usr/local/etc/openssl/cert.pem(OS X; provided by homebrew)
  7. Check if C:\windows\system32\curl-ca-bundle.crtexists (Windows)
  8. Check if C:\windows\curl-ca-bundle.crtexists (Windows)
  1. 检查是否openssl.cafile在您的 php.ini 文件中设置。
  2. 检查是否curl.cainfo在您的 php.ini 文件中设置。
  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)

You will want to make sure that the values for the first two settings are properly defined by doing a simple test:

您需要通过进行简单的测试来确保前两个设置的值已正确定义:

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

Alternatively, try to write the file into the locations indicated by #7 or #8.

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

回答by mvandillen

If you're unable to change php.ini you could also point to the cacert.pem file from code like this:

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

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

回答by George Donev

What i did was use var_dump(openssl_get_cert_locations()); die;in any php script, which gave me the information about defaults that my local php was using:

我所做的是var_dump(openssl_get_cert_locations()); die;在任何 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)

As you can notice, i have set the ini_cafile or the ini option curl.cainfo. But in my case, curl would try to use the "default_cert_file" which did not exist.

如您所见,我已经设置了 ini_cafile 或 ini 选项 curl.cainfo。但就我而言,curl 会尝试使用不存在的“default_cert_file”。

I copied the file from https://curl.haxx.se/ca/cacert.peminto the location for "default_cert_file" (c:/openssl-1.0.1c/ssl/cert.pem) and i was able to get it to work.

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

This was the only solution for me.

这对我来说是唯一的解决方案。

回答by Daydream Nation

I had this problem appear out-of-the-blue one day, when a Guzzle(5) script was attempting to connect to a host over SSL. Sure, I could disable the VERIFY option in Guzzle/Curl, but that's clearly not the correct way to go.

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

I tried everythinglisted here and in similar threads, then eventually went to terminal with openssl to test against the domain with which I was trying to connect:

我尝试了此处和类似线程中列出的所有内容,然后最终使用 openssl 转到终端以针对我尝试连接的域进行测试:

openssl s_client -connect example.com:443 

... and received first few lines indicating:

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

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 

... while everything worked fine when trying other destinations (ie: google.com, etc)

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

This prompted me to contact the domain I had been trying to connect to, and indeed, they had a problem on THEIR END that had crept up. It was resolved and my script went back to working.

这促使我联系了我一直试图连接的域,事实上,他们在 THEIR END 上遇到了一个问题。它得到了解决,我的脚本重新开始工作。

So... if you're pulling your hair out, give openssl a shot and see if there's anything up with the response from the location you are attempting to connect. Maybe the issue isn't so 'local' after all sometimes.

所以......如果你正在拔头发,给openssl一个机会,看看你试图连接的位置的响应是否有任何问题。也许问题毕竟不是那么“本地”有时。

回答by Iruku Kagika

I found a solution that worked for me. I downgraded from the latest guzzle to version ~4.0 and it worked.

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

In composer.json add "guzzlehttp/guzzle": "~4.0"

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

Hope it helps someone

希望它可以帮助某人

回答by Quang Nguyen Tri

Be sure that you open the php.inifile directly by your Window Explorer. (in my case: C:\DevPrograms\wamp64\bin\php\php5.6.25).

确保您php.ini直接通过窗口资源管理器打开文件。(在我的情况下:)C:\DevPrograms\wamp64\bin\php\php5.6.25

Don't use the shortcut to php.iniin the Wamp/Xamp icon's menu in the System Tray. This shortcut doesn't work in this case.

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

Then edit that php.ini:

然后编辑php.ini

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

and

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

After saving php.iniyou don't need to "Restart All Services" in Wamp icon or close/re-open CMD.

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

回答by Marko Milivojevic

I spent too much time to figure out this problem for me.

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

I had PHP version 5.5 and I needed to upgrade to 5.6.

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

In versions < 5.6 Guzzle will use it's own cacert.pem file, but in higher versions of PHP it will use system's cacert.pem file.

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

I also downloaded file from here https://curl.haxx.se/docs/caextract.htmland set it in php.ini.

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

Answer found in Guzzles StreamHandler.php file https://github.com/guzzle/guzzle/blob/0773d442aa96baf19d7195f14ba6e9c2da11f8ed/src/Handler/StreamHandler.php#L437

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.
        // PHP 5.6 or greater will find the system cert by default. When
        // < 5.6, use the Guzzle bundled cacert.