Paypal Access - сертификат SSL: не удалось получить сертификат локального эмитента

Я работаю с cUrl и PHP, чтобы сделать запрос на сервер (для доступа к PayPal)

Веб-сайт разработчика Paypal никогда не упоминает, что для использования API доступа PayPal требуется сертификат SSL, однако код, который я использую для запроса токена, следующий:

$options = array(
                CURLOPT_URL => $url,
                CURLOPT_POST => 1,
                CURLOPT_VERBOSE => 1,
                CURLOPT_POSTFIELDS => $postvals,
                CURLOPT_RETURNTRANSFER => 1,
                CURLOPT_SSLVERSION => 3
);

curl_setopt_array($ch, $options);

$response = curl_exec($ch); 
echo curl_error($ch);

Это эхо выводит следующую ошибку:

SSL certificate problem: unable to get local issuer certificate

Мои вопросы:

1) Мне нужен SSL для использования PayPal-доступа, если мне нужно только получить адрес электронной почты пользователя?

2), если мне не нужен SSL, почему эта ошибка возникает?

PS: конечная точка следующая: https://www.sandbox.paypal.com/webapps/auth/protocol/openidconnect/v1/tokenservice

Ответ 1

Решение правильное должно исправить вашу установку PHP.. установка CURLOPT_SSL_VERIFYPEER на false - это быстрый взлом, но это неправильно, поскольку вы отключите проверку сертификата этим центром сертификации. Это подвергает вас нападению "человек в середине".

Легко исправить (php 5.3.7 или выше) - Загрузите файл списка с последними органами сертификации и добавьте этот параметр в php.ini
curl.cainfo=<path-to>cacert.pem

Перезагрузите веб-сервер, и он будет работать!

Ответ 2

Вы можете отключить проверку SSL (которая включена по умолчанию cURL 7.10), добавив следующее:

CURLOPT_SSL_VERIFYPEER, false

в $options, однако, правильный способ - включить проверку.

УВЕДОМЛЕНИЕ О БЕЗОПАСНОСТИ

Если удаленный сайт использует сертификат, выданный известным ЦС, но проверка по-прежнему не удалась, то скорее всего сертификат неправильно настроен на удаленном сервере (отсутствие промежуточных сертификатов и т.д.). Кроме того, ваша система не знала о том, что используемый центр сертификации подписал целевой сертификат. В таком случае yo следует использовать php.ini curl.cainfo (documentation), чтобы указать на действительный файл PEM со всеми поддерживаемыми центрами сертификации - это позволит вашей настройке правильно проверить цепочку эмитентов.

Помните, что при установке CURLOPT_SSL_VERIFYPEER на false вы НЕ решили проблему! Вы работаете над этим. Это все о безопасности, так что это прекрасно, чтобы сделать это какое-то время, но развертывание этого на производстве не мудро, вежливо, так как вы станете открытым для Человек в средней атаке. Вы были предупреждены.

Ответ 3

У меня была такая же точная проблема

Can't connect to PayPal to validate IPN message: SSL certificate: unable to get local issuer certificate

Я использовал образцы кода, сгенерированные в paypal github, найденные здесь (я использовал PHP): https://github.com/paypal/ipn-code-samples

Я загрузил оба сертификата и попробовал тестирование как от curl: http://curl.haxx.se/docs/caextract.html

Примерно через 2 часа тестирования (с использованием симулятора PayPal ipn) и googling выяснилось, что paypal ipn не может быть протестирован на localhost, поэтому я нажал код в реальном времени и попробовал тестирование, но все равно получил ту же ошибку (даже с разрешениями задано на 777).

Когда я установил CURLOPT_SSL_VERIFYPEER, false, он сработал, но это может превзойти цель получения сертификата ssl.

После того, как я просматривал файлы своего сервера, я нашел файл curl-ca-bundle.crt в моей папке PHP. Я решил сделать hardcode CURLOPT_CAINFO в моем paypal ipn script этому пути. Он наконец-то сработает!

Я заметил, что этот старый .crt файл содержит некоторые сертификаты, которые не были в последнем .crt файле с сайта curl. Это была куча сертификатов от verisign class 1, verisign class 2, verisign class 3 and verisign class 4.

Здесь полный список имен сертификатов, которые я добавил в curl.crt файл:

  • Verisign Class 1 Public Primary Certification Authority
  • Verisign Class 1 Public Primary Certification Authority - G2
  • Verisign Class 1 Public Primary Certification Authority - G3
  • Verisign Class 2 Public Primary Certification Authority - G2
  • Verisign Class 2 Public Primary Certification Authority - G3
  • Verisign Class 3 Public Primary Certification Authority
  • Verisign Class 4 Public Primary Certification Authority - G2

Это может иметь какое-то отношение к тому, что говорил @Andomar, - сертификат verisign для PayPal не включен в список по умолчанию (по умолчанию я имею в виду список по умолчанию) безопасных сертификатов.

У меня не было времени для отладки и выяснения, какой именно сертификат необходим, поэтому я просто включил их все.

Для тех, кто испытывает эту проблему в будущем, я предлагаю вам получить последние сертификаты от завитка и добавить один за другим сертификаты в списке выше, пока ошибка не исчезнет.

Здесь ссылка для некоторых из этих сертификатов verisign (вам может понадобиться Google для других, не указанных в списке): www.symantec.com/page.jsp?id=roots

Примечание *: Чтобы просмотреть текущие сертификаты PayPal, вы можете запустить эту команду в терминале:

openssl s_client -connect paypal.com:443 -showcerts

Если у кого-то есть более глубокое понимание этой проблемы, прокомментируйте, поскольку я потратил часы, чтобы понять все вышеизложенное.

Ответ 4

Проблема сертификата SSL: невозможно получить сертификат локального эмитента

означает, что cUrl не доверяет Verisign, центру сертификации, который поручает PayPal. Как отмечает Marc B, cUrl больше не доверяет ни одному сертификату.

Вы можете обходить проверку цепочки сертификатов с помощью опции:

CURLOPT_SSL_VERIFYPEER => 0

Чтобы узнать, как настроить cUrl так, чтобы он доверял Verisign, прочитайте документацию cUrl.