Php curl https problem

Использование curl в PHP для доступа к сайтам по Https(ssl/tls)

В Php для доступа к сайтам по http, https, FTP часто используется библиотека curl.

На практике, однако, наиболее часто используется протокол, HTTP особенно при соединении server-to-server . Curl же используется при таких методах доступа как

XML-RPC или REST для запроса ресурса. Либо же если производится соединение с сервером посредством какого-либо API. Ну и последним использованием curl в php можно назвать парсинг ресурсов.

Тем не менее, при попытке получить доступ к ресурсу по HTTPS, например, через API, могут возникнуть определенные проблемы в подключении, о которых и пойдет речь.

Основной проблемой при данном соединении с использованием Curl можно назвать невозможность библиотекой проверить недоверенный сертификат сайта. Смоделируем ситуацию.

Предположим мы используем следующий код

// Initialize session and set URL. $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); // Set so curl_exec returns the result instead of outputting it. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // Get the response and close the channel. $response = curl_exec($ch); curl_close($ch);

Если $url указывает на https ресурс как результат выполнения данного кода мы получим

Failed: Error Number: 60. Reason: SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

Это происходит потому, что Curl не был настроен доверять HTTPS сертификату сервера.

Читайте также:  Javascript set add all

Понятия сертификаты и PKI вращается вокруг доверия сертификатов (CA), и по умолчанию, Curl настроен не доверять CA, таким образом, он не будет доверять сертификату любого веб-сервера. Так почему же не у нас не возникли проблемы посещения HTTPs сайтов через веб-браузер? Разработчики браузера включают в себя список корневых доверенных центров сертификации, у которых может быть приобретен сертификат сайта.

Таким образом необходимо либо разрешить Curl доверять нашему сертификату, либо запретить проверку доверия к сертификату при использовании библиотеки.

Обратимся к более простому решению – запретим Curl проверять сертификат, фактически настроив на доверие к любому полученному сертификату.

Это не очень верное решение с точки зрения безопасности, но действенно. Для выполнения данной настройки перед вызовом curl curl_exec() достаточно вставить следующую строку

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

Это заставляет библиотеку Curl принимать любые сертификаты, но если Вы обеспокоены, что у Вас принимаются все сертификаты без разбора необходимо сделать немного больше действий.

Оговоримся, что будем использовать такой параметр Curl CURLOPT_CAINFO и сертификат, полученный с сайта.

Давайте извлечем сертификат, используя наш броузер.

Откроем сайт и увидим следующую картинку в нижней части броузера.

1-2016

Нажмем «просмотреть сертификат»

2-2016

И далее в пункте «Детали» на странице сертификатов выберем наш сертификат. Это доверенный корневой сертификат.

3

Нам необходимо его экспортировать для дальнейшего использования Curl

4

Нажмем “Экспорт”, и сохраним наш корневой сертификат как X.509 Certificate (PEM).

Далее нам необходимо модифицировать настройки cURL для использования CA сертификата с параметром CURLOPT_CAINFO, где мы укажем место сохранения сертификата .

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt($ch, CURLOPT_CAINFO, getcwd() . "/CAcerts/BuiltinObjectToken-EquifaxSecureCA.crt");

Failed: Error Number: 60. Reason: SSL certificate problem, verify that the CA cert is OK. Details:

error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

Источник

Fix SSL certificate problem with PHP curl

Fix SSL certificate problem with PHP curl

In this article, I will show share with you a tip to fix SSL certificate problem with PHP curl when making HTTPS requests.

Making HTTPS requests

Before talking about the issue, let us try an old example by making HTTP request.

$url = "http://WEBSITE"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $result = curl_exec($ch); if(curl_errno($ch)) < echo 'Error: '.curl_error($ch); >else < echo $result; >curl_close ($ch);

It is alright for HTTP site, but if we change the $url into a HTTPS url, ex. https://petehouston.com , does it work normally?

No, it doesn’t. It shows this nagging error:

Error: SSL certificate problem: unable to get local issuer certificate

The error means we need to configure curl instance to deal with SSL-enabled websites.

Fix SSL certificate problem

There are two ways to fix SSL certificate problem with PHP curl module.

  1. Specify the valid CA certificate to curl client.
  2. Ignore SSL verification.

Solution 1: Use a valid CA certificate

I’m not going to explain what CA certificate is and why we need it to make requests.

You just need to download CA certificate provided by curl author, https://curl.haxx.se/docs/caextract.html, or click here to download.

Save the file somewhere in your computer, ex. ~/certs/cacert.pem if you’re on Linux or MacOS, D:\certs\cacert.pem if you’re using Windows.

Config the curl instance with CURLOPT_CAINFO to point to the cacert.pem file.

// for Linux/Mac curl_setopt($ch, CURLOPT_CAINFO, '/home/petehouston/certs/cacert.pem'); // for Windows curl_setopt($ch, CURLOPT_CAINFO, 'D:/certs/cacert.pem');

Try to execute the script again, it should work now!

You can also pre-configure the CA certificate by putting it into php.ini , so you don’t need to configure manually for each curl instance.

[curl] ; A default value for the CURLOPT_CAINFO option. This is required to be an ; absolute path. curl.cainfo = "/home/petehouston/certs/cacert.pem"

Solution 2: Ignore SSL verification

If you don’t really care about SSL verification, you can ignore it by disable the CURLOPT_SSL_VERIFYPEER key.

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);

It is just working as it with configured certificate.

Conclusion

So which one should I use, you ask?

Again, if you don’t care about the authenticity of the SSL then ignore it; otherwise, make sure you request to the right one.

That’s it! I’ve just shown you how to fix SSL certificate problem with PHP curl module.

Источник

PHP cURL: Fixing the “SSL certificate problem: unable to get local issuer certificate” error.

If you are using PHP’s cURL functions to connect to an HTTPS URL, then you might come across the following error:

SSL certificate problem: unable to get local issuer certificate. (cURL error code 60)

This is a common error that occurs whenever you attempt to use cURL functions to connect to an HTTPS website.

In plain English, it means that you have not configured cURL to connect to SSL-enabled websites.

The quick fix.

If you do not care about security and are looking for a quick fix, then you can simply disable the following cURL options:

  • CURLOPT_SSL_VERIFYHOST: This option tells cURL that it must verify the host name in the server cert.
  • CURLOPT_SSL_VERIFYPEER: This option tells cURL to verify the authenticity of the SSL cert on the server.

Disabling these two options disables SSL verification.

To disable these two options, you can use the curl_setopt function like so:

//The URL we are connecting to. $url = ‘https://google.com’; //Initiate cURL. $ch = curl_init($url); //Disable CURLOPT_SSL_VERIFYHOST and CURLOPT_SSL_VERIFYPEER by //setting them to false. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //Execute the request. curl_exec($ch); //Check for errors. if(curl_errno($ch))

The PHP code above essentially tells cURL that we don’t care if the server has a valid SSL cert or not. We want to connect to it anyway.

The problem with this method is that it is insecure and it leaves you open to man-in-the-middle attacks. Simply put, this means that an attacker could potentially intercept the data that you are sending in your cURL requests.

Using a cert with PHP’s cURL functions.

To use a certificate with PHP’s cURL functions, you can download the cacert.pem certificate bundle from the official cURL website.

Once you have downloaded the cacert.pem file, you should move it to whatever directory makes the most sense for you and your setup.

For example, on Windows, I moved my bundle to C:\wamp\cacert.pem

Then, you can simply tell cURL where your certificate bundle is located by using the curl_setopt function:

//Tell cURL where our certificate bundle is located. $certificate = "C:\wamp\cacert.pem"; curl_setopt($ch, CURLOPT_CAINFO, $certificate); curl_setopt($ch, CURLOPT_CAPATH, $certificate);

This allows us to make a secure request to the server and prevent any man-in-the-middle attacks.

Adding the cert to your php.ini file.

If you don’t like the thought of having to specify the location of the certificate bundle in your PHP code, then you can add its path information to your php.ini file like so:

curl.cainfo="C:\wamp\cacert.pem" openssl.cafile="C:\wamp\cacert.pem"

Once you add the above lines to your php.ini file, make sure that you reload the web server / PHP process so that the changes take effect.

Enabling mod_ssl and php_openssl.dll.

If you are using Apache and PHP on Windows, then you might need to enable both mod_ssl and php_openssl.dll.

To enable mod_ssl, you can add the following to your Apache configuration file:

LoadModule ssl_module /usr/lib/httpd/modules/mod_ssl.so

The configuration line above presumes that a file called mod_ssl.so exists in a Linux directory called “/usr/lib/httpd/modules/”.

On Windows, this directory might be something like “C:\wamp\bin\apache\apache2.4.9\modules\“.

You will need to change this line to match your own Apache setup.

To enable php_openssl.dll, you will need to uncomment the following line in your php.ini file:

As always, you should test your configurations and then reload your server for any changes to take effect.

Источник

Оцените статью