PHP cURL не работает с HTTPS

У меня были проблемы на моем сервере разработки, где cURL, отлично работая с чем-либо HTTP, не работает должным образом с чем-либо HTTPS – даже с тем же самым ресурсом с различными протоколами (для тестирования я запрашивал google.com, используя как http и https).

Полученная ошибка cURL равна 35: «Проблема возникла где-то в рукопожатии SSL / TLS».

Я расчесывал web и SO для решений, и все они были либо для параметра CURLOPT_SSL_VERIFYPEER, либо для false, что ничего не меняет или загружает файл сертификата и устанавливает CURLOPT_CAINFO на свой путь, что также ничего не меняет.

При настройке сертификата я следил за инструкциями этого руководства и этого руководства , пытаясь как загрузить сертификат для запрашиваемого ресурса, так и загрузить пакет сертификатов.

Я также попытался явно установить CURLOP_PORT на 443. Для тщательности моего вопроса, другие параметры, которые я установил, это CURLOPT_VERBOSE = true, CURLOPT_RETURNTRANSFER = true и CURLOPT_SSL_VERIFYHOST = 2 (я пробовал каждую комбинацию 1 и 2 с VERIFYPEER как true и false). Я также убедился в phpinfo (), что у меня есть OpenSSL, и он включен.

Я использую много старого кода, который отлично работал на моем последнем производственном сервере, поэтому этот код работал раньше. Но этот хостинг был общедоступным, и я не знаю большую часть конфигурации там.

Curl не имеет встроенных корневых сертификатов (как это делает большинство современных браузеров). Вам нужно явно указать его на файл cacert.pem:

curl_setopt($ch, CURLOPT_CAINFO, '/path/to/cert/file/cacert.pem'); 

Без этого завиток не может проверить сертификат, отправленный обратно через ssl. Этот же файл корневого сертификата может использоваться каждый раз, когда вы используете SSL в curl.

Вы можете получить файл cacert.pem здесь: http://curl.haxx.se/docs/caextract.html

Как насчет этого. Он выбирает домашнюю страницу HTTPS Google для меня. Это должно сделать трюк для вас.

 <?PHP // connect via SSL, but don't check cert $handle=curl_init('https://www.google.com'); curl_setopt($handle, CURLOPT_VERBOSE, true); curl_setopt($handle, CURLOPT_RETURNTRANSFER, true); curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false); $content = curl_exec($handle); echo $content; // show target page ?> 

Найдите, содержит ли ваша ОС каталог сертификатов. Если это так, то требуемые сертификаты CA часто включаются. Например, в Ubuntu это обычно /etc/ssl/certs . Если этот каталог существует, задайте параметр пути CA:

 curl_setopt($ch, CURLOPT_CAPATH, '/etc/ssl/certs'); 

В качестве альтернативы вы можете ссылаться на один файл сертификата CA. Включите файл cacert.pem в свой проект или установите его на свой сервер. Загрузите из надежного источника, например cacert.org. Для одного файла не устанавливайте CAPATH и вместо этого устанавливайте только CAINFO:

 curl_setopt($ch, CURLOPT_CAINFO, '/path/to/cacert.pem'); 

Отключение проверки сверстников и узлов – это быстрый, но небезопасный обходной путь к реальной проблеме. Эти функции существуют по уважительной причине: вы можете доверять через третью сторону, что система, к которой вы подключаетесь, является той, которую вы ожидаете.

 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);