kesalahan CURL 60: Sertifikat SSL: tidak bisa mendapatkan sertifikat penerbit lokal

232

Saya menggunakan WAMP pada lingkungan pengembangan lokal dan saya mencoba menagih kartu kredit tetapi mendapatkan pesan kesalahan:

kesalahan CURL 60: Masalah sertifikat SSL: tidak bisa mendapatkan sertifikat penerbit lokal

Saya banyak mencari di Google dan banyak orang menyarankan agar saya mengunduh file ini: cacert.pem , letakkan di suatu tempat dan rujuk di php.ini saya. Ini adalah bagian dalam php.ini saya:

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

Namun, bahkan setelah me-restart server saya beberapa kali dan mengubah path, saya mendapatkan pesan kesalahan yang sama.

Saya menggunakan WAMP dari Modul Apache dan memiliki ssl_module diaktifkan. Dan dari ekstensi PGP saya mengaktifkan php_curl.

Masih pesan kesalahan yang sama. Mengapa itu terjadi?

Sekarang saya mengikuti perbaikan ini: Cara memperbaiki PHP CURL Error 60 SSL

Yang menyarankan agar saya menambahkan baris ini ke opsi CURL saya:

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

Di mana saya menambahkan opsi ke CURL saya? Tampaknya tidak melalui baris perintah, karena CLI saya tidak menemukan perintah "curl_setopt"

EDIT

Ini adalah kode yang saya jalankan:

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');
}
Cinta dan kebahagiaan
sumber
Dengan asumsi tidak ada masalah dengan kode Anda, itu bisa jadi firewall Anda. Coba nonaktifkan firewall Anda untuk menguji.
Waqar ul islam
Bukankah saya memberi Anda jawaban untuk pertanyaan ini di sini ? :)
Limon Monte
@limonte mungkin, harus beralih proyek dan mungkin memiliki masalah yang sama dengan proyek baru. Akan beralih kembali ke masalah membuang waktu dan mungkin itu adalah perbaikan yang sama. brb
LoveAndHappiness
1
Sudahkah Anda mencoba stripe versi terbaru? Saya melihat pesan komit yang mengubah sesuatu yang berkaitan dengan sertifikat ... github.com/stripe/stripe-php/commit/…
thelastshadow
1
@LoveAndHappiness apakah Anda punya solusi untuk masalah ini? Saya menghadapi kesalahan yang sama dengan stripe. Tolong beri tahu saya jika Anda memiliki solusi.
Dev

Jawaban:

515

Solusi yang berfungsi dengan asumsi Anda menggunakan Windows di XAMPP:

Server XAMPP

  1. Mirip dengan lingkungan lain
    • unduh dan ekstrak untuk cacert.pem di sini (format / data file bersih)

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

  1. Letakkan di sini di direktori berikut.

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

  1. Di php.ini Anda, letakkan baris ini di bagian ini ("c: \ xampp \ php \ php.ini"):
;;;;;;;;;;;;;;;;;;;;
; php.ini Options  ;
;;;;;;;;;;;;;;;;;;;;

curl.cainfo = "C:\xampp\php\extras\ssl\cacert.pem"
  1. Mulai ulang server web / apache Anda

  2. Masalah terpecahkan!

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

Kotoran
sumber
6
Pesan ini datang karena versi PHP Anda. Jika lebih tinggi dari PHP 5.5 maka muncul kesalahan ini karena fitur baru PHP 5.6. PHP 5.6 memeriksa sertifikat jika Anda menggunakan cURL.
UWU_SANDUN
9
Terima kasih atas jawabannya! Meskipun saya akan merekomendasikan menggunakan cacert.pem dari halaman curl resmi: curl.haxx.se/docs/caextract.html
dieBeiden
6
Hanya ingin menunjukkan kepada siapa saja yang tidak bisa menjalankan ini - saya menggunakan garis miring ke depan curl.cainfo = "C:/cacert.pem"dan juga harus me-restart komputer saya agar bisa berfungsi. Memulai ulang server web saja tidak cukup. Semoga itu membantu:]
space_food_
1
dan jangan lupa tanda komentar curl.cainfo(facepalm)
Edmund Sulzanok
Bekerja seperti pesona! Terima kasih
Jack
56

Perhatian pengguna Wamp / Wordpress / windows. Saya memiliki masalah ini selama berjam-jam dan bahkan jawaban yang benar tidak melakukannya untuk saya, karena saya mengedit file php.ini yang salah karena pertanyaannya dijawab untuk XAMPP dan bukan untuk pengguna WAMP, meskipun pertanyaannya adalah untuk WAMP.

inilah yang saya lakukan

Unduh bundel sertifikat.

Masukkan ke dalam C:\wamp64\bin\php\your php version\extras\ssl

Pastikan file mod_ssl.soberada di dalamC:\wamp64\bin\apache\apache(version)\modules

Aktifkan mod_ssldi httpd.confdalam direktori ApacheC:\wamp64\bin\apache\apache2.4.27\conf

Aktifkan php_openssl.dlldi php.ini. Perlu diketahui masalah saya adalah bahwa saya memiliki dua file php.ini dan saya perlu melakukan ini di keduanya. Yang pertama dapat ditemukan di dalam ikon taskbar WAMP Anda di sini.

masukkan deskripsi gambar di sini

dan yang lainnya terletak di C:\wamp64\bin\php\php(Version)

temukan lokasi untuk kedua php.inifile dan temukan baris curl.cainfo =dan berikan path seperti ini

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

Sekarang simpan file dan mulai ulang server Anda dan Anda harus baik-baik saja

Rami Nour
sumber
Ini lebih sedikit daripada Anda harus melakukan kedua php.ini daripada melakukan yang Anda ingin gunakan: jika Anda menggunakan apache sebagai klien SAPI, kemudian ubah yang ada di direktori apache, dan / atau ubah yang ada di klien dir jika Anda berencana untuk menggunakan php.exe sebagai SAPI.
Fabien Haddadi
3
"Saya perlu melakukan ini pada mereka berdua" adalah catatan utama. Terima kasih
Jaroslav Klimčík
1
Ini berfungsi untuk Laravel 5.5 dengan "guzzlehttp / guzzle": "^ 6.3". Wamp server 3.1.3. Php 7.1 *
Deepesh Thapa
ini berhasil. Terima kasih
user4906240
Terima kasih telah menjawab untuk wamp
altoids
46

Jika Anda menggunakan PHP 5.6 dengan Guzzle, Guzzle telah beralih menggunakan autodetect PHP libraries untuk sertifikat daripada prosesnya ( ref ). PHP menguraikan perubahan di sini .

Mencari Tahu Dimana PHP / Guzzle Mencari Sertifikat

Anda dapat membuang di mana PHP mencari menggunakan:

 var_dump(openssl_get_cert_locations());

Mendapatkan Bundel Sertifikat

Untuk pengujian OS X, Anda dapat menggunakan homebrew untuk menginstal openssl brew install openssldan kemudian gunakan openssl.cafile=/usr/local/etc/openssl/cert.pemdi pengaturan php.ini atau Zend Server Anda (di bawah OpenSSL).

Bundel sertifikat juga tersedia dari curl / Mozilla di situs web curl: https://curl.haxx.se/docs/caextract.html

Memberitahu PHP Di Mana Sertifikat

Setelah Anda memiliki bundel, letakkan di tempat yang sudah dilihat PHP (yang Anda temukan di atas) atau perbarui openssl.cafiledi php.ini. (Umumnya, /etc/php.iniatau /etc/php/7.0/cli/php.iniatau /etc/php/php.inidi Unix.)

Loren
sumber
3
IYA. Setelah melihat terlalu banyak orang menyarankan pendekatan downgrade yang jelas salah dengan beberapa nomor versi, ini merupakan pendekatan yang benar. Saya telah mengikuti saran orang lain tentang kafetaria tetapi tidak memiliki alat untuk menguji mengapa masih tidak memuat. Fungsi openssl_get_cert_locations () benar-benar melakukan pekerjaan dalam mengidentifikasi masalah saya. Terima kasih!
Web dan Aliran
1
Terima kasih telah menyediakannya openssl_get_cert_locations, itu membuat proses debug jauh lebih mudah. Sepertinya WAMP menggunakan file ini berbeda untuk php apache daripada untuk konsol php. Dalam kasus saya, saya harus menambahkan openssl.cafile="c:/_/cacert.pem"untuk php berbasis konsol. Terakhir kali, ketika menggunakannya melalui apache, saya harus curl.cainfo="c:/_/cacert.pem"membuatnya berfungsi.
psycho brm
16

Guzzle, yang digunakan oleh cartalyst / stripe , akan melakukan hal berikut untuk menemukan arsip sertifikat yang tepat untuk memeriksa sertifikat server terhadap:

  1. Periksa apakah openssl.cafilesudah diatur dalam file php.ini Anda.
  2. Periksa apakah curl.cainfosudah diatur dalam file php.ini Anda.
  3. Periksa apakah /etc/pki/tls/certs/ca-bundle.crtada (Red Hat, CentOS, Fedora; disediakan oleh paket ca-sertifikat)
  4. Periksa apakah /etc/ssl/certs/ca-certificates.crtada (Ubuntu, Debian; disediakan oleh paket ca-sertifikat)
  5. Periksa apakah /usr/local/share/certs/ca-root-nss.crt ada (FreeBSD; disediakan oleh paket ca_root_nss)
  6. Periksa apakah /usr/local/etc/openssl/cert.pem(OS X; disediakan oleh homebrew)
  7. Periksa apakah C:\windows\system32\curl-ca-bundle.crtada (Windows)
  8. Periksa apakah C:\windows\curl-ca-bundle.crtada (Windows)

Anda akan ingin memastikan bahwa nilai-nilai untuk dua pengaturan pertama didefinisikan dengan benar dengan melakukan tes sederhana:

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

Atau, cobalah menulis file ke lokasi yang ditunjukkan oleh # 7 atau # 8.

Mendongkrak
sumber
13

Jika Anda tidak dapat mengubah php.ini, Anda juga dapat mengarahkan ke file cacert.pem dari kode seperti ini:

$http = new GuzzleHttp\Client(['verify' => '/path/to/cacert.pem']);
$client = new Google_Client();
$client->setHttpClient($http);
mvandillen
sumber
8

Apa yang saya lakukan adalah digunakan var_dump(openssl_get_cert_locations()); die;dalam skrip php apa pun, yang memberi saya informasi tentang default yang digunakan php lokal saya:

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)

Seperti yang Anda perhatikan, saya telah menyetel ini_cafile atau opsi ini curl.cainfo. Tetapi dalam kasus saya, curl akan mencoba menggunakan "default_cert_file" yang tidak ada.

Saya menyalin file dari https://curl.haxx.se/ca/cacert.pem ke lokasi untuk "default_cert_file" (c: /openssl-1.0.1c/ssl/cert.pem) dan saya bisa mendapatkannya bekerja.

Ini adalah satu-satunya solusi bagi saya.

George Donev
sumber
Saya memiliki masalah yang sama dan lokasi saya adalah sesuatu seperti c: /usr/local/ssl/cert.pem tetapi lokasi ini tidak ada, apakah Anda bisa seperti itu, selanjutnya proyek yang sama digunakan oleh coluge saya pada mesin mac bisa itulah alasannya, saya telah mencoba yang lain, yaitu menambahkan lokasi cert dalam file .ini tetapi tidak berfungsi, sepertinya solusi Anda harus berfungsi karena masuk akal tetapi tidak dapat mengubah lokasi itu dan tidak dapat memberikan sertifikat di lokasi yang tidak ada.
AbdulMueed
Anda dapat mencoba membuat folder dan meletakkan sertifikat di jalur yang Anda tentukan?
George Donev
7

Saya mengalami masalah ini muncul tiba-tiba suatu hari, ketika skrip Guzzle (5) berusaha untuk terhubung ke host melalui SSL. Tentu, saya bisa menonaktifkan opsi VERIFY di Guzzle / Curl, tapi itu jelas bukan cara yang tepat untuk pergi.

Saya mencoba semua yang tercantum di sini dan di utas yang serupa, kemudian akhirnya pergi ke terminal dengan openssl untuk menguji domain yang saya coba sambungkan:

openssl s_client -connect example.com:443 

... dan menerima beberapa baris pertama yang menunjukkan:

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 

... sementara semuanya bekerja dengan baik ketika mencoba tujuan lain (yaitu: google.com, dll)

Ini mendorong saya untuk menghubungi domain yang saya coba sambungkan, dan memang, mereka memiliki masalah pada MEREKA AKHIR yang merangkak naik. Itu diselesaikan dan skrip saya kembali berfungsi.

Jadi ... jika Anda mencabut rambut Anda, berikan suntikan pada openssl dan lihat apakah ada sesuatu dengan respons dari lokasi yang Anda coba sambungkan. Mungkin masalahnya tidak terlalu 'lokal'.

Daydream Nation
sumber
6

Saya menemukan solusi yang berhasil untuk saya. Saya menurunkan versi dari guzzle terbaru ke versi ~ 4.0 dan berhasil.

Dalam composer.json tambahkan "guzzlehttp / guzzle": "~ 4.0"

Semoga ini bisa membantu seseorang

Iruku Kagika
sumber
Itu juga akan mencegah Anda menggunakan fitur versi 5/6 apa pun. Alih-alih, cukup setel verifikasi ke false dalam array param (parameter ketiga dari metode permintaan): $ client-> request ('GET', '/', ['memverifikasi' => false]);
S ..
3

Pastikan Anda membuka php.inifile secara langsung oleh Window Explorer Anda. (dalam kasus saya:) C:\DevPrograms\wamp64\bin\php\php5.6.25.

Jangan gunakan pintasan ke php.inidalam menu ikon Wamp / Xamp di Baki Sistem. Pintasan ini tidak berfungsi dalam hal ini.

Kemudian edit itu php.ini:

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

dan

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

Setelah menyimpan php.iniAnda tidak perlu "Restart All Services" di ikon Wamp atau tutup / buka kembali CMD.

Quang Nguyen Tri
sumber
2

Sudahkah Anda mencoba ..

curl_setopt($process, CURLOPT_SSL_VERIFYPEER, false);

Jika Anda menggunakan sumber tepercaya, Anda tidak perlu memverifikasi sertifikat SSL.

Mike Miller
sumber
2

Saya menghabiskan terlalu banyak waktu untuk mencari tahu masalah ini untuk saya.

Saya memiliki PHP versi 5.5 dan saya perlu meningkatkan ke 5.6.

Dalam versi <5.6 Guzzle akan menggunakan file cacert.pem itu sendiri, tetapi dalam versi PHP yang lebih tinggi ia akan menggunakan file cacert.pem sistem.

Saya juga mengunduh file dari sini https://curl.haxx.se/docs/caextract.html dan mengaturnya di php.ini.

Jawaban ditemukan dalam file Guidelines 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
sumber
2

Semua jawaban itu benar; tetapi yang paling penting adalah Anda harus menemukan file php.ini yang tepat. periksa perintah ini dalam cmd "php --ini" bukan jawaban yang tepat untuk menemukan file php.ini yang tepat.

jika Anda mengedit

curl.cainfo ="PATH/cacert.pem"

dan cek

var_dump(openssl_get_cert_locations()); 

maka curl.cainfo harus memiliki nilai. jika tidak maka itu bukan file php.ini yang benar;

* Saya sarankan Anda untuk mencari * .ini di wamp / bin atau xxamp / bin atau server apa pun yang Anda gunakan dan ubah satu per satu dan periksa. *

Mohsen Molaei
sumber
1

Saya baru saja mengalami masalah yang sama dengan kerangka PHP Laravel 4 yang menggunakan guzzlehttp/guzzlepaket komposer. Untuk beberapa alasan, sertifikat SSL untuk mailgun berhenti tiba-tiba divalidasi dan saya mendapat pesan "kesalahan 60" yang sama.

Jika, seperti saya, Anda menggunakan hosting bersama tanpa akses php.ini, solusi lain tidak mungkin. Bagaimanapun, Guzzle memiliki kode inisialisasi klien ini yang kemungkinan besar akan membatalkan php.iniefek:

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

Di sini Guzzle memaksa penggunaan file cacert.pem internalnya sendiri, yang mungkin sekarang sudah ketinggalan zaman, alih-alih menggunakan yang disediakan oleh lingkungan cURL . Mengubah baris ini (setidaknya di Linux) mengkonfigurasi Guzzle untuk menggunakan logika verifikasi SSL default cURL dan memperbaiki masalah saya:

        'verify'          => true

Anda juga dapat mengatur ini falsejika Anda tidak peduli dengan keamanan koneksi SSL Anda, tetapi itu bukan solusi yang baik.

Karena file-file di vendordalamnya tidak dimaksudkan untuk dirusak, solusi yang lebih baik adalah mengkonfigurasi klien Guzzle pada penggunaan, tetapi ini terlalu sulit untuk dilakukan di Laravel 4.

Semoga ini menyelamatkan orang lain beberapa jam dari debugging ...

bernie
sumber
1

Ini mungkin kasus tepi, tetapi dalam kasus saya masalahnya bukan klien conf (saya sudah curl.cainfomengkonfigurasi di php.ini), tetapi server jauh tidak dikonfigurasi dengan benar:

Itu tidak mengirim sertifikat perantara dalam rantai. Tidak ada kesalahan saat menelusuri situs menggunakan Chrome, tetapi dengan PHP saya mendapat kesalahan berikut.

kesalahan CURL 60

Setelah memasukkan Sertifikat Menengah dalam konfigurasi server web jarak jauh itu berhasil.

Anda dapat menggunakan situs ini untuk memeriksa konfigurasi SSL server Anda:

https://whatsmychaincert.com/

Tobias K.
sumber
1

ketika saya menjalankan 'var_dump(php_ini_loaded_file());' saya mendapatkan output ini di halaman saya 'C:\Development\bin\apache\apache2.4.33\bin\php.ini' (length=50)'

dan untuk mendapatkan php untuk memuat file cert saya, saya harus mengedit php.ini di jalur ini 'C:\Development\bin\apache\apache2.4.33\bin\php.ini' dan menambahkan di openssl.cafile="C:/Development/bin/php/php7.2.4/extras/ssl/cacert.pem"mana saya telah mengunduh dan menempatkan file cert saya dari https://curl.haxx.se/docs/caextract.html

Saya di windows 10, menggunakan drupal 8, wamp dan php7.2.4

Nicholas
sumber
0

Saya punya solusi yang tepat untuk masalah ini, mari kita coba dan memahami akar penyebab masalah ini. Masalah ini muncul ketika server jauh ssl tidak dapat diverifikasi menggunakan sertifikat root di toko sertifikat sistem Anda atau ssl jarak jauh tidak diinstal bersama dengan sertifikat berantai. Jika Anda memiliki sistem linux dengan akses ssh root, maka dalam hal ini Anda dapat mencoba memperbarui toko sertifikat Anda dengan perintah di bawah ini:

update-ca-certificates

Jika masih, itu tidak berfungsi maka Anda perlu menambahkan root dan sertifikat interim dari server jauh di toko sertifikat Anda. Anda dapat mengunduh sertifikat root dan perantara dan menambahkannya direktori / usr / local / share / ca-sertifikat dan kemudian jalankan perintahupdate-ca-certificates. Ini harus melakukan trik. Demikian pula untuk windows Anda dapat mencari cara menambahkan root dan sertifikat menengah.

Cara lain Anda dapat mengatasi masalah ini adalah dengan meminta tim server jarak jauh untuk menambahkan sertifikat ssl sebagai kumpulan sertifikat root domain, sertifikat menengah dan sertifikat root.

prasoon
sumber
-1

Saat Anda menggunakan Windows, saya pikir pemisah jalur Anda adalah '\' (dan '/' di Linux). Coba gunakan konstantaDIRECTORY_SEPARATOR . Kode Anda akan lebih portabel.

Mencoba:

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

Sunting: dan tulis path lengkapnya. Saya punya beberapa masalah dengan path relatif (mungkin curl dijalankan dari direktori basis lain?)

C Würtz
sumber
1
Ini tidak akan membuat perbedaan, karena pengaturan CURL yang sebenarnya berada di luar kendali Anda ketika Anda menggunakan pustaka Stripe tertentu.
Ja͢ck
-1

jika Anda menggunakan WAMP, Anda juga harus menambahkan baris sertifikat di php.ini untuk Apache (selain file php.ini default):

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

bekerja untuk php5.3 +

bob
sumber
Iya! Berhati-hatilah untuk mengedit file versi php.ini apache dan php. Untuk pengguna WAMP, jawaban ini adalah satu-satunya untuk menyelesaikan masalah saya: stackoverflow.com/questions/28858351/…
MavBzh