Я пытаюсь написать PHP-скрипт, используя cURL, который может авторизовать пользователя через страницу, использующую сертификат SSL, в дополнение к имени пользователя и паролю, и я не могу пройти экзамен SSL.
В этом случае curl_setopt($handle, CURLOPT_VERIFYPEER, 0)
к сожалению, не является вариантом. Сертификат является обязательной частью аутентификации, в противном случае я получаю ошибку, упомянутую в этой другой аналогичной должности SO .
Я пробовал несколько прогонов командной строки cURL:
> curl --url https://website
Это возвращает ошибку (60) SLL certificate problem
. Если я --cacert
команду для включения опции --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 : Эти дисквалификации на единственные души, достаточно храбрые, чтобы ответить на этот вопрос, стареют. Либо сделайте что-нибудь значимое, либо передайте, пожалуйста.
Поскольку все работает через командную строку, но не через php, используя curl, тогда я бы искал завиток, являющийся проблемой.
Согласно этому URL-адресу, http://curl.haxx.se/docs/sslcerts.html , который был ссылкой в сообщении SO, которое вы цитировали выше ( чтение страницы SSL с помощью CURL (php) ) …
«До 7.18.0 завиток включал сильно устаревший файл привязки ca, который был установлен по умолчанию. В наши дни в архивах curl нет никаких сертификатов ca. Вы должны получить их в другом месте. См. Ниже, например.
Если удаленный сервер использует самозаверяющий сертификат, если вы не устанавливаете пакет сертификации CA, если сервер использует сертификат, подписанный ЦС, который не включен в используемый вами пакет или если удаленный хост является самозваным выдавая себя за ваш любимый сайт, и вы хотите передать файлы с этого сервера, выполните одно из следующих действий:
Затем он перечислит несколько шагов, которые вы можете попробовать.
Так как ваша версия 7.16.3 curl до 7.18.0, если вы еще этого не сделали, я бы рекомендовал обновить ваши компоненты curl и openssl, а затем работать с указанным выше списком.
После 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.
Теперь, когда этот вопрос является старым, но может быть полезным для некоторых пользователей, которые ищут ответ в настоящее время.
У меня аналогичная проблема с API с SSL, у меня проблемы с CURL (а не с браузерами). Моя проблема заключалась в том, что я просто поместил сертификат, но не цепочку цепочек / пакетов. Затем я положил это, и все начало работать. Поэтому это важно для того, чтобы избежать проблем.
Надеюсь, это может быть полезно для кого-то.
Чтобы уточнить и подвести итог:
если у вас есть 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;