HTTPS и SSL3_GET_SERVER_CERTIFICATE: сбой проверки сертификата, CA в порядке

208

Я использую 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 и т.д. могут решить эту проблему.

Josnidhin
источник

Ответы:

145

curl используется для включения списка принятых CA, но больше не связывает ЛЮБЫЕ сертификаты CA. Поэтому по умолчанию он отклоняет все SSL-сертификаты как непроверяемые.

Вы должны будете получить свидетельство вашего CA и указать на него. Более подробную информацию можно найти в разделе cURLS о серверных SSL-сертификатах .

Марк Б
источник
4
Завиток происходит в библиотеке php веб-сервисов Amazon. Я не понимал, как это исправить, не редактируя код библиотеки.
Josnidhin
41
Затем отключите проверку сертификата ( CURLOPT_SSL_VERIFYPEER-> false). Вы либо добавляете сертификат CA сайта, с которым вы пытаетесь использовать SSL, либо отключаете проверку CA. Это только два доступных варианта.
Марк Б
78
Просто fyi - настройка CURLOPT_SSL_VERIFYPEERдля falseпоражения цели использования SSL.
до
13
@ До тех пор, пока не победит половина цели SSL? Вы все еще получаете конфиденциальность между вами и вашим пэром: у вас просто нет подлинности вашего пира.
Марк Фокс
10
без аутентификации, какой смысл шифровать отправляемые данные? Если вы были MITMed, то данные все равно скомпрометированы
hdgarrood
290

Это довольно распространенная проблема в Windows. Вам нужно просто установить cacert.pemна curl.cainfo.

Начиная с PHP 5.3.7 вы можете делать:

  1. скачайте https://curl.haxx.se/ca/cacert.pem и сохраните его где-нибудь.
  2. обновить php.ini- добавить curl.cainfo = "PATH_TO / cacert.pem"

В противном случае вам нужно будет сделать следующее для каждого ресурса cURL:

curl_setopt ($ch, CURLOPT_CAINFO, "PATH_TO/cacert.pem");
Артур Курицын
источник
2
Это работало для меня в XAMPP на OS X. Это исправило проблему, когда плагин Wordpress не обновлялся из-за невозможности найти локальный сертификат.
Джонатан Николь
8
Для тех, кто пытается решить эту проблему в Windows с помощью Apache, мне нужно было указать полный путь (например, C: \ PATH_TO \ cacert.pem) в моем PHP-коде. На IIS относительный путь работал нормально.
http203
Если cacert.pem находится в том же каталоге, то curl_setopt ($ ch, CURLOPT_CAINFO, dirname ( FILE ). '/Cacert.pem'); будет работать
моджахеды
7
При использовании WampServer с 2., вы должны добавить переменную в два отдельных php.iniфайла. См. Stackoverflow.com/a/25706713/1101095
конец
Что удивительно / иронично, так это то, что вы можете скачать curl.haxx.se/ca/cacert.pem через HTTPS, не указывая никаких дополнительных опций. Сертифицирован ли сертификат curl.haxx.se в сам curl?
Qbolec
84

Предупреждение: это может привести к проблемам безопасности, от которых защищен протокол SSL, что делает вашу кодовую базу небезопасной. Это противоречит любой рекомендуемой практике.

Но действительно простым решением, которое сработало для меня, было позвонить:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

перед звонком:

curl_exec():

в файле php.

Я считаю, что это отключает все проверки SSL-сертификатов.

Крис Датроу
источник
65
... и отключив проверку сертификатов, вы оставляете дверь открытой для потенциальных MITM-атак, от которых SSL / TLS в противном случае стремится защищаться. НЕ ДЕЛАЙТЕ ЭТОГО!
Бруно
12
Ага. Я должен был обратить больше внимания на это в ответе. Делайте это только если вы не работаете над чем-то важным. Я использую его на localhost для доступа к веб-сайтам, которые я лично запрограммировал.
Крис Датроу
3
Даунвот от меня. Это грязное исправление, чтобы ваш код работал, но не решение. Ответ от Артур Курицын намного лучше.
Илья
2
@ Bruno Это идеальное решение для вспомогательных сценариев, тестов, доверенных приложений, интрасети, ..... Каждый, кто знает немного о SSL, знает, в каких случаях проверка сертификата может быть пропущена. Так что все «умные» комментарии к этому ответу и такие вещи, как «НЕ ДЕЛАЙТЕ ЭТОГО», просто БЕЗУМНЫ !!
Кенякорн Кецомбут
5
... " Каждый, кто знает немного о SSL [...] " ... и вы будете удивлены тем, сколько людей даже не удосуживаются узнать немного об основах SSL / TLS, и только приходят здесь, чтобы скопировать / вставить быстрое исправление их сообщения об ошибке.
Бруно
53

Источник: 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.

Дипак Оберой
источник
38
Обычно считается вежливым указывать источник вашей информации и цитировать только определенные части, имеющие отношение к вопросу, а не просто копировать и вставлять ее здесь!
Дэн Херд
1
Извините, я был в гостях, да, я ценю Дэна за это и обновил сообщение
Дипак Оберой
6
По крайней мере, Дипак приложил усилия, чтобы исследовать это. @ danherd Итак, danherd, вы только что провели исследование, чтобы найти, что он взял код откуда-то? Какое право было присвоено этому коду? Вместо того, чтобы тратить время на поиски чужих ошибок, постарайтесь помочь кому-то самостоятельно. Не борись, поделись!
Г.Т.Доров
17

Вышеуказанные решения хороши, но если вы используете 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 файла.

Nate
источник
6

Ради любви всего святого ...

В моем случае мне пришлось установить openssl.cafileпеременную PHP config в путь к файлу PEM.

Я верю, что это очень верно, что есть много систем, где настройка curl.cainfoв конфиге PHP - это именно то, что нужно, но в среде, с которой я работаю, то есть eboraas / laravel докера , который использует Debian 8 (jessie) и PHP 5.6, установка этой переменной не сработала.

Я заметил, что в выводе php -iничего не упоминалось об этом конкретном параметре конфигурации, но в нем было несколько строк openssl. Существует как опция, так openssl.capathи openssl.cafileопция, но только установка второй позволила curl через PHP, наконец, быть в порядке с HTTPS URL.

Спенсер Уильямс
источник
Спасибо! Настройка curl.cainfo у меня тоже не сработала, но настройка openssl.cafile подействовала! Я на Windows 7 с XAMPP и PHP 7.1.1.
Кенцмилось
@knezmilos как ты настроил openssl.cafile? где вы скачали и как его активировать?
Крыс
Ну, это было какое-то время, но я думаю, что-то вроде этого: curl.cainfo = "C: \ xampp \ cacert \ cacert.pem" и openssl.cafile = "C: \ xampp \ cacert \ cacert.pem" в php. ini, хотя я думаю, что получил файл pem из одного из ответов здесь.
Кенцмилось
1
«Ради любви всего святого ...». Это сработало для моей установки Ubuntu 18.08 / Apache / Php7.2. Если ошибка скручивания указывает на правильный файл, то это, безусловно, ошибка openssls
JTG
4

Иногда, если приложение, с которым вы пытаетесь связаться, имеет самозаверяющие сертификаты, обычный cacert.pem с http://curl.haxx.se/ca/cacert.pem не решает проблему.

Если вы уверены в URL-адресе конечной точки службы, нажмите его через браузер, сохраните сертификат вручную в формате «Сертификат X 509 с цепочкой (PEM)». Укажите этот файл сертификата с помощью

curl_setopt ($ch, CURLOPT_CAINFO, "pathto/{downloaded certificate chain file}");   
madRai
источник
4

У меня такая же ошибка на 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"
Рейнальдо Мендес
источник
Отлично, спасибо! Я обновил вопрос, чтобы добавить именно то, что я сделал, что решило проблему для меня, вместо того, чтобы создать другой ответ.
Тим
3

При настройке параметров 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 в одной области.)

LOwens1931
источник
1
Я надеюсь, что php.ini должен указывать на файл pem вместо его родительской папки
dejjub-AIS
2

Я попал сюда, когда пытался заставить 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 / поиск других в цепочке, если они вам нужны.

Они выглядят так:

пример сертификата изображения

( Примечание: это изображение, поэтому люди не будут просто копировать / вставлять сертификаты из stackoverflow )

Как только нужные сертификаты будут в этом файле, перезапустите apache и протестируйте.

TrophyGeek
источник
0

Вы можете попытаться переустановить ca-certificatesпакет или явно разрешить соответствующий сертификат, как описано здесь .

сайт
источник
-5

Решение очень простое! Поместите эту строку перед curl_exec:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

Для меня это работает.

Жолт Босзорменый
источник
7
Никогда, никогда не отключайте взаимную проверку, если вам все равно, если данные скомпрометированы при передаче.
rdlowrey
Согласовано. Если вы хотите безопасное приложение, вам нужна сверстная проверка.
Брэйд
2
«Никогда, никогда не отключайте проверку одноранговой сети», ЕСЛИ ВЫ не хотите использовать функциональность браузера по умолчанию, ха-ха. Кроме того, почему это так сильно отвергается? Это единственный ответ, который короткий, сладкий, по сути И эффективный.
Адам Ф
@ AdamF FYI, браузеры проверяют сертификат одноранговых узлов по умолчанию, они только дают вам возможность обходить ошибки вручную, с предупреждением.
Бруно