file get contents (): operacja SSL nie powiodła się z kodem 1, nie udało się włączyć crypto

Próbowałem uzyskać dostęp do tej konkretnej usługi REST ze strony PHP, którą stworzyłem na naszym serwerze. Zawęziłem problem do tych dwóch linii. Więc moja strona PHP wygląda tak:

<?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; ?>

Strona umiera w linii 2 z następującymi błędami:

  • Warning: file_get_contents (): operacja SSL nie powiodła się z kodem 1. Komunikaty o błędach OpenSSL: błąd: 14090086: SSL procedury: SSL3_GET_SERVER_CERTIFICATE: certificate verify failed in ...php on line 2
    • Warning: file_get_contents (): Failed to enable crypto in ...php on linia 2
    • Ostrzeżenie: 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): nie udało się otworzyć strumienia: operacja nie powiodła się ...php on line 2

Używamy serwera Gentoo. Niedawno zaktualizowaliśmy PHP do wersji 5.6. To było po aktualizacji, kiedy pojawił się ten problem.

Znalazłem po zastąpieniu usługi REST adresem takim jak https://www.google.com; Moja strona działa dobrze.

We wcześniejszej próbie ustawiłem “verify_peer”=>false i przekazałem to jako argument do file_get_contents, jak opisano tutaj: file_get_contents ignorując verify_peer=>false? ale jak zauważył pisarz; to nie robi różnicy.

Zapytałem jednego z naszych administratorów serwerów, czy te linie w naszym php.plik INI istnieje:

  • extension = php_openssl.dll
  • allow_url_fopen = On

Powiedział mi, że skoro jesteśmy na Gentoo, OpenSSL jest kompilowany, gdy build; i nie jest ustawiony w php.plik ini.

Potwierdziłem również, że allow_url_fopen działa. Ze względu na specjalistyczny charakter tego problemu; nie znajduję zbyt wielu informacji do pomocy. Czy ktoś z Was spotkał się z czymś takim? Dzięki.

Author: AbraCadaver, 2014-10-01

17 answers

To był niezwykle pomocny link do znalezienia:

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

Oficjalny dokument opisujący zmiany dokonane w open ssl w PHP 5.6 Stąd dowiedziałem się o jeszcze jednym parametrze, który powinienem ustawić na false: "verify_peer_name" = > false

Uwaga: ma to bardzo znaczące implikacje dla bezpieczeństwa. Wyłączenie weryfikacji potencjalnie pozwala atakującemu MITM na użycie nieprawidłowego zaświadczenie o podsłuchiwaniu wniosków. Chociaż może to być przydatne w rozwoju lokalnym, inne podejścia powinny być stosowane w produkcji.

Więc mój kod roboczy wygląda tak:

<?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; ?>
 375
Author: Joe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-07-09 15:14:39

Nie powinieneś po prostu wyłączać weryfikacji. Raczej powinieneś pobrać pakiet certyfikatu, być może pakiet curl wystarczy?

Następnie wystarczy umieścić go na swoim serwerze WWW, dając użytkownikowi, który uruchamia PHP uprawnienia do odczytu pliku. Wtedy ten kod powinien działać dla Ciebie:

$arrContextOptions= [
    'ssl' => [
        '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)
);

Miejmy nadzieję, że główny certyfikat witryny, do której próbujesz uzyskać dostęp, znajduje się w pakiecie curl. Jeśli tak nie jest, to nadal nie będzie działać, dopóki nie otrzymasz głównego certyfikatu witryny i nie umieścisz go do pliku certyfikatu.

 159
Author: elitechief21,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-12-06 21:18:39

Naprawiłem to, upewniając się, że OpenSSL został zainstalowany na moim komputerze, a następnie dodając to do mojego php.ini:

openssl.cafile=/usr/local/etc/openssl/cert.pem
 38
Author: andlin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-01 13:33:00

Możesz obejść ten problem, pisząc niestandardową funkcję, która używa curl, jak w:

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;

}

Następnie po prostu użyj file_get_contents_curl zamiast file_get_contents, gdy wywołujesz adres URL zaczynający się od https.

 23
Author: Ben Shoval,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-28 18:29:12

Pracując dla mnie, używam PHP 5.6. rozszerzenie OpenSSL powinno być włączone i podczas wywoływania google map api verify_peer make false Poniższy kod działa dla mnie.

<?php
$arrContextOptions=array(
    "ssl"=>array(
         "verify_peer"=>false,
         "verify_peer_name"=>false,
    ),
);  
$url = "https://maps.googleapis.com/maps/api/geocode/json?latlng="
      . $latitude
      . ","
      . $longitude
      . "&sensor=false&key="
      . Yii::$app->params['GOOGLE_API_KEY'];

$data = file_get_contents($url, false, stream_context_create($arrContextOptions));

echo $data;
?>
 15
Author: Dipti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-17 12:03:03

Jeśli Twoja wersja PHP jest 5, spróbuj zainstalować cURL, wpisując następujące polecenie w Terminalu:

sudo apt-get install php5-curl
 10
Author: ARUNBALAN NV,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-16 06:56:10

Zasadniczo musisz ustawić zmienną środowiskową SSL_CERT_FILE na ścieżkę do pliku PEM certyfikatu ssl pobranego z poniższego linku: http://curl.haxx.se/ca/cacert.pem .

Zajęło mi dużo czasu, żeby to rozgryźć.

 8
Author: Kshitij Mittal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-09 08:46:56

Poniższe kroki rozwiązują ten problem,

  1. Pobierz certyfikat CA z tego linku: https://curl.haxx.se/ca/cacert.pem
  2. Znajdź i otwórz php.ini
  3. poszukaj curl.cainfo i wklej ścieżkę bezwzględną gdzie masz pobrać certyfikat. curl.cainfo ="C:\wamp\htdocs\cert\cacert.pem"
  4. Restart WAMP / XAMPP (serwer apache).
  5. To działa!
Mam nadzieję, że to pomoże !!
 6
Author: shakee93,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-06 17:02:47

Po prostu chciałem dodać do tego, ponieważ natknąłem się na ten sam problem i nic nie mogłem znaleźć nigdzie nie działa (np pobieranie cacert.plik pem, ustawianie cafile w php.ini itp.)

Jeśli używasz NGINX, a twój certyfikat SSL zawiera "certyfikat pośredni", musisz połączyć pośredni plik cert z głównym plikiem "mydomain. com. crt" i powinien działać. Apache ma ustawienie specyficzne dla pośrednich Cert, ale NGINX nie musi więc znajdować się w tym samym pliku, co twój zwykły cert.

 5
Author: SlickTheNick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-26 20:40:31

Powodem tego błędu jest to, że PHP nie ma listy zaufanych organów certyfikujących.

PHP 5.6 i Później spróbuj załadować CAs zaufanego przez system automatycznie. Problemy z tym można naprawić. Zobacz http://php.net/manual/en/migration56.openssl.php aby uzyskać więcej informacji.

PHP 5.5 i wcześniejsze są naprawdę trudne do poprawnej konfiguracji, ponieważ ręcznie musisz określić pakiet CA w każdym kontekście żądania, czego nie chcesz posypać wokół swojego kod. Postanowiłem więc dla mojego kodu, że dla wersji 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);
}
 4
Author: cweiske,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-06 21:34:02

Miał ten sam błąd w PHP 7 na XAMPP i OSX.

Powyższa odpowiedź w https://stackoverflow.com / jest dobry, ale to nie całkowicie rozwiązać problem dla mnie. Musiałem dostarczyć kompletny łańcuch certyfikatów, aby file_get_contents() znów działało. Tak to zrobiłem:

Get root / intermediate certificate

Najpierw musiałem dowiedzieć się, co to jest root i certyfikat pośredni.

Najbardziej wygodnym sposobem jest być może Narzędzie cert online, takie jak ssl-shopper

Znalazłem tam trzy certyfikaty, jeden server-certificate i dwa Chain-certificates (jeden to root, drugi to pośredni).

Wszystko, co muszę zrobić, to przeszukać internet w poszukiwaniu ich obu. W moim przypadku jest to root:

Thawte DV SSL SHA256 CA

I prowadzi do jego url thawte.com . więc po prostu włożyłem ten cert do pliku tekstowego i zrobiłem to samo dla średnio zaawansowanych. Załatwione.

Pobierz certyfikat hosta

Następną rzeczą, jaką musiałem zrobić, to pobrać certyfikat serwera. Na Linuksie lub OS X można to zrobić za pomocą openssl:

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

Teraz połącz je wszystkie

Teraz połącz wszystkie w jeden plik. (Może dobrze jest po prostu umieścić je w jednym folderze, po prostu połączyłem je w jeden plik). Możesz to zrobić tak:
cat /tmp/thawteRoot.crt > /tmp/chain.crt
cat /tmp/thawteIntermediate.crt >> /tmp/chain.crt
cat /tmp/tmp/whatsyoururl.de.cert >> /tmp/chain.crt

Tell PHP where to find the chain

Jest to przydatna funkcja openssl_get_cert_locations (), która powie Ci, gdzie PHP szuka plików cert. I jest taki parametr, który powie file_get_contents (), gdzie szukać plików cert. Może oba sposoby zadziałają. Wolałem sposób parametryzacji. (W porównaniu do rozwiązania wspomnianego powyżej).

Więc to jest teraz Mój kod 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));
To wszystko. file_get_contents() działa ponownie. Bez zawijania i oby bez wad bezpieczeństwa.
 4
Author: n.r.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-14 11:56:26

Padając ofiarą tego problemu na centOS po aktualizacji php do php5. 6 znalazłem rozwiązanie, które działało dla mnie.

Uzyskaj prawidłowy katalog, w którym Twoje certy mają być domyślnie umieszczone za pomocą tego

php -r 'print_r(openssl_get_cert_locations()["default_cert_file"]);'

Następnie użyj tego, aby uzyskać cert i umieścić go w domyślnej lokalizacji znalezionej z powyższego kodu

wget http://curl.haxx.se/ca/cacert.pem -O <default location>
 4
Author: Edward DiGirolamo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-07-18 15:54:11

Miałem ten sam problem z ssl na mojej maszynie programisty (php 7, xampp na windows) z własnym podpisanym certyfikatem próbującym otworzyć " https://localhost/..."- plik. Oczywiście root-certificate-assembly (cacert.pem) nie zadziałało. Właśnie skopiowałem ręcznie kod z serwera apache.crt-plik w pobranym pliku cacert.pem i zrobił openssl.cafile=path / to / cacert.wpis pem w php.ini

 3
Author: hangerer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-12 15:21:41

Kolejną rzeczą do wypróbowania jest ponowne zainstalowanie ca-certificates zgodnie z opisem tutaj.

# yum reinstall ca-certificates
...
# update-ca-trust force-enable 
# update-ca-trust extract

I kolejną rzeczą do wypróbowania jest jawne Zezwolenie na certyfikat jednej witryny, o którym mowa, zgodnie z opisem tutaj (zwłaszcza jeśli jedna witryna jest twoim własnym serwerem i już masz.pem in reach).

# cp /your/site.pem /etc/pki/ca-trust/source/anchors/
# update-ca-trust extract

Wpadłem na to dokładnie, więc błąd po aktualizacji do PHP 5.6 na CentOS 6 próbując uzyskać dostęp do samego serwera, który ma certyfikat cheapsslsecurity, który może był potrzebny być aktualizowane, ale zamiast tego zainstalowałem certyfikat letsencrypt i te dwa kroki powyżej to zrobił sztuczkę. Nie wiem, dlaczego drugi krok był konieczny.


Przydatne Polecenia

Zobacz wersję openssl:

# openssl version
OpenSSL 1.0.1e-fips 11 Feb 2013

Wyświetl bieżące ustawienia PHP CLI ssl:

# php -i | grep ssl
openssl
Openssl default config => /etc/pki/tls/openssl.cnf
openssl.cafile => no value => no value
openssl.capath => no value => no value
 2
Author: site,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-11 18:29:18

Odnośnie błędów podobnych do

[11-May-2017 19:19:13 America/Chicago] PHP Warning: file_get_contents(): operacja SSL nie powiodła się z kodem 1. Komunikaty o błędach OpenSSL: w związku z tym, że nie jest to możliwe, nie jest to możliwe.]}

Sprawdziłeś uprawnienia cert i katalogów, do których odwołuje się openssl?

Możesz to zrobić

var_dump(openssl_get_cert_locations());

Aby uzyskać coś podobnego

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) ""
}

Ten problem mnie sfrustrował przez jakiś czas, aż zdałem sobie sprawę, że mój folder "certs" miał 700 uprawnień, podczas gdy powinien mieć 755 uprawnień. Pamiętaj, że nie jest to folder dla kluczy, ale certyfikaty. Polecam przeczytać ten ten link NA ssl permissions.

Raz zrobiłem

chmod 755 certs
Problem został rozwiązany, przynajmniej dla mnie.
 1
Author: Aleks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-07-18 15:54:41

Miałem ten sam problem dla innej zabezpieczonej strony podczas korzystania z wget lub file_get_contents. Wiele badań (w tym niektóre odpowiedzi na to pytanie) zaowocowało prostym rozwiązaniem-zainstalowaniem Curl i PHP-Curl - jeśli dobrze zrozumiałem, Curl ma Root CA dla Comodo, który rozwiązał problem

Zainstaluj Curl i PHP-Curl addon, a następnie uruchom ponownie Apache

sudo apt-get install curl
sudo apt-get install php-curl
sudo /etc/init.d/apache2 reload
Wszystko działa.
 0
Author: Aubs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-31 13:31:56

Na początku musisz mieć włączone rozszerzenie curl w PHP. Następnie możesz użyć tej funkcji:

function file_get_contents_ssl($url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_REFERER, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3000); // 3 sec.
    curl_setopt($ch, CURLOPT_TIMEOUT, 10000); // 10 sec.
    $result = curl_exec($ch);
    curl_close($ch);
    return $result;
}

Działa podobnie do funkcji file_get_contents(..).

Przykład:

echo file_get_contents_ssl("https://www.example.com/");

Wyjście:

<!doctype html>
<html>
<head>
    <title>Example Domain</title>
...
 0
Author: Martin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-02-13 21:06:56