file get contents (): сбой операции SSL с кодом 1. И еще



Я пытался получить доступ к этой конкретной службе REST со страницы PHP, которую я создал на нашем сервере. Я сузил проблему до этих двух линий. Так что моя PHP страница выглядит так:



<?php
$response = file_get_contents("https://maps.co.weber.ut.us/arcgis/rest/services/SDE_composite_locator/GeocodeServer/findAddressCandidates?Street=&SingleLine=3042+N+1050+W&outFields=*&outSR=102100&searchExtent=&f=json");

echo $response; ?>


страница умирает в строке 2 со следующими ошибками:





  • предупреждение: file_get_contents (): сбой SSL-операции с кодом 1.
    Сообщения об ошибках OpenSSL: ошибка: 14090086: SSL
    процедуры: SSL3_GET_SERVER_CERTIFICATE: ошибка проверки сертификата
    ...РНР на линии 2


    • предупреждение: file_get_contents (): не удалось включить шифрование...php on
      строка 2

    • предупреждение:
      функции file_get_contents(https://maps.co.weber.ut.us/arcgis/rest/services/SDE_composite_locator/GeocodeServer/findAddressCandidates?Street=&SingleLine=3042+N+1050+W&outFields=*&outSR=102100&searchExtent=&f=json):
      не удалось открыть поток: операция не удалась ...php на линии 2






мы используем сервер Gentoo. Недавно мы обновились до версии PHP 5.6. Это было после обновления, когда эта проблема появилась.



я нашел, когда я заменяю службу REST на адрес как https://www.google.com; моя страница работает просто отлично.



в предыдущей попытке я поставил “verify_peer”=>false, и передал это в качестве аргумента file_get_contents, как описано здесь: file_get_contents игнорируя verify_peer= > false? Но, как заметил писатель, это не имело никакого значения.



Я спросил одного из наших администраторов сервера, если эти строки в нашем php.существует ini файл:




  • extension=php_openssl.dll

  • allow_url_fopen = On


Он сказал мне, что, поскольку мы находимся на Gentoo, openssl компилируется при сборке; и он не установлен в php.ini-файл.



Я также подтвердил, что allow_url_fopen работает. Из-за специализированного характера этой проблемы; я не нахожу много информации для помощи. Кто-нибудь из вас сталкивался с чем-то подобным? Спасибо.

1133   14  

14 ответов:

Это была чрезвычайно полезная ссылка для поиска:

http://php.net/manual/en/migration56.openssl.php

официальный документ, описывающий изменения, внесенные для открытия ssl в PHP 5.6 Отсюда я узнал еще один параметр, который я должен иметь значение false: "по"=>ложные

Так что мой рабочий код выглядит так:

<?php
$arrContextOptions=array(
    "ssl"=>array(
        "verify_peer"=>false,
        "verify_peer_name"=>false,
    ),
);  

$response = file_get_contents("https://maps.co.weber.ut.us/arcgis/rest/services/SDE_composite_locator/GeocodeServer/findAddressCandidates?Street=&SingleLine=3042+N+1050+W&outFields=*&outSR=102100&searchExtent=&f=json", false, stream_context_create($arrContextOptions));

echo $response; ?>

вы не должны просто отключить проверку. Скорее вы должны скачать пакет сертификатов, возможно, curl комплект будет делать?

тогда вам просто нужно поместить его на свой веб-сервер, предоставив пользователю, который запускает php разрешение на чтение файла. Тогда этот код должен работать для вас:

$arrContextOptions=array(
    "ssl"=>array(
        "cafile" => "/path/to/bundle/cacert.pem",
        "verify_peer"=> true,
        "verify_peer_name"=> true,
    ),
);

$response = file_get_contents("https://maps.co.weber.ut.us/arcgis/rest/services/SDE_composite_locator/GeocodeServer/findAddressCandidates?Street=&SingleLine=3042+N+1050+W&outFields=*&outSR=102100&searchExtent=&f=json", false, stream_context_create($arrContextOptions));

надеюсь, корневой сертификат сайта, к которому вы пытаетесь получить доступ, находится в пакете curl. Если это не так, это все равно не будет работать, пока вы не получите корень сертификат сайта и поместите его в свой файл сертификата.

я исправил это, убедившись, что OpenSSL был установлен на моей машине, а затем добавил Это в мой php.ini:

openssl.cafile=/usr/local/etc/openssl/cert.pem

вы можете обойти эту проблему, написав пользовательскую функцию, которая использует curl, как в:

function file_get_contents_curl( $url ) {

  $ch = curl_init();

  curl_setopt( $ch, CURLOPT_AUTOREFERER, TRUE );
  curl_setopt( $ch, CURLOPT_HEADER, 0 );
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
  curl_setopt( $ch, CURLOPT_URL, $url );
  curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, TRUE );

  $data = curl_exec( $ch );
  curl_close( $ch );

  return $data;

}

тогда просто используйте file_get_contents_curl вместо file_get_contents всякий раз, когда вы вызываете url, который начинается с https.

Если ваша версия PHP 5, попробуйте установить cURL, введя следующую команду в терминале:

sudo apt-get install php5-curl

вам в основном нужно установить переменную среды SSL_CERT_FILE в путь к PEM-файлу ssl-сертификата, загруженного по следующей ссылке:http://curl.haxx.se/ca/cacert.pem.

Мне потребовалось много времени, чтобы выяснить это.

следующие ниже шаги, чтобы исправить эту проблему,

  1. загрузите сертификат CA по этой ссылке:https://curl.haxx.se/ca/cacert.pem
  2. найти и открыть php.ini
  3. искать curl.cainfo и вставить абсолютный путь где у вас скачать сертификат. curl.cainfo ="C:\wamp\htdocs\cert\cacert.pem"
  4. перезапустить WAMP / XAMPP (сервер apache).
  5. это работает!

надеюсь, что помогает !!

просто хотел добавить к этому, так как я столкнулся с той же проблемой, и ничего я не мог найти нигде не будет работать (например, загрузка cacert.PEM файл, установка cafile в php.Ини и т. д.)

Если вы используете NGINX и ваш SSL сертификат поставляется с" промежуточным сертификатом", вам нужно объединить промежуточный файл сертификата с вашим основным файлом" mydomain.com.crt", и он должен работать. Apache имеет настройку, специфичную для промежуточных сертификатов, но NGINX не делает этого, поэтому он должен быть в пределах одного и того же файл как ваш обычный сертификат.

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

PHP 5.6 и позже попробуйте загрузить CAs, которому доверяет система, автоматически. Проблемы с этим могут быть исправлены. См.http://php.net/manual/en/migration56.openssl.php для получения дополнительной информации.

версия PHP 5.5 и выше действительно трудно правильно настроить, так как вы вручную должны указать пакет CA в каждом контексте запроса, чего вы не делаете хотите посыпать вокруг вашего кода. Поэтому я решил для своего кода, что для PHP версии

$req = new HTTP_Request2($url);
if (version_compare(PHP_VERSION, '5.6.0', '<')) {
    //correct ssl validation on php 5.5 is a pain, so disable
    $req->setConfig('ssl_verify_host', false);
    $req->setConfig('ssl_verify_peer', false);
}

была такая же проблема ssl на моей машине разработчика( php 7, xampp на windows) с самозаверяющим сертификатом, пытающимся открыть "https://localhost/..."-папка. Очевидно, что корневой сертификат-сборка (cacert.pem) не сработало. Я просто скопировал вручную код с сервера apache.crt-файл в загруженном cacert.Пем и сделал openssl.cafile=путь/к/cacert.запись pem в php.ini

была такая же ошибка с PHP 7 на XAMPP и OSX.

вышеупомянутый ответ в https://stackoverflow.com/ это хорошо, но это не полностью решило проблему для меня. Мне пришлось предоставить полную цепочку сертификатов, чтобы file_get_contents() снова работал. Вот как я это сделал:

получаем root / промежуточный сертификат

прежде всего я должен был выяснить, в чем корень и промежуточный сертификат.

самый удобный способ, возможно, онлайн-сертификат-инструмент, как ssl-shopper

там я нашел три сертификата, один сервер-сертификат и два цепных сертификата (один-корень, другой-промежуточный).

все я нужно сделать, это просто поиск в интернете для них обоих. В моем случае это корень:

thawte DV SSL SHA256 CA

и это приводит к его url thawte.com. поэтому я просто поместил этот сертификат в текстовый файл и сделал то же самое для промежуточного. Сделанный.

получить сертификат узла

следующее, что мне пришлось сделать, это загрузить мой серверный сертификат. В Linux или OS X это можно сделать с помощью openssl:

openssl s_client -showcerts -connect whatsyoururl.de:443 </dev/null 2>/dev/null|openssl x509 -outform PEM > /tmp/whatsyoururl.de.cert

теперь собери их всех вместе

Теперь просто объединить все из них в один файл. (Может быть, это хорошо, чтобы просто положить их в одну папку, я просто объединил их в один файл.) Вы можете сделать это так:

cat /tmp/thawteRoot.crt > /tmp/chain.crt
cat /tmp/thawteIntermediate.crt >> /tmp/chain.crt
cat /tmp/tmp/whatsyoururl.de.cert >> /tmp/chain.crt

скажите PHP, где найти цепочку

есть такая удобная функция openssl_get_cert_locations () которая подскажет вам, где PHP ищет cert файлы. И есть этот параметр, который подскажет file_get_contents () где искать cert файлы. Может быть, оба способа сработают. Я предпочел способ параметра. (По сравнению с выше).

Так это теперь мой PHP-код

$arrContextOptions=array(
    "ssl"=>array(
        "cafile" => "/Applications/XAMPP/xamppfiles/share/openssl/certs/chain.pem",
        "verify_peer"=> true,
        "verify_peer_name"=> true,
    ),
);

$response = file_get_contents($myHttpsURL, 0, stream_context_create($arrContextOptions));

вот и все. функции file_get_contents() снова работает. Без завитка и, надеюсь, без недостатков безопасности.

после падения жертвой этой проблемы на centOS после обновления php до php5.6 я нашел решение, которое работало для меня.

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

php -r 'print_r(openssl_get_cert_locations());' | grep '\[default_cert_file\]' | awk '{print }'

затем использовать это, чтобы получить сертификат и поместить его в папку по умолчанию из кода выше

wget http://curl.haxx.se/ca/cacert.pem -O <default location>

относительно ошибок, подобных

[11-May-2017 19:19: 13 America/Chicago] PHP предупреждение: file_get_contents (): операция SSL не удалась с кодом 1. Сообщения об ошибках OpenSSL: ошибка:14090086:протокол SSL подпрограммы:ssl3_get_server_certificate:сертификат проверить не удалось

вы проверили разрешения, сертификата и каталогов, на которые ссылается в OpenSSL?

вы можете сделать это

var_dump(openssl_get_cert_locations());

чтобы сделать что-то похожее на это

array(8) {
  ["default_cert_file"]=>
  string(21) "/usr/lib/ssl/cert.pem"
  ["default_cert_file_env"]=>
  string(13) "SSL_CERT_FILE"
  ["default_cert_dir"]=>
  string(18) "/usr/lib/ssl/certs"
  ["default_cert_dir_env"]=>
  string(12) "SSL_CERT_DIR"
  ["default_private_dir"]=>
  string(20) "/usr/lib/ssl/private"
  ["default_default_cert_area"]=>
  string(12) "/usr/lib/ssl"
  ["ini_cafile"]=>
  string(0) ""
  ["ini_capath"]=>
  string(0) ""
}

этот проблема расстроила меня на некоторое время, пока я не понял, что моя папка "certs" имела 700 разрешений, когда она должна была иметь 755 разрешений. Помните, что это не папка для ключей и сертификатов. Я рекомендую прочитать это эта ссылка на разрешения ssl.

однажды я сделал

chmod 755 certs

проблема была исправлена, по крайней мере для меня в любом случае.

у меня была такая же проблема еще на защищенную страницу при использовании wget или file_get_contents. Многие исследования (включая некоторые ответы на этот вопрос) привели к простому решению-установке Curl и PHP-Curl - если я правильно понял, Curl имеет корневой CA для Comodo, который решил проблему

установите Curl и PHP-curl addon, а затем перезапустите Apache

sudo apt-get install curl
sudo apt-get install php-curl
sudo /etc/init.d/apache2 reload

все теперь работает.

Comments

    Ничего не найдено.