Подтвердить что ты не робот

Ошибка при использовании PHP cURL с сертификатами SSL

Я пытаюсь написать PHP script, используя 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

Это прекрасно работает; возвращается веб-сайт auth.

Однако, я пробовал следующий 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: none

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

EDIT: Я пробовал chmod 777 servercert.cer без успеха. Однако при выполнении PHP скрипт с приведенным выше кодом из командной строки вместо браузера через php test.php он отлично работает. Любое объяснение того, почему он не работает в браузере?

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

4b9b3361

Ответ 1

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

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

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

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

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

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

Ответ 2

После 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; поэтому я добавил 4-ю строку для установки CAPath.

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

Ответ 3

Чтобы продумать и подвести итог:

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

    $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;

Ответ 4

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

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

Надеюсь, это может быть полезно для кого-то.

Ответ 5

Вы можете попробовать это, если это работает для вас:

curl_setopt($ch, CURLOPT_URL, "https://test.example.com/v1/authenticate.json?api_key=123456");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,0);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_FAILONERROR, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch,CURLOPT_CAINFO,'cert.embedapp.20191004.pem');
curl_setopt($ch,CURLOPT_CAPATH,'./cert.embedapp.20191004.pem');

Прокомментируйте эти строки и добавьте следующее:

//curl_setopt($ch,CURLOPT_CAINFO,'cert.embedapp.20191004.pem');
//curl_setopt($ch,CURLOPT_CAPATH,'./cert.embedapp.20191004.pem');
curl_setopt($ch, CURLOPT_SSLCERT,'cert.embedapp.20191004.pem');