błąd cURL 60: Certyfikat SSL: nie można uzyskać certyfikatu lokalnego wystawcy

232

Korzystam z WAMP w lokalnym środowisku programistycznym i próbuję obciążyć kartę kredytową, ale pojawia się komunikat o błędzie:

błąd cURL 60: Problem z certyfikatem SSL: nie można uzyskać certyfikatu lokalnego wystawcy

Dużo szukałem w Google i wiele osób sugeruje, żebym pobrał ten plik: cacert.pem , umieściłem go gdzieś i odsyłam do niego w php.ini. To jest część mojego php.ini:

curl.cainfo = "C:\Windows\cacert.pem"

Jednak nawet po kilkukrotnym ponownym uruchomieniu serwera i zmianie ścieżki pojawia się ten sam komunikat o błędzie.

Używam WAMP z modułów Apache i mam włączony moduł ssl_module. A z rozszerzeń PGP mam włączone php_curl.

Nadal ten sam komunikat o błędzie. Dlaczego tak się dzieje?

Teraz śledzę tę poprawkę: Jak naprawić błąd PHP CURL 60 SSL

Co sugeruje, że dodałem te linie do moich opcji CURL:

curl_setopt($process, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem');
curl_setopt($process, CURLOPT_SSL_VERIFYPEER, true);

Gdzie mogę dodać opcje do mojego cURL? Najwyraźniej nie za pośrednictwem wiersza polecenia, ponieważ mój CLI nie znajduje polecenia „curl_setopt”

EDYTOWAĆ

Oto kod, który uruchamiam:

public function chargeStripe()
{
    $stripe = new Stripe;
    $stripe = Stripe::make(env('STRIPE_PUBLIC_KEY'));

    $charge = $stripe->charges()->create([
        'amount'   => 2900,
        'customer' => Input::get('stripeEmail'),
        'currency' => 'EUR',
    ]);

    dd($charge);

    // echo $charge[Input::get('stripeToken')];


    return Redirect::route('step1');
}
Miłość i szczęście
źródło
Zakładając, że nie ma problemów z twoim kodem, może to być twoja zapora ogniowa. Spróbuj wyłączyć zaporę ogniową w celu przetestowania.
Waqar ul islam
did't Dałem Ci odpowiedzieć na to pytanie tutaj ? :)
Limon Monte,
@limonte możliwe, musiał zmienić projekty i prawdopodobnie miał ten sam problem z nowym projektem. Powróci do problemu żużlu i być może jest to ta sama poprawka. brb
LoveAndHappiness
1
Czy wypróbowałeś najnowszą wersję paska? Widzę komunikat zatwierdzenia, który zmienił coś wspólnego z certyfikatami ... github.com/stripe/stripe-php/commit/…
thelastshadow
1
@LoveAndHappiness czy masz rozwiązanie tego problemu? Mam ten sam błąd z paskiem. Daj mi znać, jeśli masz jakieś rozwiązanie.
Dev

Odpowiedzi:

515

Działające rozwiązanie zakładające, że masz system Windows za pomocą XAMPP:

Serwer XAMPP

  1. Podobne dla innych środowisk
    • pobierz i wypakuj dla cacert.pem tutaj (czysty format / dane pliku)

https://curl.haxx.se/docs/caextract.html

  1. Umieść go tutaj w następującym katalogu.

C: \ xampp \ php \ extras \ ssl \ cacert.pem

  1. W swoim php.ini umieść ten wiersz w tej sekcji („c: \ xampp \ php \ php.ini”):
;;;;;;;;;;;;;;;;;;;;
; php.ini Options  ;
;;;;;;;;;;;;;;;;;;;;

curl.cainfo = "C:\xampp\php\extras\ssl\cacert.pem"
  1. Uruchom ponownie serwer / apache

  2. Problem rozwiązany!

(Odwołanie: https://laracasts.com/discuss/channels/general-discussion/curl-error-60-ssl-certificate-problem-unable-to-get-local-issuer-certificate )

Łajno
źródło
6
Ta wiadomość nadchodzi z powodu twojej wersji PHP. Jeśli jest wyższy od PHP 5.5, pojawia się ten błąd z powodu nowej funkcji PHP 5.6. PHP 5.6 sprawdza certyfikaty, jeśli używasz cURL.
UWU_SANDUN
9
Dziękuję za odpowiedź! Chociaż polecam użycie cacert.pem z oficjalnej strony curl: curl.haxx.se/docs/caextract.html
dieBeiden
6
Chciałem tylko zwrócić uwagę na każdego, kto nie może tego zrobić - użyłem ukośników do przodu curl.cainfo = "C:/cacert.pem"i musiałem zrestartować komputer, aby go uruchomić. Ponowne uruchomienie serwera WWW nie wystarczyło. Mam nadzieję, że to pomaga:]
space_food_
1
i nie zapomnij odkomentować curl.cainfo(facepalm)
Edmund Sulzanok
Działa jak urok! Dzięki
Jack
55

Uwaga użytkownicy Wamp / Wordpress / Windows. Miałem ten problem przez wiele godzin i nawet poprawna odpowiedź nie robiła tego dla mnie, ponieważ edytowałem niewłaściwy plik php.ini, ponieważ pytanie zostało udzielone XAMPP, a nie użytkownikom WAMP, chociaż pytanie dotyczyło WAMP.

oto co zrobiłem

Pobierz pakiet certyfikatów.

Włóż to do środka C:\wamp64\bin\php\your php version\extras\ssl

Upewnij się, że plik mod_ssl.sojest w środkuC:\wamp64\bin\apache\apache(version)\modules

Włącz mod_sslw httpd.confkatalogu ApacheC:\wamp64\bin\apache\apache2.4.27\conf

Włącz php_openssl.dllw php.ini. Pamiętaj, że moim problemem było to, że miałem dwa pliki php.ini i muszę to zrobić w obu z nich. Pierwszy z nich można znaleźć wewnątrz ikony paska zadań WAMP tutaj.

wprowadź opis zdjęcia tutaj

a drugi znajduje się w C:\wamp64\bin\php\php(Version)

znajdź lokalizację obu php.iniplików i znajdź linię curl.cainfo =i podaj jej ścieżkę w ten sposób

curl.cainfo = "C:\wamp64\bin\php\php(Version)\extras\ssl\cacert.pem"

Teraz zapisz pliki i uruchom ponownie serwer, a powinieneś być gotowy

Rami Nour
źródło
Mniej musisz robić zarówno php.ini, jak i ten, którego zamierzasz używać: jeśli używasz apache jako klienta SAPI, to zmień ten w katalogu apache i / lub zmień ten w kliencie katalog, jeśli planujesz używać php.exe jako SAPI.
Fabien Haddadi
3
„Muszę to zrobić w obu przypadkach” to kluczowa uwaga. Dziękuję
Jaroslav Klimčík,
1
Działa to dla Laravel 5.5 z „guzzlehttp / guzzle”: „^ 6.3”. Serwer Wamp 3.1.3. Php 7.1 *
Deepesh Thapa
to działało. Dzięki
4906240,
Dzięki za odpowiedź na wamp
alttoidy
46

Jeśli używasz PHP 5.6 z Guzzle, Guzzle przeszedł na używanie bibliotek PHP do automatycznego wykrywania certyfikatów, a nie do procesu ( ref ). PHP opisuje zmiany tutaj .

Dowiedz się, gdzie PHP / Guzzle szuka certyfikatów

Możesz zrzucić, gdzie szuka PHP, używając:

 var_dump(openssl_get_cert_locations());

Uzyskiwanie pakietu certyfikatu

Do testowania OS X możesz użyć homebrew, aby zainstalować openssl, brew install openssla następnie użyć go openssl.cafile=/usr/local/etc/openssl/cert.pemw ustawieniach php.ini lub Zend Server (pod OpenSSL).

Pakiet certyfikatów jest również dostępny w curl / Mozilla na stronie curl: https://curl.haxx.se/docs/caextract.html

Informowanie PHP, gdzie znajdują się certyfikaty

Kiedy już masz pakiet, umieść go w miejscu, w którym PHP już szuka (czego dowiedziałeś się powyżej) lub zaktualizuj openssl.cafilew php.ini. (Ogólnie, /etc/php.inilub /etc/php/7.0/cli/php.iniczy /etc/php/php.inina Unix).

Loren
źródło
3
TAK. Po zobaczeniu zbyt wielu osób sugerujących ewidentnie niewłaściwe podejście obniżenia o wiele numerów wersji, jest to prawidłowe podejście imho. Postępowałem zgodnie z radami innych osób odnośnie kawiarni, ale nie miałem możliwości sprawdzenia, dlaczego wciąż się nie ładuje. Ta funkcja openssl_get_cert_locations () naprawdę wykonała zadanie w identyfikacji mojego problemu. Dzięki!
Web and Flow
1
Dziękujemy za udostępnienie openssl_get_cert_locations, znacznie ułatwiło debugowanie. Wygląda na to, że WAMP używa innego pliku ini dla apache php niż dla php konsoli. W moim przypadku musiałem dodać openssl.cafile="c:/_/cacert.pem"php na konsolę. Ostatnim razem, kiedy korzystałem z niego przez apache, musiałem curl.cainfo="c:/_/cacert.pem"go uruchomić .
psycho brm
16

Guzzle, który jest używany przez cartalyst / stripe , wykona następujące czynności, aby znaleźć odpowiednie archiwum certyfikatów, aby sprawdzić certyfikat serwera względem:

  1. Sprawdź, czy openssl.cafilejest ustawiony w pliku php.ini.
  2. Sprawdź, czy curl.cainfojest ustawiony w pliku php.ini.
  3. Sprawdź, czy /etc/pki/tls/certs/ca-bundle.crtistnieje (Red Hat, CentOS, Fedora; dostarczone przez pakiet ca-certyfikatów)
  4. Sprawdź, czy /etc/ssl/certs/ca-certificates.crtistnieje (Ubuntu, Debian; dostarczone przez pakiet ca-certyfikatów)
  5. Sprawdź, czy /usr/local/share/certs/ca-root-nss.crtistnieje (FreeBSD; dostarczone przez pakiet ca_root_nss)
  6. Sprawdź, czy /usr/local/etc/openssl/cert.pem(OS X; dostarczone przez homebrew)
  7. Sprawdź, czy C:\windows\system32\curl-ca-bundle.crtistnieje (Windows)
  8. Sprawdź, czy C:\windows\curl-ca-bundle.crtistnieje (Windows)

Aby upewnić się, że wartości dla pierwszych dwóch ustawień są poprawnie zdefiniowane, wykonaj prosty test:

echo "openssl.cafile: ", ini_get('openssl.cafile'), "\n";
echo "curl.cainfo: ", ini_get('curl.cainfo'), "\n";

Alternatywnie spróbuj zapisać plik w lokalizacjach wskazanych przez # 7 lub # 8.

Jacek
źródło
13

Jeśli nie możesz zmienić php.ini, możesz również wskazać plik cacert.pem z kodu w następujący sposób:

$http = new GuzzleHttp\Client(['verify' => '/path/to/cacert.pem']);
$client = new Google_Client();
$client->setHttpClient($http);
mvandillen
źródło
8

Zrobiłem to var_dump(openssl_get_cert_locations()); die;w dowolnym skrypcie php, który dostarczył mi informacji o domyślnych ustawieniach, których używał mój lokalny php:

array (size=8)
  'default_cert_file' => string 'c:/openssl-1.0.1c/ssl/cert.pem' (length=30)
  'default_cert_file_env' => string 'SSL_CERT_FILE' (length=13)
  'default_cert_dir' => string 'c:/openssl-1.0.1c/ssl/certs' (length=27)
  'default_cert_dir_env' => string 'SSL_CERT_DIR' (length=12)
  'default_private_dir' => string 'c:/openssl-1.0.1c/ssl/private' (length=29)
  'default_default_cert_area' => string 'c:/openssl-1.0.1c/ssl' (length=21)
  'ini_cafile' => string 'E:\xampp\php\extras\ssl\cacert.pem' (length=34)
  'ini_capath' => string '' (length=0)

Jak można zauważyć, ustawiłem opcję ini_cafile lub opcję ini curl.cainfo. Ale w moim przypadku curl próbowałby użyć „default_cert_file”, który nie istniał.

Skopiowałem plik z https://curl.haxx.se/ca/cacert.pem do lokalizacji dla pliku „default_cert_file” (c: /openssl-1.0.1c/ssl/cert.pem) i udało mi się go zdobyć pracować.

To było dla mnie jedyne rozwiązanie.

George Donev
źródło
Mam podobny problem, a moja lokalizacja to coś w rodzaju c: /usr/local/ssl/cert.pem, ale ta lokalizacja nie istnieje, czy co to może być, dalej ten sam projekt jest używany przez mój kolega na komputerze Mac z tego powodu próbowałem już wszystkiego innego, czyli dodawania lokalizacji certyfikatu do pliku .ini, ale to nie działa, wygląda na to, że Twoje rozwiązanie powinno działać, ponieważ ma sens, ale nie może zmienić tej lokalizacji i nie może umieścić certyfikatu w miejscu, które nie istnieje.
AbdulMueed
Możesz spróbować utworzyć foldery i umieścić certyfikat na określonej ścieżce?
George Donev
7

Kiedyś ten problem pojawił się nieoczekiwany, gdy skrypt Guzzle (5) próbował połączyć się z hostem przez SSL. Jasne, mógłbym wyłączyć opcję WERYFIKUJ w Guzzle / Curl, ale najwyraźniej nie jest to właściwa droga.

Próbowałem wszystkiego wymienionego tutaj i w podobnych wątkach, a potem ostatecznie poszedłem do terminalu z openssl, aby przetestować domenę, z którą próbowałem się połączyć:

openssl s_client -connect example.com:443 

... i otrzymałem kilka pierwszych wierszy wskazujących:

CONNECTED(00000003)
depth=0 CN = example.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = example.com
verify error:num=21:unable to verify the first certificate
verify return:1 

... podczas gdy wszystko działało dobrze podczas wypróbowywania innych miejsc docelowych (np. google.com itp.)

To skłoniło mnie do skontaktowania się z domeną, z którą próbowałem się połączyć, i rzeczywiście mieli problem z ICH KONIEC, który się podkradł. Zostało to rozwiązane i mój skrypt wrócił do działania.

Więc ... jeśli wyciągasz włosy, daj opensl szansę i sprawdź, czy coś jest nie tak z odpowiedzią z miejsca, z którym próbujesz się połączyć. Może czasami problem nie jest tak „lokalny”.

Naród marzeń
źródło
6

Znalazłem rozwiązanie, które działało dla mnie. Zmieniłem wersję z najnowszego żonglera na wersję ~ 4.0 i działało.

W pliku composer.json dodaj „guzzlehttp / guzzle”: „~ 4.0”

Mam nadzieję, że to komuś pomoże

Iruku Kagika
źródło
Uniemożliwi to również korzystanie z funkcji wersji 5/6. Zamiast tego po prostu ustaw Verify na false w tablicy parametrów (3. parametr metody żądania): $ client-> request ('GET', '/', ['Verify' => false]);
S ..
3

Pamiętaj, aby otworzyć php.iniplik bezpośrednio w Eksploratorze Windows. (w moim przypadku C:\DevPrograms\wamp64\bin\php\php5.6.25:).

Nie używaj skrótu do php.iniw menu ikony Wamp / Xamp na pasku zadań. Ten skrót nie działa w tym przypadku.

Następnie edytuj to php.ini:

curl.cainfo ="C:/DevPrograms/wamp64/bin/php/cacert.pem" 

i

openssl.cafile="C:/DevPrograms/wamp64/bin/php/cacert.pem"

Po zapisaniu php.ininie trzeba „ponownie uruchamiać wszystkich usług” w ikonie Wamp ani zamykać / ponownie otwierać CMD.

Quang Nguyen Tri
źródło
2

Czy próbowałeś..

curl_setopt($process, CURLOPT_SSL_VERIFYPEER, false);

Jeśli korzystasz z zaufanego źródła, prawdopodobnie nie musisz weryfikować certyfikatu SSL.

Mike Miller
źródło
2

Spędziłem zbyt dużo czasu, aby rozwiązać ten problem.

Miałem PHP w wersji 5.5 i musiałem zaktualizować do wersji 5.6.

W wersjach <5.6 Guzzle użyje własnego pliku cacert.pem, ale w wyższych wersjach PHP użyje systemowego pliku cacert.pem.

Pobrałem również plik stąd https://curl.haxx.se/docs/caextract.html i ustawiłem go w php.ini.

Odpowiedź znaleziona w pliku Guzzles StreamHandler.php https://github.com/guzzle/guzzle/blob/0773d442aa96baf19d7195f14ba6e9c2da11f8ed/src/Handler/StreamHandler.php#L437

        // PHP 5.6 or greater will find the system cert by default. When
        // < 5.6, use the Guzzle bundled cacert.
Marko Milivojevic
źródło
2

Wszystkie odpowiedzi są poprawne; ale najważniejsze jest to, że musisz znaleźć odpowiedni plik php.ini. zaznacz to polecenie w cmd „php --ini” nie jest właściwą odpowiedzią na znalezienie właściwego pliku php.ini.

jeśli edytujesz

curl.cainfo ="PATH/cacert.pem"

i zaznacz

var_dump(openssl_get_cert_locations()); 

następnie curl.cainfo powinien mieć wartość. jeśli nie, to nie jest właściwy plik php.ini;

* Polecam przeszukać * .ini w wamp / bin lub xxamp / bin lub dowolnym serwerze, z którego korzystasz i zmieniać je jeden po drugim i sprawdzać. *

Mohsen Molaei
źródło
1

Właśnie spotkałem ten sam problem z frameworkiem Laravel 4 php, który korzysta z guzzlehttp/guzzlepakietu kompozytora. Z jakiegoś powodu certyfikat SSL dla pistoletu pocztowego nagle przestał się sprawdzać i otrzymałem ten sam komunikat „błąd 60”.

Jeśli, podobnie jak ja, korzystasz z hostingu współdzielonego bez dostępu php.ini, inne rozwiązania nie są możliwe. W każdym razie Guzzle ma tego klienta inicjującego kod, który najprawdopodobniej zniweczy php.iniefekty:

// vendor/guzzlehttp/guzzle/src/Client.php
    $settings = [
        'allow_redirects' => true,
        'exceptions'      => true,
        'decode_content'  => true,
        'verify'          => __DIR__ . '/cacert.pem'
    ];

Tutaj Guzzle wymusza użycie własnego wewnętrznego pliku cacert.pem, który prawdopodobnie jest już nieaktualny, zamiast korzystania z pliku dostarczanego przez środowisko cURL . Zmiana tej linii (przynajmniej w Linuksie) konfiguruje Guzzle do korzystania z domyślnej logiki weryfikacji SSL cURL i naprawiła mój problem:

        'verify'          => true

Możesz to również ustawić, falsejeśli nie dbasz o bezpieczeństwo połączenia SSL, ale to nie jest dobre rozwiązanie.

Ponieważ pliki w vendornich nie są przeznaczone do manipulowania, lepszym rozwiązaniem byłoby skonfigurowanie klienta Guzzle przy użyciu, ale było to zbyt trudne w Laravel 4.

Mam nadzieję, że zaoszczędzi to komuś innemu kilka godzin debugowania ...

bernie
źródło
1

Może to być przypadek skrajny, ale w moim przypadku problemem nie była konfiguracja klienta (już curl.cainfoskonfigurowałem php.ini), ale raczej niepoprawna konfiguracja zdalnego serwera:

Nie wysłał żadnych pośrednich certyfikatów w łańcuchu. Podczas przeglądania strony za pomocą Chrome nie wystąpił błąd, ale w przypadku PHP wystąpił błąd.

błąd cURL 60

Po uwzględnieniu certyfikatów pośrednich do konfiguracji zdalnego serwera WWW działało.

Możesz użyć tej strony, aby sprawdzić konfigurację SSL swojego serwera:

https://whatsmychaincert.com/

Tobias K.
źródło
1

kiedy uruchamiam 'var_dump(php_ini_loaded_file());' , otrzymuję ten wynik na mojej stronie 'C:\Development\bin\apache\apache2.4.33\bin\php.ini' (length=50)'

i aby php załadował mój plik certyfikatu, musiałem edytować plik php.ini w tej ścieżce 'C:\Development\bin\apache\apache2.4.33\bin\php.ini' i dodać, openssl.cafile="C:/Development/bin/php/php7.2.4/extras/ssl/cacert.pem"gdzie pobrałem, i umieścić mój plik cert z https://curl.haxx.se/docs/caextract.html

Jestem na Windowsie 10, używając Drupala 8, Wampa i php7.2.4

Mikołaj
źródło
0

Mam właściwe rozwiązanie tego problemu, spróbujmy zrozumieć podstawową przyczynę tego problemu. Ten problem występuje, gdy nie można zweryfikować zdalnych serwerów ssl przy użyciu certyfikatów głównych w magazynie certyfikatów systemu lub zdalny ssl nie jest zainstalowany razem z certyfikatami łańcuchowymi. Jeśli masz system Linux z dostępem root ssh, w takim przypadku możesz spróbować zaktualizować bazę certyfikatów za pomocą poniższego polecenia:

update-ca-certificates

Jeśli nadal nie działa, musisz dodać główny i tymczasowy certyfikat zdalnego serwera w swoim magazynie certyfikatów. Możesz pobrać certyfikaty root i pośrednie i dodać je do katalogu / usr / local / share / ca-certyfikaty, a następnie uruchomić polecenie update-ca-certificates. To powinno załatwić sprawę. Podobnie w przypadku systemu Windows można wyszukać sposób dodawania certyfikatu root i pośredniego.

Innym sposobem rozwiązania tego problemu jest poproszenie zdalnego zespołu serwerów o dodanie certyfikatu ssl jako pakietu certyfikatu głównego domeny, certyfikatu pośredniego i certyfikatu głównego.

prasoon
źródło
-1

Gdy używasz systemu Windows, myślę, że twój separator ścieżek to „\” (i „/” w systemie Linux). Spróbuj użyć stałej DIRECTORY_SEPARATOR. Twój kod będzie bardziej przenośny.

Próbować:

curl_setopt($process, CURLOPT_CAINFO, dirname(__FILE__) . DIRECTORY_SEPARATOR . 'cacert.pem');

EDYCJA: i wpisz pełną ścieżkę. Miałem pewne problemy ze ścieżkami względnymi (być może curl jest wykonywany z innego katalogu podstawowego?)

C Würtz
źródło
1
Nie zrobiłoby to różnicy, ponieważ rzeczywiste ustawienia cURL są poza twoją kontrolą, gdy używasz tej konkretnej biblioteki Stripe.
Ja͢ck
-1

jeśli używasz WAMP, powinieneś również dodać linię certyfikatu do php.ini dla Apache (oprócz domyślnego pliku php.ini):

[curl]
curl.cainfo = C:\your_location\cacert.pem

działa dla php5.3 +

pion
źródło
Tak! Ostrożnie edytuj pliki php.ini zarówno w wersji apache, jak i php. Dla użytkowników WAMP ta odpowiedź była jedynym rozwiązaniem mojego problemu: stackoverflow.com/questions/28858351/…
MavBzh