HTTPS и SSL3_GET_SERVER_CERTIFICATE: сбой проверки сертификата, CA в порядке
Я использую XAMPP для разработки. Недавно я обновил установку xampp со старой версии до 1.7.3.
Теперь, когда я скручиваю сайты с поддержкой HTTPS, я получаю следующее исключение
Неустранимая ошибка: необработанное исключение "RequestCore_Exception" с сообщением "cURL resource: Resource id #55; Ошибка cURL: проблема с сертификатом SSL, убедитесь, что сертификат CA в порядке. Сведения: ошибка:14090086: подпрограммы SSL:SSL3_GET_SERVER_CERTIFICATE: сбой проверки сертификата (60)'
Все предлагают использовать некоторые конкретные параметры curl из кода PHP, чтобы решить эту проблему. Я думаю, что это не должно быть так. Потому что у меня не было никаких проблем с моей старой версией XAMPP, и это произошло только после установки новой версии.
Мне нужна помощь, чтобы выяснить, какие настройки меняются в моей установке PHP, Apache и т. Д. Могут решить эту проблему.
11 ответов
curl раньше включал список принятых CA, но больше не связывает ЛЮБЫЕ сертификаты CA. Поэтому по умолчанию он отклоняет все SSL-сертификаты как непроверяемые.
Вы должны будете получить свидетельство вашего CA и указать на него. Более подробную информацию можно найти в разделе cURLS о серверных SSL-сертификатах.
Это довольно распространенная проблема в Windows. Вам нужно просто установить cacert.pem
в curl.cainfo
,
Начиная с PHP 5.3.7 вы можете делать:
- скачайте https://curl.haxx.se/ca/cacert.pem и сохраните его где-нибудь.
- Обновить
php.ini
- добавить curl.cainfo = "PATH_TO/cacert.pem"
В противном случае вам нужно будет сделать следующее для каждого ресурса cURL:
curl_setopt ($ch, CURLOPT_CAINFO, "PATH_TO/cacert.pem");
Предупреждение: это может привести к проблемам безопасности, от которых защищен протокол SSL.
Но действительно простым решением, которое сработало для меня, было позвонить:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
перед звонком:
curl_exec():
в файле php.
Я считаю, что это отключает все проверки SSL-сертификатов.
Источник: http://ademar.name/blog/2006/04/curl-ssl-certificate-problem-v.html
Curl: проблема с сертификатом SSL, убедитесь, что сертификат CA в порядке
07 апреля 2006 г.
Открывая безопасный URL с помощью Curl, вы можете получить следующую ошибку:
Проблема с сертификатом SSL, проверьте, что сертификат CA в порядке
Я объясню, почему ошибка и что вы должны с этим делать.
Самый простой способ избавиться от ошибки - добавить следующие две строки в ваш скрипт. Это решение создает угрозу безопасности.
//WARNING: this would prevent curl from detecting a 'man in the middle' attack curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
Давайте посмотрим, что делают эти два параметра. Цитирую руководство.
CURLOPT_SSL_VERIFYHOST: 1, чтобы проверить наличие общего имени в сертификате SSL-партнера. 2 проверить наличие общего имени, а также убедиться, что оно соответствует указанному имени хоста.
CURLOPT_SSL_VERIFYPEER: FALSE, чтобы остановить CURL от проверки сертификата партнера. Альтернативные сертификаты для проверки могут быть указаны с помощью параметра CURLOPT_CAINFO или каталог сертификатов может быть указан с помощью параметра CURLOPT_CAPATH. CURLOPT_SSL_VERIFYHOST может также иметь значение TRUE или FALSE, если CURLOPT_SSL_VERIFYPEER отключен (по умолчанию 2). Установка CURLOPT_SSL_VERIFYHOST в 2 (это значение по умолчанию) гарантирует, что представляемый вам сертификат имеет "общее имя", соответствующее URN, который вы используете для доступа к удаленному ресурсу. Это здоровая проверка, но она не гарантирует, что ваша программа не будет принята.
Введите "человек посередине"
Ваша программа может быть введена в заблуждение, чтобы вместо этого общаться с другим сервером. Это может быть достигнуто с помощью нескольких механизмов, таких как днс или отравление арп (это история для другого дня). Злоумышленник также может самостоятельно подписать сертификат с тем же именем, что и ваша программа. Сообщение будет по-прежнему зашифровано, но вы будете передавать свои секреты самозванцу. Этот вид атаки называется "человек посередине"
Победа над "человеком посередине"
Что ж, нам нужно убедиться, что представленный нам сертификат действительно хорош. Мы делаем это, сравнивая его с сертификатом, которому мы разумно * доверяем.
Если удаленный ресурс защищен сертификатом, выпущенным одним из главных центров сертификации, таким как Verisign, GeoTrust и др., Вы можете безопасно сравнить его с пакетом сертификатов CA Mozilla, который можно получить по http://curl.haxx.se/docs/caextract.html
Сохранить файл
cacert.pem
где-нибудь на вашем сервере и установите следующие параметры в вашем скрипте.curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, TRUE); curl_setopt ($ch, CURLOPT_CAINFO, "pathto/cacert.pem");
для всех вышеупомянутых информационных кредитов. Идет по адресу: http://ademar.name/blog/2006/04/curl-ssl-certificate-problem-v.html
Вышеуказанные решения хороши, но если вы используете WampServer, вы можете найти curl.cainfo
переменная в php.ini
не работает
Я в конечном итоге обнаружил, что WampServer имеет два php.ini
файлы:
C:\wamp\bin\apache\Apachex.x.x\bin
C:\wamp\bin\php\phpx.x.xx
Первый, по-видимому, используется, когда файлы PHP вызываются через веб-браузер, а второй используется, когда команда вызывается из командной строки или shell_exec()
,
TL;DR
Если вы используете WampServer, вы должны добавить curl.cainfo
линия к обоим php.ini
файлы.
Ради любви всего святого...
В моем случае я должен был установить openssl.cafile
Переменная config в пути к файлу PEM.
Я верю, что это очень верно, что есть много систем, где установка curl.cainfo
в конфиге PHP именно то, что нужно, но в среде, с которой я работаю, - это контейнер докера eboraas / laravel, который использует Debian 8 (jessie) и PHP 5.6, установка этой переменной не сработала.
Я заметил, что на выходе php -i
ничего не упомянул об этом конкретном параметре конфигурации, но там было несколько строк о openssl
, Существует как openssl.capath
а также openssl.cafile
вариант, но только установка второго позволила curl через PHP, наконец, в порядке с HTTPS URL.
У меня такая же ошибка на Amazon AMI Linux.
Я решил, установив curl.cainfo в /etc/php.d/curl.ini
https://gist.github.com/reinaldomendes/97fb2ce8a606ec813c4b
Дополнение октябрь 2018
На Amazon Linux v1 отредактируйте этот файл
vi /etc/php.d/20-curl.ini
Добавить эту строку
curl.cainfo="/etc/ssl/certs/ca-bundle.crt"
При настройке параметров curl для CURLOPT_CAINFO, пожалуйста, не забывайте использовать одинарные кавычки, использование двойных кавычек вызовет только еще одну ошибку. Так что ваш вариант должен выглядеть так:
curl_setopt ($ch, CURLOPT_CAINFO, 'c:\wamp\www\mywebfolder\cacert.pem');
Кроме того, в вашем файле php.ini настройки должны быть записаны как:(обратите внимание на мои двойные кавычки)
curl.cainfo = "C:\wamp\www\mywebfolder"
Я помещаю это непосредственно ниже линии, которая говорит это: extension=php_curl.dll
(Только для целей организации, вы можете поместить его в любом месте вашего php.ini
Я просто поместил его рядом с другой ссылкой на curl, поэтому при поиске по ключевому слову curl я могу найти обе ссылки на curl в одной области.)
Иногда, если приложение, с которым вы пытаетесь связаться, имеет самозаверяющие сертификаты, обычная cacert.pem с http://curl.haxx.se/ca/cacert.pem не решает проблему.
Если вы уверены в URL-адресе конечной точки службы, нажмите его через браузер, сохраните сертификат вручную в формате "Сертификат X 509 с цепочкой (PEM)". Укажите этот файл сертификата с помощью
curl_setopt ($ch, CURLOPT_CAINFO, "pathto/{downloaded certificate chain file}");
Я попал сюда при попытке получить GuzzleHttp (php+apache на Mac), чтобы получить страницу с www.googleapis.com.
Вот мое окончательное решение на случай, если оно кому-нибудь поможет.
Посмотрите на цепочку сертификатов для любого домена, который дает вам эту ошибку. Для меня это был googleapis.com
openssl s_client -host www.googleapis.com -port 443
Вы получите что-то вроде этого:
Certificate chain
0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=*.googleapis.com
i:/C=US/O=Google Inc/CN=Google Internet Authority G2
1 s:/C=US/O=Google Inc/CN=Google Internet Authority G2
i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
Примечание: я зафиксировал это после того, как исправил проблему, чтобы вывод вашей цепочки мог выглядеть иначе.
Затем вам нужно посмотреть сертификаты, разрешенные в php. Запустите phpinfo() на странице.
<?php echo phpinfo();
Затем найдите файл сертификата, который загружен со страницы вывода:
openssl.cafile /usr/local/php5/ssl/certs/cacert.pem
Этот файл вам нужно исправить, добавив в него правильные сертификаты.
sudo nano /usr/local/php5/ssl/certs/cacert.pem
В основном вам нужно добавить правильные "подписи" сертификатов в конец этого файла.
Вы можете найти некоторые из них здесь: Вам может понадобиться поискать в Google/ поиск других в цепочке, если они вам нужны.
Они выглядят так:
(Примечание: это изображение, поэтому люди не будут просто копировать / вставлять сертификаты из stackru)
Как только нужные сертификаты будут в этом файле, перезапустите apache и протестируйте.
Вы можете попробовать переустановить ca-certificates
пакет, или явно разрешить соответствующий сертификат, как описано здесь.
Решение очень простое! Поместите эту строку перед curl_exec
:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
Для меня это работает.