Błąd zwijania 60, problem z certyfikatem SSL: certyfikat z podpisem własnym w łańcuchu certyfikatów

81

Próbuję wysłać żądanie curl z moim poprawnym APP_ID, APP_SECRET itp. Do

  https://oauth.vk.com/access_token?client_id=APP_ID&client_secret=APP_SECRET&code=7a6fa4dff77a228eeda56603b8f53806c883f011c40b72630bb50df056f6479e52a&redirect_uri=REDIRECT_URI 

Muszę uzyskać z niego access_token, ale otrzymuję FALSE i curl_error()wypisuję następną wiadomość w przeciwnym razie:

60: SSL certificate problem: self signed certificate in certificate chain

Mój kod to:

    // create curl resource
    $ch = curl_init();

    // set url
    curl_setopt($ch, CURLOPT_URL, $url);
    //return the transfer as a string
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

    // $output contains the output string
    $output = curl_exec($ch);
    if ( ! $output) {
        print curl_errno($ch) .': '. curl_error($ch);
    }

    // close curl resource to free up system resources
    curl_close($ch);

    return $output;

Kiedy przechodzę ręcznie do powyższego linku, dobrze otrzymuję access_token. Dlaczego nie działa z lokami? Prosimy o pomoc.

Victor Bocharsky
źródło
Może potrzebuję certyfikatu z .crtprzedłużeniem? Ale nie wiem, jak go zdobyć
Victor Bocharsky
1
Prosimy o unikanie [zepsutej] zaakceptowanej odpowiedzi. Zamiast tego użyj odpowiedzi @ erlangsec. Zobacz także Najbardziej niebezpieczny kod na świecie: sprawdzanie poprawności certyfikatów SSL w oprogramowaniu innym niż przeglądarka .
jww

Odpowiedzi:

180

Odpowiedzi sugerujące wyłączenie CURLOPT_SSL_VERIFYPEERnie powinny być akceptowane. Pytanie brzmi „Dlaczego to nie działa z cURL” i jak słusznie zauważył Martijn Hols, jest to niebezpieczne.

Błąd jest prawdopodobnie spowodowany brakiem aktualnego pakietu certyfikatów głównych CA. Zwykle jest to plik tekstowy z zestawem podpisów kryptograficznych, których curl używa do weryfikacji certyfikatu SSL hosta.

Musisz upewnić się, że Twoja instalacja PHP zawiera jeden z tych plików i że jest aktualny (w przeciwnym razie pobierz go tutaj: http://curl.haxx.se/docs/caextract.html ).

Następnie ustaw w php.ini :

curl.cainfo = <absolute_path_to> cacert.pem

Jeśli ustawiasz go w czasie wykonywania, użyj:

curl_setopt ($ch, CURLOPT_CAINFO, dirname(__FILE__)."/cacert.pem");
erlangsec
źródło
1
Dzięki, ale szukałem propozycji pracy z zewnętrznym API. Więc sugestia, że ​​proponuję @SabujHassan działa i, jak zrozumiałem, API, z którego korzystałem, nie zapewnia SSL.
Victor Bocharsky
Doskonałe rozwiązanie. Dziękuję bardzo :)
Chandra Nakka
1
Działa jak magia. To powinna być odpowiedź, „zaakceptowana odpowiedź” jest łatwa, ale zła ze względów bezpieczeństwa.
KristCont,
Dzięki, jak powiedziałem, działa świetnie! To rzeczywiście powinna być prawidłowa odpowiedź.
PostMans
2
Warto zauważyć, że curl.cainfo nie pojawia się w phpinfo () w PHP 7.1 / 7.2, chociaż openssl.cafile tak. php.net/manual/en/curl.configuration.php
Elijah Lynn
58

To obejście jest niebezpieczne i nie jest zalecane :

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

Nie jest dobrym pomysłem wyłączanie weryfikacji SSL na poziomie równorzędnym. Może to narazić Twoje żądania na atakujące MITM.

W rzeczywistości potrzebujesz tylko aktualnego pakietu certyfikatów głównych CA. Zainstalowanie zaktualizowanej wersji jest tak proste, jak:

  1. Pobieranie aktualnego cacert.pempliku ze strony cURL i

  2. Ustawienie ścieżki do niego w pliku php.ini, np. W systemie Windows:

    curl.cainfo=c:\php\cacert.pem

Otóż ​​to!

Bądź bezpieczny.

zxcmehran
źródło
5
Możesz również ustawić tę opcję w swoim kodzie, jeśli nie masz uprawnień do edycji php.inipliku globalnego : curl_setopt ($curl_ch, CURLOPT_CAINFO, dirname(__FILE__)."/cacert.pem");
zxcmehran
2
Pracowałem nad środowiskiem
deweloperskim
2
Dobry do testowania na dev env
Gaurav Rai,
To okropna rada i odpowiedź powinna zostać usunięta.
miken32
4
@ miken32 tak, a następnie proponuję alternatywne bezpieczne rozwiązanie jako zamiennik niebezpiecznego obejścia. Czytaj dalej do końca.
zxcmehran
3

Jeśli certyfikaty SSL nie są poprawnie zainstalowane w twoim systemie, możesz otrzymać ten błąd:

Błąd cURL 60: problem z certyfikatem SSL: nie można uzyskać certyfikatu lokalnego wystawcy.

Możesz rozwiązać ten problem w następujący sposób:

Pobierz plik ze zaktualizowaną listą certyfikatów z https://curl.haxx.se/ca/cacert.pem

Przenieś pobrany cacert.pemplik w jakieś bezpieczne miejsce w systemie

Zaktualizuj php.iniplik i skonfiguruj ścieżkę do tego pliku:

sunil
źródło
Być może będziesz musiał ustawić openssl.cafile="C:/dev/ssl/mywebsite.local.crt"­w php.ini
François Breton
3

Ważne: ten problem doprowadzał mnie do szału na kilka dni i nie mogłem dowiedzieć się, co się dzieje z moimi instalacjami curl i openssl. W końcu zorientowałem się, że to mój pośredni certyfikat (w moim przypadku GoDaddy) był nieaktualny. Wróciłem do panelu administracyjnego SSL godaddy, pobrałem nowy certyfikat pośredni i problem zniknął.

Jestem pewien, że to jest problem dla niektórych z was.

Najwyraźniej GoDaddy zmienił w pewnym momencie swój certyfikat pośredni z powodu problemów z bezpieczeństwem, ponieważ teraz wyświetla to ostrzeżenie:

„Pamiętaj, aby używać nowych certyfikatów pośrednich SHA-2 zawartych w pobranym pakiecie”.

Mam nadzieję, że to pomoże niektórym z was, ponieważ oszalałem i to rozwiązało problem na WSZYSTKICH moich serwerach.

Zawietrzny
źródło
Chociaż nie jest to dokładnie związane z pytaniem, może ogólnie przedstawiać sensowne informacje.
peter.hrasko.sk
Komunikaty o błędach generowane przez curl mogą czasami być zagadkowe i wprowadzające w błąd. Jestem pewien, że niektórzy ludzie, którzy otrzymywali błąd „certyfikatu z podpisem własnym”, otrzymywali go z powodu przytoczonego przeze mnie dziwactwa. Chciałem również dodać, że podczas budowania curl użyłem ciągu konfiguracyjnego: ./configure --with-ca-bundle = / etc / ssl / certs / ca-bundle.crt, a także użyłem skryptu perl lib / mk -ca-bundle.pl, aby wygenerować ładny, świeży plik ca-bundle.crt. Używałem serwera WWW Apache, ale nie zastąpiłem istniejącego certyfikatu pośredniego zaktualizowanym certyfikatem GoDaddy.
Lee
-3

Błąd: problem z certyfikatem SSL: certyfikat z podpisem własnym w łańcuchu certyfikatów

Solution:
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);    
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_FAILONERROR, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
Sundar
źródło