HTTPS dan SSL3_GET_SERVER_CERTIFICATE: verifikasi sertifikat gagal, CA tidak masalah

208

Saya menggunakan XAMPP untuk pengembangan. Baru-baru ini saya memutakhirkan instalasi xampp dari versi lama ke 1.7.3.

Sekarang ketika saya mengeriting situs yang diaktifkan HTTPS saya mendapatkan pengecualian berikut

Kesalahan fatal: Pengecualian tanpa permintaan 'RequestCore_Exception' dengan pesan 'cURL resource: Resource id # 55; kesalahan CURL: masalah sertifikat SSL, verifikasi bahwa sertifikat CA OK. Detail: kesalahan: 14090086: Rutinitas SSL: SSL3_GET_SERVER_CERTIFICATE: verifikasi sertifikat gagal (60) '

Semua orang menyarankan menggunakan beberapa opsi ikal tertentu dari kode PHP untuk memperbaiki masalah ini. Saya pikir ini seharusnya tidak menjadi jalannya. Karena saya tidak punya masalah dengan versi lama XAMPP saya dan terjadi hanya setelah menginstal versi baru.

Saya perlu bantuan untuk mencari tahu perubahan pengaturan apa dalam instalasi PHP saya, Apache dll dapat memperbaiki masalah ini.

Josnidhin
sumber

Jawaban:

145

curl digunakan untuk memasukkan daftar CA yang diterima, tetapi tidak lagi bundel sertifikat CA APAPUN. Jadi secara default itu akan menolak semua sertifikat SSL sebagai tidak dapat diverifikasi.

Anda harus mendapatkan sertifikat CA dan curl point di sana. Lebih detail di Detail cURLS tentang Sertifikat SSL Server .

Marc B
sumber
4
Keriting terjadi di perpustakaan php layanan web Amazon. Saya tidak mengerti bagaimana cara memperbaikinya tanpa mengedit kode perpustakaan.
Josnidhin
41
Kemudian matikan verifikasi sertifikat ( CURLOPT_SSL_VERIFYPEER-> false). Anda dapat menambahkan sertifikat CA dari situs yang Anda coba lakukan SSL, atau Anda menonaktifkan verifikasi CA. Hanya itulah dua opsi yang tersedia.
Marc B
78
Hanya fyi - pengaturan CURLOPT_SSL_VERIFYPEERuntuk falsemengalahkan tujuan menggunakan SSL.
Hingga
13
@Tapi bukankah itu mengalahkan setengah dari tujuan SSL? Anda masih mendapatkan privasi antara Anda dan rekan Anda: Anda tidak memiliki keaslian rekan Anda.
Mark Fox
10
tanpa keaslian, apa gunanya mengenkripsi data yang Anda kirim? Jika Anda telah MITMed, maka data tersebut tetap dikompromikan
hdgarrood
290

Ini masalah yang cukup umum di Windows. Anda perlu hanya untuk set cacert.pemke curl.cainfo.

Karena PHP 5.3.7 dapat Anda lakukan:

  1. unduh https://curl.haxx.se/ca/cacert.pem dan simpan di suatu tempat.
  2. perbarui php.ini- tambahkan curl.cainfo = "PATH_TO / cacert.pem"

Jika tidak, Anda harus melakukan yang berikut untuk setiap sumber daya CURL:

curl_setopt ($ch, CURLOPT_CAINFO, "PATH_TO/cacert.pem");
Артур Курицын
sumber
2
Ini bekerja untuk saya di XAMPP pada OS X. Ini memperbaiki masalah di mana plugin Wordpress tidak akan diperbarui karena tidak dapat menemukan sertifikat lokal.
Jonathan Nicol
8
Untuk orang lain yang mencoba menyelesaikan masalah ini di Windows menggunakan Apache, saya harus menetapkan path lengkap (yaitu C: \ PATH_TO \ cacert.pem) dalam kode PHP saya. Pada IIS, jalur relatif tampaknya berfungsi ok.
http203
Jika cacert.pem berada di direktori yang sama maka curl_setopt ($ ch, CURLOPT_CAINFO, dirname ( FILE ). '/Cacert.pem'); akan bekerja
mujaffar
7
Saat menggunakan WampServer dengan 2., Anda harus menambahkan variabel ke dua php.inifile terpisah . Lihat stackoverflow.com/a/25706713/1101095
Nate
Yang membingungkan / ironis adalah Anda dapat mengunduh curl.haxx.se/ca/cacert.pem melalui HTTPS tanpa menentukan opsi tambahan. Apakah sertifikat untuk curl.haxx.se didukung ke curl sendiri?
qbolec
84

Peringatan: ini dapat menimbulkan masalah keamanan yang dirancang untuk dilindungi oleh SSL, menjadikan seluruh basis kode Anda tidak aman. Itu bertentangan dengan setiap praktik yang disarankan.

Tetapi perbaikan yang sangat sederhana yang berhasil bagi saya adalah menelepon:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

sebelum menelepon:

curl_exec():

dalam file php.

Saya percaya ini menonaktifkan semua verifikasi sertifikat SSL.

Chris Dutrow
sumber
65
... dan dengan menonaktifkan verifikasi sertifikat, Anda membiarkan pintu terbuka terhadap kemungkinan serangan MITM, yang sebaliknya dilindungi oleh SSL / TLS. JANGAN LAKUKAN INI!
Bruno
12
Ya. Aku seharusnya lebih memperhatikan hal ini dalam jawabannya. Hanya lakukan ini jika Anda tidak mengerjakan sesuatu yang penting. Saya menggunakannya di localhost untuk mengakses situs web yang saya program secara pribadi.
Chris Dutrow
3
Downvote dari saya. Ini adalah perbaikan kotor untuk membuat kode Anda berfungsi, tetapi bukan solusi. Jawaban yang diberikan oleh Артур Курицын jauh lebih baik.
Ilija
2
@Bruno Ini adalah solusi sempurna, untuk skrip pembantu, tes, aplikasi tepercaya, intranet, ..... Semua orang yang tahu sedikit tentang SSL, tahu dalam hal apa validasi sertifikat dapat dilewati. Jadi semua komentar 'pintar' tentang jawaban ini dan hal-hal seperti 'JANGAN LAKUKAN INI' hanyalah NONSENSE !!
Kenyakorn Ketsombut
5
... " Semua orang yang tahu sedikit tentang SSL [...] " ... dan Anda akan terkejut betapa banyak orang yang tidak peduli mengetahui sedikit tentang dasar-dasar SSL / TLS, dan baru saja datang di sini untuk menyalin / menempel perbaikan cepat untuk pesan kesalahan mereka.
Bruno
53

Sumber: http://ademar.name/blog/2006/04/curl-ssl-certificate-problem-v.html

Curl: Masalah sertifikat SSL, verifikasi bahwa sertifikat CA adalah OK

07 April 2006

Saat membuka url aman dengan Curl Anda mungkin mendapatkan kesalahan berikut:

Masalah sertifikat SSL, verifikasi bahwa sertifikat CA OK

Saya akan menjelaskan mengapa kesalahan dan apa yang harus Anda lakukan.

Cara termudah untuk menghilangkan kesalahan adalah menambahkan dua baris berikut ke skrip Anda. Solusi ini menimbulkan risiko keamanan.

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

Coba lihat apa yang dilakukan kedua parameter ini. Mengutip manual.

CURLOPT_SSL_VERIFYHOST : 1 untuk memeriksa keberadaan nama umum dalam sertifikat rekan SSL. 2 untuk memeriksa keberadaan nama umum dan juga memverifikasi bahwa itu cocok dengan nama host yang disediakan.

CURLOPT_SSL_VERIFYPEER : FALSE untuk menghentikan CURL dari memverifikasi sertifikat rekan. Sertifikat alternatif untuk diverifikasi dapat ditentukan dengan opsi CURLOPT_CAINFO atau direktori sertifikat dapat ditentukan dengan opsi CURLOPT_CAPATH. CURLOPT_SSL_VERIFYHOST mungkin juga harus TRUE atau FALSE jika CURLOPT_SSL_VERIFYPEER dinonaktifkan (standarnya adalah 2). Mengatur CURLOPT_SSL_VERIFYHOST ke 2 (Ini adalah nilai default) akan menjamin bahwa sertifikat yang disajikan kepada Anda memiliki 'nama umum' yang cocok dengan URN yang Anda gunakan untuk mengakses sumber daya jarak jauh. Ini adalah pemeriksaan yang sehat tetapi tidak menjamin program Anda tidak ditipu.

Masukkan 'pria di tengah'

Program Anda dapat disesatkan untuk berbicara dengan server lain sebagai gantinya. Ini dapat dicapai melalui beberapa mekanisme, seperti dns atau keracunan arp (Ini adalah cerita untuk hari lain). Penyusup juga dapat menandatangani sendiri sertifikat dengan 'nama bersama' yang sama dengan yang diharapkan oleh program Anda. Komunikasi masih akan dienkripsi tetapi Anda akan memberikan rahasia Anda kepada penipu. Serangan semacam ini disebut 'man in the middle'

Mengalahkan 'pria di tengah'

Ya, kita perlu memverifikasi bahwa sertifikat yang diberikan kepada kita itu benar-benar baik. Kami melakukan ini dengan membandingkannya dengan sertifikat yang kami percayai * masuk akal.

Jika sumber daya jarak jauh dilindungi oleh sertifikat yang dikeluarkan oleh salah satu CA utama seperti Verisign, GeoTrust et al, Anda dapat dengan aman membandingkan dengan bundel sertifikat CA Mozilla yang bisa Anda dapatkan dari http://curl.haxx.se/docs/caextract .html

Simpan file cacert.pemdi suatu tempat di server Anda dan atur opsi berikut dalam skrip Anda.

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

untuk Semua Info Kredit di atas Pergi ke: http://ademar.name/blog/2006/04/curl-ssl-certificate-problem-v.html

Deepak Oberoi
sumber
38
Pada umumnya dianggap sopan untuk memberi kredit pada sumber informasi Anda dan hanya mengutip bagian-bagian tertentu yang relevan dengan pertanyaan, daripada hanya menyalin dan menempelkannya di sini!
Dan Herd
1
Maaf, saya telah pergi, ya saya memberi Dan untuk itu dan Diperbarui The Post
Deepak Oberoi
6
Setidaknya Deepak berusaha untuk meneliti itu. @danherd Jadi danherd, Anda baru saja membuat penelitian untuk menemukan bahwa dia mengambil kode dari suatu tempat? Apa hak atribusi dari kode ini? Alih-alih membuang waktu Anda untuk menemukan kesalahan orang lain, cobalah untuk membantu seseorang sendiri. Jangan berkelahi, berbagi!
GTodorov
17

Solusi di atas sangat bagus, tetapi jika Anda menggunakan WampServer Anda mungkin menemukan pengaturan curl.cainfovariabel dalam php.initidak berfungsi.

Saya akhirnya menemukan WampServer memiliki dua php.inifile:

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

Yang pertama tampaknya digunakan untuk ketika file PHP dipanggil melalui browser web, sedangkan yang kedua digunakan ketika perintah dipanggil melalui baris perintah atau shell_exec().

TL; DR

Jika menggunakan WampServer, Anda harus menambahkan curl.cainfobaris ke kedua php.ini file.

Nate
sumber
6

Untuk cinta semua yang suci ...

Dalam kasus saya, saya harus mengatur openssl.cafilevariabel konfigurasi PHP ke jalur file PEM.

Saya percaya sangat benar bahwa ada banyak sistem di mana pengaturan curl.cainfodalam konfigurasi PHP adalah persis apa yang dibutuhkan, tetapi di lingkungan saya bekerja dengan, yang merupakan eboraas / laravel wadah docker , yang menggunakan Debian 8 (jessie) dan PHP 5,6, pengaturan variabel itu tidak melakukan trik.

Saya perhatikan bahwa output dari php -itidak menyebutkan apa pun tentang pengaturan konfigurasi tertentu, tetapi memang memiliki beberapa baris tentang openssl. Ada keduanyaopenssl.capath dan openssl.cafileopsi, tetapi hanya mengatur yang kedua ikal diizinkan melalui PHP untuk akhirnya baik-baik saja dengan URL HTTPS.

Spencer Williams
sumber
Terima kasih! Mengatur curl.cainfo juga tidak berhasil, tetapi pengaturan openssl.cafile berhasil! Saya menggunakan Windows 7 dengan XAMPP dan PHP 7.1.1.
knezmilos
@knezmilos bagaimana Anda mengatur pengaturan openssl.cafile? di mana Anda mengunduh, dan bagaimana Anda mengaktifkannya?
Krys
Yah, sudah lama tapi saya pikir ini sesuatu seperti ini: curl.cainfo = "C: \ xampp \ cacert \ cacert.pem" dan openssl.cafile = "C: \ xampp \ cacert \ cacert.pem" di php. Suami, sementara saya pikir saya mendapat file pem dari salah satu jawaban di sini.
knezmilos
1
"Untuk cinta semua yang suci ..." memang. Ini berfungsi untuk pengaturan Ubuntu 18.08 / Apache / Php7.2 saya. Jika kesalahan curl mengarah ke file yang tepat, maka itu pastinya adalah kesalahan openssls
JTG
4

Terkadang jika aplikasi yang Anda coba hubungi memiliki sertifikat yang ditandatangani sendiri, cacert.pem normal dari http://curl.haxx.se/ca/cacert.pem tidak menyelesaikan masalah.

Jika Anda yakin dengan url titik akhir layanan, tekan melalui browser, simpan sertifikat secara manual dalam format "X 509 sertifikat dengan rantai (PEM)". Arahkan file sertifikat ini dengan

curl_setopt ($ch, CURLOPT_CAINFO, "pathto/{downloaded certificate chain file}");   
madRai
sumber
4

Saya memiliki kesalahan yang sama pada linux AMI amazon.

Saya Dipecahkan dengan pengaturan curl.cainfo di /etc/php.d/curl.ini

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

Penambahan Oktober 2018

Di Amazon Linux v1 edit file ini

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

Untuk menambahkan baris ini

curl.cainfo="/etc/ssl/certs/ca-bundle.crt"
Reinaldo Mendes
sumber
Sempurna terima kasih! Saya memperbarui pertanyaan untuk menambahkan apa yang saya lakukan yang memecahkan masalah bagi saya, daripada membuat jawaban lain.
Tim
3

Saat mengatur opsi ikal untuk CURLOPT_CAINFO harap ingat untuk menggunakan tanda kutip tunggal, menggunakan tanda kutip ganda hanya akan menyebabkan kesalahan lain. Jadi pilihan Anda akan terlihat seperti:

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

Selain itu, dalam pengaturan file php.ini Anda harus ditulis sebagai: (perhatikan tanda kutip ganda saya)

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

Saya meletakkannya langsung di bawah garis yang mengatakan ini: extension=php_curl.dll

(Untuk tujuan pengorganisasian saja, Anda bisa meletakkannya di mana saja di dalam Anda php.ini, saya hanya meletakkannya dekat dengan referensi curl lain, jadi ketika saya mencari menggunakan curl kata kunci, saya dapat menemukan kedua referensi curl di satu area.)

LOwens1931
sumber
1
Saya harap php.ini harus menunjuk ke file pem bukan folder induknya
dejjub-AIS
2

Saya berakhir di sini ketika mencoba untuk mendapatkan GuzzleHttp (php + apache di Mac) untuk mendapatkan halaman dari www.googleapis.com.

Inilah solusi terakhir saya jika itu membantu siapa pun.

Lihatlah rantai sertifikat untuk domain apa pun yang memberi Anda kesalahan ini. Bagi saya itu googleapis.com

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

Anda akan mendapatkan sesuatu seperti ini:

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

Catatan: Saya menangkap ini setelah saya memperbaiki masalah ini, untuk output rantai Anda mungkin terlihat berbeda.

Maka Anda perlu melihat sertifikat yang diizinkan dalam php. Jalankan phpinfo () di sebuah halaman.

<?php echo phpinfo();

Kemudian cari file sertifikat yang diambil dari output halaman:

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

Ini adalah file yang harus Anda perbaiki dengan menambahkan sertifikat yang benar ke dalamnya.

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

Anda pada dasarnya perlu menambahkan "tanda tangan" sertifikat yang benar ke akhir file ini.

Anda dapat menemukannya di sini: Anda mungkin perlu mencari / mencari orang lain di rantai jika Anda membutuhkannya.

Mereka terlihat seperti ini:

contoh gambar sertifikat

( Catatan: Ini adalah gambar sehingga orang tidak akan hanya menyalin / menempelkan sertifikat dari stackoverflow )

Setelah sertifikat yang tepat ada di file ini, restart apache dan uji.

TrofiGeek
sumber
0

Anda dapat mencoba menginstal ulang ca-certificatespaket, atau secara eksplisit mengizinkan sertifikat yang dimaksud seperti dijelaskan di sini .

situs
sumber
-5

Solusinya sangat sederhana! Letakkan baris ini sebelumnya curl_exec:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

Bagi saya itu berhasil.

Zsolt Boszormenyi
sumber
7
Jangan sekali- kali menonaktifkan verifikasi rekan kecuali jika Anda tidak peduli apakah data tersebut dikompromikan dalam perjalanan.
rdlowrey
Sepakat. Jika Anda menginginkan aplikasi yang aman, Anda perlu verifikasi rekan.
braden
2
"Jangan, pernah nonaktifkan verifikasi rekan" KECUALI Anda menginginkan fungsi browser default haha. Juga, mengapa hal ini sangat diremehkan? Ini adalah satu-satunya jawaban yang singkat, manis, to the point DAN efektif.
Adam F
@AdamF FYI, browser DO memverifikasi sertifikat rekan secara default, mereka hanya memberi Anda opsi untuk memotong kesalahan secara manual, dengan peringatan.
Bruno