Ошибка при использовании PHP cURL с сертификатами SSL - PullRequest
25 голосов
/ 08 апреля 2009

Я пытаюсь написать сценарий PHP с использованием cURL, который может авторизовать пользователя на странице, использующей сертификат SSL, в дополнение к имени пользователя и паролю, и я не могу пройти этап сертификации SSL.

В этом случае, к сожалению, curl_setopt($handle, CURLOPT_VERIFYPEER, 0) не вариант. Сертификат является обязательной частью аутентификации, в противном случае я получаю ошибку, упомянутую в этом другом аналогичном сообщении SO .

Я пробовал несколько команд командной строки с помощью cURL:

> curl --url https://website

Возвращает ошибку (60) SLL certificate problem. Если я настрою команду для включения опции --cacert:

> curl --url https://website --cacert /path/to/servercert.cer

Работает просто отлично; сайт авторизации возвращается.

Однако я попробовал следующий код PHP:

$handle = curl_init();
$options = array( 
                  CURLOPT_RETURNTRANSFER => false,
                  CURLOPT_HEADER         => true,
                  CURLOPT_FOLLOWLOCATION => false,
                  CURLOPT_SSL_VERIFYHOST => '0',
                  CURLOPT_SSL_VERIFYPEER => '1',
                  CURLOPT_CAINFO         => '/path/to/servercert.cer',
                  CURLOPT_USERAGENT      => 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)',
                  CURLOPT_VERBOSE        => true,
                  CURLOPT_URL            => 'https://website'
           );

curl_setopt_array($handle, $options);
curl_exec($handle);
if (curl_errno($handle)) {
  echo 'Error: ' . curl_error($handle);
}
curl_close($handle);

Я бы подумал, что код по сути аналогичен командам оболочки, но вместо этого меня приветствует следующее сообщение об ошибке:

Ошибка: ошибка установки сертификата при проверке местоположения: CAfile: /path/to/servercert.cer CApath: нет

Я прочитал всю литературу, которую могу найти (в частности, на php.net и curl.haxx) и не могу найти ничего, что решило бы эту проблему. Есть предложения?

РЕДАКТИРОВАТЬ : Я пытался chmod 777 servercert.cer безуспешно. Однако при выполнении сценария PHP с указанным выше кодом из командной строки вместо браузера через php test.php он работает отлично. Любое объяснение, почему это не работает в браузере?

РЕДАКТИРОВАТЬ 2 : Эти понижающие голоса единственных душ, достаточно смелых, чтобы ответить на этот вопрос, стареют. Либо добавьте что-нибудь значимое, либо пройдите мимо, пожалуйста.

Ответы [ 4 ]

13 голосов
/ 02 мая 2012

Поскольку все работает через командную строку, а не через php с использованием curl, я бы решил, что проблема в curl.

Согласно этому URL, http://curl.haxx.se/docs/sslcerts.html,, который был ссылкой в ​​сообщении SO, которое вы цитировали выше ( чтение страницы SSL с CURL (php) ) ...

"До 7.18.0, curl связывал сильно устаревший файл ca ca bundle, который был установлен по умолчанию. В эти дни архивы локонов не содержат сертификатов на все. Вы должны получить их в другом месте. См. Ниже, например.

Если удаленный сервер использует самозаверяющий сертификат, если вы не устанавливаете CA комплект сертификатов, если сервер использует сертификат, подписанный центром сертификации, который не является входит в комплект, который вы используете, или если удаленный хост является самозванцем выдает себя за ваш любимый сайт, и вы хотите передать файлы с этого сервер, выполните одно из следующих действий: "

Затем перечисляется ряд шагов, которые вы можете попробовать.

Поскольку ваша версия curl 7.16.3 до 7.18.0, если вы еще этого не сделали, я бы порекомендовал обновить компоненты curl и openssl, а затем работать со списком, упомянутым выше.

5 голосов
/ 08 декабря 2015

После 6 лет вопроса я сталкиваюсь с той же проблемой на общем хосте, и, видимо, нет удовлетворительного ответа. Я нашел для себя решение, надеюсь, оно пригодится всем.

Вы можете попробовать этот конфиг:

curl_setopt($config,CURLOPT_SSL_VERIFYHOST,0);
curl_setopt($config,CURLOPT_SSL_VERIFYPEER,1);
curl_setopt($config,CURLOPT_CAINFO,'ca-bundle.crt');
curl_setopt($config,CURLOPT_CAPATH,'ca-bundle.crt');

Я встретил ту же ошибку с @Magsol: Error: error setting certificate verify locations: CAfile: /path/to/servercert.cer CApath: none; поэтому я добавил четвертую строку для установки CAPath.

Это работа со мной. Но обратите внимание, файл CA должен быть помещен в доступный каталог (с chmod 755 или 777), и будет лучше, если файл CA будет в том же каталоге, что и файл PHP.

3 голосов
/ 14 июля 2017

Для уточнения и подведения итогов:

если у вас есть PHP-файл, использующий PHP curl, и поместите сертификат ca для своих систем в тот же каталог, приведенный ниже код даст вам краткий старт

    $url = "https://myserver.mydomain.local/get_somedata.php";
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);

//These next lines are for the magic "good cert confirmation"
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
    curl_setopt($ch, CURLOPT_VERBOSE, true);

//for local domains:
//you need to get the pem cert file for the root ca or intermediate CA that you signed all the domain certificates with so that PHP curl can use it...sorry batteries not included
//place the pem or crt ca certificate file in the same directory as the php file for this code to work
    curl_setopt($ch, CURLOPT_CAINFO, __DIR__.'/cafile.pem');
    curl_setopt($ch, CURLOPT_CAPATH, __DIR__.'/cafile.pem');

//DEBUG: remove slashes on the next line to prove "SSL verify" is the cause       
//curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

//Error handling and return result
    if (curl_exec($ch) === false)
      {
       $result = curl_error($ch);
      }
    else
      {
       $result = curl_exec($ch);
      }
    // Close handle
    curl_close($ch);
    return $result;
3 голосов
/ 01 октября 2015

Теперь этот вопрос очень старый, но, возможно, может быть полезен для некоторых пользователей, которые ищут ответ в настоящее время.

У меня похожая проблема с API с SSL, у меня проблемы с CURL (не с браузерами), моя проблема была в том, что я просто поставил сертификат, а не цепочку / комплект сертификатов. Тогда я положил это, и все начало работать. Так что это важно, чтобы избежать проблем.

Надеюсь, это кому-нибудь пригодится.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...