Помилка curl 60, випуск сертифіката SSL: самопідписаний сертифікат у ланцюжку сертифікатів


81

Я намагаюся надіслати запит на завивку з моїми правильними APP_ID, APP_SECRET тощо на

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

Мені потрібно отримати з нього access_token, але отримати FALSE і curl_error()надрукувати наступне повідомлення в іншому випадку:

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

Мій код:

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

Коли я переходжу вручну за посиланням вище, я добре отримую access_token. Чому це не працює з завиванням? Допоможіть, будь ласка.


Можливо, мені потрібно отримати довідку з .crtпродовженням? Але я не знаю, як його отримати
Віктор Бочарський

1
Будь ласка, уникайте прийнятої [непрацюючої] відповіді. Замість цього використовуйте відповідь @ erlangsec. Також див . Найнебезпечніший у світі код: перевірка сертифікатів SSL у програмному забезпеченні, що не стосується браузера .
jww

Відповіді:


180

Відповіді з пропозицією відключити CURLOPT_SSL_VERIFYPEERне слід приймати. Питання в тому, "чому це не працює з curl", і як правильно зазначив Мартін Холс, це небезпечно.

Помилка, ймовірно, викликана відсутністю оновленого пакета кореневих сертифікатів ЦС. Зазвичай це текстовий файл із купою криптографічних підписів, які curl використовує для перевірки сертифіката SSL хоста.

Потрібно переконатися, що у вашій установці PHP є один із цих файлів і що він оновлений (інакше завантажте його тут: http://curl.haxx.se/docs/caextract.html ).

Потім встановіть у php.ini :

curl.cainfo = <absolute_path_to> cacert.pem

Якщо ви встановлюєте його під час виконання, використовуйте:

curl_setopt ($ch, CURLOPT_CAINFO, dirname(__FILE__)."/cacert.pem");

1
Дякую, але я шукав пропозицію щодо роботи із зовнішнім API. Отже, пропозиція щодо пропозиції @SabujHassan - це робота, і, як я зрозумів, API, який я використовував, не забезпечує SSL.
Віктор Бочарський

Відмінне рішення. Щиро дякую :)
Чандра Накка

1
Працює як магія. Це повинна бути відповідь, "прийнята відповідь" - це простий, але поганий спосіб з міркувань безпеки.
KristCont

Дякую, як сказано працює чудово! Це справді має бути правильною відповіддю.
PostMans

2
Варто зазначити, що curl.cainfo не відображається у phpinfo () у PHP 7.1 / 7.2, хоч openssl.cafile це робить. php.net/manual/en/curl.configuration.php
Елайджа Лінн

58

Цей обхідний шлях є небезпечним і не рекомендується :

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

Це не гарна ідея, щоб вимкнути однорангову перевірку SSL. Це може розкрити ваші запити зловмисникам MITM.

Насправді вам просто потрібен сучасний комплект кореневих сертифікатів ЦС. Встановити оновлений так просто, як:

  1. Завантаження актуального cacert.pemфайлу з веб-сайту cURL та

  2. Встановлення шляху до нього у вашому файлі php.ini, наприклад, у Windows:

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

Це воно!

Залишайтеся в безпеці.


5
Ви також можете встановити цю опцію у своєму коді, якщо у вас немає прав редагувати глобальний php.iniфайл: curl_setopt ($curl_ch, CURLOPT_CAINFO, dirname(__FILE__)."/cacert.pem");
zxcmehran

2
Працював над розробницьким середовищем
cmedeiros

2
Добре для тестування на розробнику
Gaurav Rai

Це жахлива порада, і відповідь слід видалити.
miken32

4
@ miken32 так, і тоді я пропоную альтернативне безпечне рішення як заміну небезпечному обхідному шляху. Продовжуйте читати до кінця.
zxcmehran

3

Якщо сертифікати SSL неправильно встановлені у вашій системі, ви можете отримати таку помилку:

Помилка cURL 60: Проблема сертифіката SSL: не вдається отримати сертифікат місцевого видавця.

Вирішити цю проблему можна таким чином:

Завантажте файл із оновленим списком сертифікатів з https://curl.haxx.se/ca/cacert.pem

Перемістіть завантажений cacert.pemфайл у безпечне місце у вашій системі

Оновіть свій php.iniфайл і налаштуйте шлях до нього:


Крім того, можливо, вам доведеться встановити openssl.cafile="C:/dev/ssl/mywebsite.local.crt"­в php.ini
Франсуа Бретон

3

Важливо: ця проблема зводила мене з розуму на пару днів, і я не міг зрозуміти, що відбувається з моїми установками curl & openssl. Нарешті я зрозумів, що це мій проміжний сертифікат (у моєму випадку GoDaddy), який застарів. Я повернувся до адміністраторської панелі godaddy SSL, завантажив новий проміжний сертифікат, і проблема зникла.

Я впевнений, що це питання для деяких із вас.

Очевидно, GoDaddy в якийсь момент змінив свій проміжний сертифікат через проблеми з дефіцитом, оскільки зараз вони відображають таке попередження:

"Будь ласка, використовуйте нові проміжні сертифікати SHA-2, включені до завантаженого пакета."

Сподіваюся, це допоможе деяким із вас, тому що я збився з пантелику, і це виправило проблему на ВСІХ моїх серверах.


Хоча це не зовсім пов'язано з питанням, воно може представляти життєздатну інформацію загалом.
peter.hrasko.sk

Повідомлення про помилки, які видає curl, іноді можуть бути загадковими та оманливими, і я впевнений, що деякі люди, які отримували помилку "самопідписаного сертифіката", отримували її через химерність, яку я цитував. Я також хотів додати, що під час створення curl я використовував рядок налаштування: ./configure --with-ca-bundle = / etc / ssl / certs / ca-bundle.crt, а також я використовував скрипт perl lib / mk -ca-bundle.pl для створення приємного свіжого файлу ca-bundle.crt. Я використовував веб-сервер apache, але я не замінив свій існуючий проміжний сертифікат оновленим сертифікатом godaddy.
Lee

-3

Помилка: проблема із сертифікатом SSL: самопідписаний сертифікат у ланцюжку сертифікатів

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);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.