HTTPS i SSL3_GET_SERVER_CERTIFICATE: weryfikacja certyfikatu nie powiodła się, CA jest w porządku

208

Używam XAMPP do programowania. Niedawno zaktualizowałem moją instalację Xampp ze starej wersji do 1.7.3.

Teraz, gdy zwijam witryny z włączoną obsługą HTTPS, otrzymuję następujący wyjątek

Błąd krytyczny: nieprzechwycony wyjątek „RequestCore_Exception” z komunikatem „zasób cURL: identyfikator zasobu nr 55; błąd cURL: problem z certyfikatem SSL, sprawdź, czy certyfikat CA jest OK. Szczegóły: błąd: 14090086: Procedury SSL: SSL3_GET_SERVER_CERTIFICATE: weryfikacja certyfikatu nie powiodła się (60) ”

Wszyscy sugerują użycie pewnych specjalnych opcji curl z kodu PHP, aby rozwiązać ten problem. Myślę, że nie powinno tak być. Ponieważ nie miałem problemu ze starą wersją XAMPP i stało się to dopiero po zainstalowaniu nowej wersji.

Potrzebuję pomocy, aby dowiedzieć się, jakie ustawienia zmienią się w mojej instalacji PHP, Apache itp. Mogą rozwiązać ten problem.

Josnidhin
źródło

Odpowiedzi:

145

curl zawierał listę akceptowanych urzędów certyfikacji, ale nie łączy już ŻADNYCH certyfikatów urzędów certyfikacji. Dlatego domyślnie odrzuca wszystkie certyfikaty SSL jako niemożliwe do zweryfikowania.

Musisz zdobyć certyfikat urzędu certyfikacji i zwinąć go. Więcej szczegółów w szczegółach cURLS dotyczących certyfikatów SSL serwera .

Marc B.
źródło
4
Curl dzieje się w bibliotece php usług internetowych Amazon. Nie wiedziałem, jak to naprawić bez edycji kodu biblioteki.
Josnidhin,
41
Następnie wyłącz weryfikację certyfikatu ( CURLOPT_SSL_VERIFYPEER-> fałsz). Dodaj certyfikat urzędu certyfikacji witryny, z którą próbujesz wykonać protokół SSL, lub wyłącz weryfikację urzędu certyfikacji. To jedyne dwie dostępne opcje.
Marc B,
78
Just fyi - ustawienie, CURLOPT_SSL_VERIFYPEERktóre falsepokonuje cel używania SSL.
Do
13
@ Dopóki nie pokona połowy celu SSL? Nadal masz prywatność między sobą a swoim rówieśnikiem: po prostu nie masz autentyczności swojego rówieśnika.
Mark Fox
10
bez autentyczności, jaki jest sens szyfrowania przesyłanych danych? Jeśli zostałeś MITMed, dane i tak są zagrożone
hdgarrood
290

To dość powszechny problem w systemie Windows. Trzeba po prostu zestaw cacert.pemdo curl.cainfo.

Od wersji PHP 5.3.7 możesz:

  1. pobierz https://curl.haxx.se/ca/cacert.pem i zapisz gdzieś.
  2. aktualizacja php.ini- dodaj curl.cainfo = "PATH_TO / cacert.pem"

W przeciwnym razie musisz wykonać następujące czynności dla każdego zasobu cURL:

curl_setopt ($ch, CURLOPT_CAINFO, "PATH_TO/cacert.pem");
Артур Курицын
źródło
2
To działało dla mnie w XAMPP na OS X. Naprawiono problem polegający na tym, że wtyczka Wordpress nie aktualizowała się z powodu niemożności zlokalizowania lokalnego certyfikatu.
Jonathan Nicol,
8
Dla każdego, kto próbuje rozwiązać ten problem w systemie Windows przy użyciu Apache, musiałem ustawić pełną ścieżkę (tj. C: \ PATH_TO \ cacert.pem) w moim kodzie PHP. W IIS ścieżka względna wydawała się działać dobrze.
http203
Jeśli plik cacert.pem znajduje się w tym samym katalogu, to curl_setopt ($ ch, CURLOPT_CAINFO, dirname ( FILE ). '/Cacert.pem'); zadziała
mujaffars,
7
Korzystając z WampServer z 2., musisz dodać zmienną do dwóch oddzielnych php.iniplików. Zobacz stackoverflow.com/a/25706713/1101095
Nate
Dziwne / ironiczne jest to, że możesz pobrać curl.haxx.se/ca/cacert.pem przez HTTPS bez określania żadnych dodatkowych opcji. Czy certyfikat dla curl.haxx.se jest utworzony w samym curl?
qbolec 11.03.16
84

Ostrzeżenie: może to powodować problemy z bezpieczeństwem, przed którymi ma chronić SSL, powodując, że cała baza kodu jest niepewna. Jest to sprzeczne z każdą zalecaną praktyką.

Ale naprawdę prostym rozwiązaniem, które zadziałało, było zadzwonienie:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

przed dzwonieniem:

curl_exec():

w pliku php.

Uważam, że wyłącza to wszelką weryfikację certyfikatów SSL.

Chris Dutrow
źródło
65
... i wyłączając weryfikację certyfikatów, pozostawiasz otwarte drzwi dla potencjalnych ataków MITM, przed którymi w przeciwnym razie SSL / TLS ma chronić. NIE Rób tego!
Bruno
12
Tak. Powinienem był zwrócić na to większą uwagę w odpowiedzi. Rób to tylko wtedy, gdy nie pracujesz nad niczym ważnym. Używam go na localhost, aby uzyskać dostęp do stron internetowych, które osobiście zaprogramowałem.
Chris Dutrow
3
Głosuj ode mnie. To jest brudna poprawka umożliwiająca działanie kodu, ale nie rozwiązanie. Odpowiedź udzielona przez Артур Курицын jest znacznie lepsza.
Ilija
2
@Bruno Jest to idealne rozwiązanie dla skryptów pomocniczych, testów, zaufanych aplikacji, intranetu, ... Każdy, kto zna MAŁĄ wiedzę o SSL, wie, w których przypadkach można pominąć weryfikację certyfikatu. Więc wszystkie „inteligentne” komentarze do tej odpowiedzi i rzeczy takie jak „NIE RÓB TO” są po prostu NIEDENSOWE !!
Kenyakorn Ketsombut
5
... „ Każdy, kto zna LITTLE o SSL [...] ”… byłbyś zaskoczony, jak wiele osób nawet nie zadaje sobie trudu, wiedząc trochę o podstawach SSL / TLS, i właśnie nadchodzi tutaj, aby skopiować / wkleić szybką poprawkę dla ich komunikatu o błędzie.
Bruno,
53

Źródło: http://ademar.name/blog/2006/04/curl-ssl-certificate-problem-v.html

Zwijanie się: problem z certyfikatem SSL, sprawdź, czy certyfikat CA jest OK

07 kwietnia 2006 r

Podczas otwierania bezpiecznego adresu URL za pomocą Curl może pojawić się następujący błąd:

Problem z certyfikatem SSL, sprawdź, czy certyfikat CA jest OK

Wyjaśnię, dlaczego błąd i co należy z tym zrobić.

Najłatwiejszym sposobem na pozbycie się błędu jest dodanie do skryptu następujących dwóch wierszy. To rozwiązanie stanowi zagrożenie dla bezpieczeństwa.

//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); 

Zobaczmy, co robią te dwa parametry. Cytując instrukcję.

CURLOPT_SSL_VERIFYHOST : 1, aby sprawdzić istnienie wspólnej nazwy w certyfikacie równorzędnym SSL. 2, aby sprawdzić istnienie wspólnej nazwy, a także sprawdzić, czy jest ona zgodna z podaną nazwą hosta.

CURLOPT_SSL_VERIFYPEER : FALSE, aby powstrzymać CURL od weryfikacji certyfikatu peera. Alternatywne certyfikaty do weryfikacji można określić za pomocą opcji CURLOPT_CAINFO lub katalog certyfikatów można określić za pomocą opcji CURLOPT_CAPATH. CURLOPT_SSL_VERIFYHOST może także wymagać wartości PRAWDA lub FAŁSZ, jeśli CURLOPT_SSL_VERIFYPEER jest wyłączony (domyślnie 2). Ustawienie CURLOPT_SSL_VERIFYHOST na 2 (jest to wartość domyślna) zagwarantuje, że przedstawiony Ci certyfikat będzie miał „wspólną nazwę” pasującą do URN, którego używasz do uzyskania dostępu do zdalnego zasobu. Jest to zdrowy czek, ale nie gwarantuje, że twój program nie zostanie oszukany.

Wpisz „mężczyzna w środku”

Zamiast tego twój program może zostać wprowadzony w błąd i rozmawiać z innym serwerem. Można to osiągnąć za pomocą kilku mechanizmów, takich jak zatrucie dns lub arp (to historia na inny dzień). Intruz może również samopodpisać certyfikat z taką samą „wspólną nazwą”, jakiej oczekuje Twój program. Komunikacja nadal będzie szyfrowana, ale będziesz zdradzał swoje tajemnice oszustowi. Ten rodzaj ataku nazywa się „człowiekiem w środku”

Pokonanie „mężczyzny na środku”

Cóż, musimy sprawdzić, czy przedstawiony nam certyfikat jest prawdziwy. Robimy to, porównując go z certyfikatem, któremu możemy * zaufać.

Jeśli zdalny zasób jest chroniony certyfikatem wydanym przez jeden z głównych urzędów certyfikacji, takich jak Verisign, GeoTrust i in., Można bezpiecznie porównać z pakietem certyfikatów CA Mozilli, który można uzyskać ze strony http://curl.haxx.se/docs/caextract .html

Zapisz plik cacert.pemgdzieś na serwerze i ustaw następujące opcje w skrypcie.

curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, TRUE); 
curl_setopt ($ch, CURLOPT_CAINFO, "pathto/cacert.pem");

za wszystkie powyższe informacje Źródło: http://ademar.name/blog/2006/04/curl-ssl-certificate-problem-v.html

Deepak Oberoi
źródło
38
Powszechnie uważa się za grzeczne uznanie źródła informacji i cytowanie tylko niektórych części istotnych dla pytania, a nie tylko kopiowanie i wklejanie tutaj!
Dan Herd
1
Przepraszam, byłem daleko, tak aprobuję Dana za to i zaktualizowałem Post
Deepak Oberoi,
6
Przynajmniej Deepak starał się to zbadać. @danherd Więc Danherd, właśnie przeprowadziłeś badania, aby dowiedzieć się, że skądś wziął kod? Jakie było prawo do atrybucji tego kodu? Zamiast marnować czas na szukanie błędów innych osób, spróbuj pomóc komuś samemu. Nie walcz, dziel się!
GTodorov,
17

Powyższe rozwiązania są świetne, ale jeśli używasz WampServer, może się okazać, że ustawienie curl.cainfozmiennej php.ininie działa.

W końcu odkryłem, że WampServer ma dwa php.inipliki:

C:\wamp\bin\apache\Apachex.x.x\bin
C:\wamp\bin\php\phpx.x.xx

Pierwszy jest używany do wywoływania plików PHP przez przeglądarkę internetową, a drugi do wywoływania polecenia przez wiersz poleceń lub shell_exec().

TL; DR

Jeśli używasz WampServer, musisz dodać curl.cainfolinię do obu php.ini plików.

Nate
źródło
6

Z miłości do wszystkiego, co święte ...

W moim przypadku musiałem ustawić openssl.cafilezmienną konfiguracyjną PHP na ścieżkę pliku PEM.

Ufam, że to prawda, że ​​istnieje wiele systemów, w których ustawienie curl.cainfow konfiguracji PHP jest dokładnie tym, czego potrzeba, ale w środowisku, w którym pracuję, jest kontener dokujący eboraas / laravel , który używa Debiana 8 (jessie) i PHP 5.6, ustawienie tej zmiennej nie załatwiło sprawy.

Zauważyłem, że dane wyjściowe php -inie wspominały nic o tym konkretnym ustawieniu konfiguracji, ale zawierało kilka wierszy openssl. Istnieje zarówno opcja openssl.capathi openssl.cafile, ale tylko ustawienie drugiego dozwolonego zwijania za pośrednictwem PHP, aby w końcu było w porządku z adresami URL HTTPS.

Spencer Williams
źródło
Dziękuję Ci! Ustawienie curl.cainfo również nie działało dla mnie, ale ustawienie openssl.cafile zadziałało! Korzystam z systemu Windows 7 z XAMPP i PHP 7.1.1.
knezmilos 24.04.17
@knezmilos, jak poszedłeś na temat ustawiania pliku openssl.cafile? skąd pobrałeś i jak go aktywować?
Krys
Cóż, minęło trochę czasu, ale myślę, że to coś takiego: curl.cainfo = "C: \ xampp \ cacert \ cacert.pem" i openssl.cafile = "C: \ xampp \ cacert \ cacert.pem" w php. ini, podczas gdy myślę, że dostałem plik pem z jednej z odpowiedzi tutaj.
knezmilos
1
„Dla miłości wszystkiego, co święte ...”. Działa to w mojej konfiguracji Ubuntu 18.08 / Apache / Php7.2. Jeśli błąd zwijania wskazuje właściwy plik, to z pewnością jest to błąd otwierania
JTG
4

Czasami jeśli aplikacja, z którą próbujesz się skontaktować, ma certyfikaty z podpisem własnym, normalny plik cacert.pem z http://curl.haxx.se/ca/cacert.pem nie rozwiązuje problemu.

Jeśli masz pewność co do adresu URL punktu końcowego usługi, naciśnij go w przeglądarce, zapisz ręcznie certyfikat w formacie „X 509 certyfikat z łańcuchem (PEM)”. Wskaż ten plik certyfikatu za pomocą

curl_setopt ($ch, CURLOPT_CAINFO, "pathto/{downloaded certificate chain file}");   
madRai
źródło
4

Mam ten sam błąd na amazonie AMI Linux.

Rozwiązałem, ustawiając curl.cainfo na /etc/php.d/curl.ini

https://gist.github.com/reinaldomendes/97fb2ce8a606ec813c4b

Dodatek październik 2018 r

Na Amazon Linux v1 edytuj ten plik

vi /etc/php.d/20-curl.ini

Aby dodać tę linię

curl.cainfo="/etc/ssl/certs/ca-bundle.crt"
Reinaldo Mendes
źródło
Perfekcyjnie, dzięki! Zaktualizowałem pytanie, aby dodać dokładnie to, co zrobiłem, co rozwiązało problem, zamiast tworzyć kolejną odpowiedź.
Tim
3

Podczas ustawiania opcji zwijania dla CURLOPT_CAINFO pamiętaj, aby używać pojedynczych cudzysłowów, użycie podwójnych cudzysłowów spowoduje tylko kolejny błąd. Twoja opcja powinna wyglądać następująco:

curl_setopt ($ch, CURLOPT_CAINFO, 'c:\wamp\www\mywebfolder\cacert.pem');

Dodatkowo w ustawieniach pliku php.ini należy zapisać jako: (zauważ moje podwójne cudzysłowy)

curl.cainfo = "C:\wamp\www\mywebfolder"

Umieszczam go bezpośrednio poniżej linii, która mówi: extension=php_curl.dll

(Tylko w celu organizowania, możesz umieścić go w dowolnym miejscu w swoim miejscu php.ini, po prostu umieszczam go w pobliżu innego odwołania do curl, więc kiedy szukam za pomocą słowa kluczowego curl, nie mogę znaleźć obu odwołań do curl w jednym obszarze).

LOwens1931
źródło
1
Mam nadzieję, że php.ini powinien wskazywać na plik pem zamiast na folder nadrzędny
dejjub-AIS
2

Skończyło się tutaj, gdy próbowałem zdobyć GuzzleHttp (php + apache na Macu), aby uzyskać stronę z www.googleapis.com.

Oto moje ostatnie rozwiązanie na wypadek, gdyby komukolwiek to pomogło.

Sprawdź łańcuch certyfikatów dla dowolnej domeny, w której występuje ten błąd. Dla mnie była to googleapis.com

openssl s_client -host www.googleapis.com -port 443

Otrzymasz coś takiego:

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

Uwaga: Przechwyciłem to po rozwiązaniu problemu, ponieważ dane wyjściowe łańcucha mogą wyglądać inaczej.

Następnie musisz spojrzeć na certyfikaty dozwolone w php. Uruchom phpinfo () na stronie.

<?php echo phpinfo();

Następnie poszukaj pliku certyfikatu załadowanego z danych wyjściowych strony:

openssl.cafile  /usr/local/php5/ssl/certs/cacert.pem

Jest to plik, który musisz naprawić, dodając do niego poprawne certyfikaty.

sudo nano /usr/local/php5/ssl/certs/cacert.pem

Zasadniczo musisz dołączyć poprawne „podpisy” certyfikatu na końcu tego pliku.

Niektóre z nich można znaleźć tutaj: Może być konieczne wyszukanie w Google innych osób w łańcuchu, jeśli są one potrzebne.

Wyglądają tak:

przykładowy obraz certyfikatu

( Uwaga: jest to obraz, więc ludzie nie będą po prostu kopiować / wklejać certyfikatów z stackoverflow )

Gdy odpowiednie certyfikaty znajdą się w tym pliku, uruchom ponownie apache i przetestuj.

TrophyGeek
źródło
0

Możesz spróbować ponownie zainstalować ca-certificatespakiet lub jawnie zezwolić na dany certyfikat, jak opisano tutaj .

teren
źródło
-5

Rozwiązanie jest bardzo proste! Umieść tę linię przed curl_exec:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

Dla mnie to działa.

Zsolt Boszormenyi
źródło
7
Nigdy, nigdy nie wyłączaj weryfikacji równorzędnej, chyba że nie przejmujesz się, czy dane zostały naruszone podczas transportu.
rdlowrey
Zgoda. Jeśli chcesz mieć bezpieczną aplikację, potrzebujesz weryfikacji równorzędnej.
braden
2
„Nigdy, nigdy nie wyłączaj weryfikacji równorzędnej”, chyba że chcesz domyślnej funkcjonalności przeglądarki haha. Ponadto, dlaczego jest to tak bardzo zaniedbywane? To jedyna krótka, słodka odpowiedź na temat ORAZ skuteczna.
Adam F
@AdamF FYI, przeglądarki domyślnie weryfikują certyfikat równorzędny, dają jedynie opcję ręcznego pomijania błędów, z ostrzeżeniem.
Bruno,