Подтверждения IPN PayPal IPN с использованием процедур SSL: SSL3_READ_BYTES: сбой вызова подтверждения sslv3

Без изменений на нашей стороне и, возможно, связанных с POODLE / SSL3, наш API-интерфейс PayPal API для PPIPNMessage :: validate теперь не работает.

SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure 

Проверка и получение IPN в порядке (и мы никогда не поддерживали входящий SSL3), это просто сбой при подтверждении IPN (странно PayPal не пытается снова, даже если мы потерпели неудачу)

Запуск curl с той же командной строки сервера завершается успешно

 $ curl -iv https://ipnpb.paypal.com/cgi-bin/webscr * About to connect() to ipnpb.paypal.com port 443 (#0) * Trying 173.0.88.8... connected * successfully set certificate verify locations: * CAfile: none CApath: /etc/ssl/certs * SSLv3, TLS handshake, Client hello (1): * SSLv3, TLS handshake, Server hello (2): * SSLv3, TLS handshake, CERT (11): * SSLv3, TLS handshake, Server finished (14): * SSLv3, TLS handshake, Client key exchange (16): * SSLv3, TLS change cipher, Client hello (1): * SSLv3, TLS handshake, Finished (20): * SSLv3, TLS change cipher, Client hello (1): * SSLv3, TLS handshake, Finished (20): * SSL connection using AES256-SHA * Server certificate: * subject: 1.3.6.1.4.1.311.60.2.1.3=US; 1.3.6.1.4.1.311.60.2.1.2=Delaware; businessCategory=Private Organization; serialNumber=3014267; C=US; postalCode=95131-2021; ST=California; L=San Jose; street=2211 N 1st St; O=PayPal, Inc.; OU=PayPal Production; CN=ipnpb.paypa * start date: 2013-06-28 00:00:00 GMT * expire date: 2015-08-02 23:59:59 GMT * subjectAltName: ipnpb.paypal.com matched * issuer: C=US; O=VeriSign, Inc.; OU=VeriSign Trust Network; OU=Terms of use at https://www.verisign.com/rpa (c)06; CN=VeriSign Class 3 Extended Validation SSL CA * SSL certificate verify ok. > GET /cgi-bin/webscr HTTP/1.1 > User-Agent: curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3 > Host: ipnpb.paypal.com > Accept: */* 

Я заметил, что ssllabs.com показывает 1 из 4 IP-адресов, поддерживающих SSL3 на этой конечной точке.

Это та же проблема, что и ошибка 0x1408F10B: «SSL3_GET_RECORD: неправильный номер версии» с SDK PayPal

В версии API PayPal мы используем жесткие коды CURLOPT_SSLVERSION до 3.

Наше исправление заключается в том, чтобы вставить это перед любыми вызовами PayPal.

 PPHttpConfig::$DEFAULT_CURL_OPTS[CURLOPT_SSLVERSION] = 4; 

У меня была такая же проблема … Просто измените следующую строку на ipnlistener.php

из:

 curl_setopt($ch, CURLOPT_SSLVERSION, 3); 

чтобы:

 curl_setopt($ch, CURLOPT_SSLVERSION, 4); 

ipnlistener.php

 use_ssl) { $uri = 'https://'.$this->getPaypalHost().'/cgi-bin/webscr'; $this->post_uri = $uri; } else { $uri = 'http://'.$this->getPaypalHost().'/cgi-bin/webscr'; $this->post_uri = $uri; } $ch = curl_init(); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__)."/cert/api_cert_chain.crt"); curl_setopt($ch, CURLOPT_URL, $uri); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $encoded_data); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $this->follow_location); curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_SSLVERSION, 4); if ($this->force_ssl_v3) { curl_setopt($ch, CURLOPT_SSLVERSION, 4); //Modified from 3 to 4 } $this->response = curl_exec($ch); $this->response_status = strval(curl_getinfo($ch, CURLINFO_HTTP_CODE)); if ($this->response === false || $this->response_status == '0') { $errno = curl_errno($ch); $errstr = curl_error($ch); throw new Exception("cURL error: [$errno] $errstr"); } } /** * Post Back Using fsockopen() * * Sends the post back to PayPal using the fsockopen() function. Called by * the processIpn() method if the use_curl property is false. Throws an * exception if the post fails. Populates the response, response_status, * and post_uri properties on success. * * @param string The post data as a URL encoded string */ protected function fsockPost($encoded_data) { if ($this->use_ssl) { $uri = 'ssl://'.$this->getPaypalHost(); $port = '443'; $this->post_uri = $uri.'/cgi-bin/webscr'; } else { $uri = $this->getPaypalHost(); // no "http://" in call to fsockopen() $port = '80'; $this->post_uri = 'http://'.$uri.'/cgi-bin/webscr'; } $fp = fsockopen($uri, $port, $errno, $errstr, $this->timeout); if (!$fp) { // fsockopen error throw new Exception("fsockopen error: [$errno] $errstr"); } $header = "POST /cgi-bin/webscr HTTP/1.1\r\n"; $header .= "Host: ".$this->getPaypalHost()."\r\n"; $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; $header .= "Content-Length: ".strlen($encoded_data)."\r\n"; $header .= "Connection: Close\r\n\r\n"; fputs($fp, $header.$encoded_data."\r\n\r\n"); while(!feof($fp)) { if (empty($this->response)) { // extract HTTP status from first line $this->response .= $status = fgets($fp, 1024); $this->response_status = trim(substr($status, 9, 4)); } else { $this->response .= fgets($fp, 1024); } } fclose($fp); } private function getPaypalHost() { if ($this->use_sandbox) return self::SANDBOX_HOST; else return self::PAYPAL_HOST; } /** * Get POST URI * * Returns the URI that was used to send the post back to PayPal. This can * be useful for troubleshooting connection problems. The default URI * would be "ssl://www.sandbox.paypal.com:443/cgi-bin/webscr" * * @return string */ public function getPostUri() { return $this->post_uri; } /** * Get Response * * Returns the entire response from PayPal as a string including all the * HTTP headers. * * @return string */ public function getResponse() { return $this->response; } /** * Get Response Status * * Returns the HTTP response status code from PayPal. This should be "200" * if the post back was successful. * * @return string */ public function getResponseStatus() { return $this->response_status; } /** * Get Text Report * * Returns a report of the IPN transaction in plain text format. This is * useful in emails to order processors and system administrators. Override * this method in your own class to customize the report. * * @return string */ public function getTextReport() { $r = ''; // date and POST url for ($i=0; $i<80; $i++) { $r .= '-'; } $r .= "\n[".date('m/d/Y g:i A').'] - '.$this->getPostUri(); if ($this->use_curl) $r .= " (curl)\n"; else $r .= " (fsockopen)\n"; // HTTP Response for ($i=0; $i<80; $i++) { $r .= '-'; } $r .= "\n{$this->getResponse()}\n"; // POST vars for ($i=0; $i<80; $i++) { $r .= '-'; } $r .= "\n"; foreach ($this->post_data as $key => $value) { $r .= str_pad($key, 25)."$value\n"; } $r .= "\n\n"; return $r; } /** * Process IPN * * Handles the IPN post back to PayPal and parsing the response. Call this * method from your IPN listener script. Returns true if the response came * back as "VERIFIED", false if the response came back "INVALID", and * throws an exception if there is an error. * * @param array * * @return boolean */ public function processIpn($post_data=null) { $encoded_data = 'cmd=_notify-validate'; if ($post_data === null) { // use raw POST data if (!empty($_POST)) { $this->post_data = $_POST; $encoded_data .= '&'.file_get_contents('php://input'); } else { throw new Exception("No POST data found."); } } else { // use provided data array $this->post_data = $post_data; foreach ($this->post_data as $key => $value) { $encoded_data .= "&$key=".urlencode($value); } } if ($this->use_curl) $this->curlPost($encoded_data); else $this->fsockPost($encoded_data); if (strpos($this->response_status, '200') === false) { throw new Exception("Invalid response status: ".$this->response_status); } if (strpos($this->response, "VERIFIED") !== false) { return true; } elseif (strpos($this->response, "INVALID") !== false) { return false; } else { throw new Exception("Unexpected response from PayPal."); } } /** * Require Post Method * * Throws an exception and sets a HTTP 405 response header if the request * method was not POST. */ public function requirePostMethod() { // require POST requests if ($_SERVER['REQUEST_METHOD'] && $_SERVER['REQUEST_METHOD'] != 'POST') { header('Allow: POST', true, 405); throw new Exception("Invalid HTTP request method."); } } } ?> . use_ssl) { $uri = 'https://'.$this->getPaypalHost().'/cgi-bin/webscr'; $this->post_uri = $uri; } else { $uri = 'http://'.$this->getPaypalHost().'/cgi-bin/webscr'; $this->post_uri = $uri; } $ch = curl_init(); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__)."/cert/api_cert_chain.crt"); curl_setopt($ch, CURLOPT_URL, $uri); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $encoded_data); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $this->follow_location); curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_SSLVERSION, 4); if ($this->force_ssl_v3) { curl_setopt($ch, CURLOPT_SSLVERSION, 4); //Modified from 3 to 4 } $this->response = curl_exec($ch); $this->response_status = strval(curl_getinfo($ch, CURLINFO_HTTP_CODE)); if ($this->response === false || $this->response_status == '0') { $errno = curl_errno($ch); $errstr = curl_error($ch); throw new Exception("cURL error: [$errno] $errstr"); } } /** * Post Back Using fsockopen() * * Sends the post back to PayPal using the fsockopen() function. Called by * the processIpn() method if the use_curl property is false. Throws an * exception if the post fails. Populates the response, response_status, * and post_uri properties on success. * * @param string The post data as a URL encoded string */ protected function fsockPost($encoded_data) { if ($this->use_ssl) { $uri = 'ssl://'.$this->getPaypalHost(); $port = '443'; $this->post_uri = $uri.'/cgi-bin/webscr'; } else { $uri = $this->getPaypalHost(); // no "http://" in call to fsockopen() $port = '80'; $this->post_uri = 'http://'.$uri.'/cgi-bin/webscr'; } $fp = fsockopen($uri, $port, $errno, $errstr, $this->timeout); if (!$fp) { // fsockopen error throw new Exception("fsockopen error: [$errno] $errstr"); } $header = "POST /cgi-bin/webscr HTTP/1.1\r\n"; $header .= "Host: ".$this->getPaypalHost()."\r\n"; $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; $header .= "Content-Length: ".strlen($encoded_data)."\r\n"; $header .= "Connection: Close\r\n\r\n"; fputs($fp, $header.$encoded_data."\r\n\r\n"); while(!feof($fp)) { if (empty($this->response)) { // extract HTTP status from first line $this->response .= $status = fgets($fp, 1024); $this->response_status = trim(substr($status, 9, 4)); } else { $this->response .= fgets($fp, 1024); } } fclose($fp); } private function getPaypalHost() { if ($this->use_sandbox) return self::SANDBOX_HOST; else return self::PAYPAL_HOST; } /** * Get POST URI * * Returns the URI that was used to send the post back to PayPal. This can * be useful for troubleshooting connection problems. The default URI * would be "ssl://www.sandbox.paypal.com:443/cgi-bin/webscr" * * @return string */ public function getPostUri() { return $this->post_uri; } /** * Get Response * * Returns the entire response from PayPal as a string including all the * HTTP headers. * * @return string */ public function getResponse() { return $this->response; } /** * Get Response Status * * Returns the HTTP response status code from PayPal. This should be "200" * if the post back was successful. * * @return string */ public function getResponseStatus() { return $this->response_status; } /** * Get Text Report * * Returns a report of the IPN transaction in plain text format. This is * useful in emails to order processors and system administrators. Override * this method in your own class to customize the report. * * @return string */ public function getTextReport() { $r = ''; // date and POST url for ($i=0; $i<80; $i++) { $r .= '-'; } $r .= "\n[".date('m/d/Y g:i A').'] - '.$this->getPostUri(); if ($this->use_curl) $r .= " (curl)\n"; else $r .= " (fsockopen)\n"; // HTTP Response for ($i=0; $i<80; $i++) { $r .= '-'; } $r .= "\n{$this->getResponse()}\n"; // POST vars for ($i=0; $i<80; $i++) { $r .= '-'; } $r .= "\n"; foreach ($this->post_data as $key => $value) { $r .= str_pad($key, 25)."$value\n"; } $r .= "\n\n"; return $r; } /** * Process IPN * * Handles the IPN post back to PayPal and parsing the response. Call this * method from your IPN listener script. Returns true if the response came * back as "VERIFIED", false if the response came back "INVALID", and * throws an exception if there is an error. * * @param array * * @return boolean */ public function processIpn($post_data=null) { $encoded_data = 'cmd=_notify-validate'; if ($post_data === null) { // use raw POST data if (!empty($_POST)) { $this->post_data = $_POST; $encoded_data .= '&'.file_get_contents('php://input'); } else { throw new Exception("No POST data found."); } } else { // use provided data array $this->post_data = $post_data; foreach ($this->post_data as $key => $value) { $encoded_data .= "&$key=".urlencode($value); } } if ($this->use_curl) $this->curlPost($encoded_data); else $this->fsockPost($encoded_data); if (strpos($this->response_status, '200') === false) { throw new Exception("Invalid response status: ".$this->response_status); } if (strpos($this->response, "VERIFIED") !== false) { return true; } elseif (strpos($this->response, "INVALID") !== false) { return false; } else { throw new Exception("Unexpected response from PayPal."); } } /** * Require Post Method * * Throws an exception and sets a HTTP 405 response header if the request * method was not POST. */ public function requirePostMethod() { // require POST requests if ($_SERVER['REQUEST_METHOD'] && $_SERVER['REQUEST_METHOD'] != 'POST') { header('Allow: POST', true, 405); throw new Exception("Invalid HTTP request method."); } } } ?> 

PayPal отключил SSLv3 в ответ на пристрастие «POODLE». Читайте об этом здесь: PayPal Response

Если вы используете ipnlistener.php, заставьте TLS 1.2 в качестве протокола SSL:

 curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); 

(Обновлено: TLS V1.2 требуется на 2017 год)

Примечание. PayPal обновляет протоколы, используемые для защиты всех внешних подключений к их системам. Transport Layer Security версии 1.2 (TLS 1.2) и Hypertext Transfer Protocol версии 1.1 (HTTP / 1.1) станут обязательными для связи с PayPal в 2018 году. См. Их дорожную карту безопасности

SSLv3 больше не доступен для http://www.paypal.com:

 # sslscan www.paypal.com|grep Accepted Accepted TLSv1 256 bits AES256-SHA Accepted TLSv1 128 bits AES128-SHA Accepted TLSv1 168 bits DES-CBC3-SHA Accepted TLSv1 128 bits RC4-SHA Accepted TLSv1 128 bits RC4-MD5 

Вы должны изменить CURLOPT_SSLVERSION на TLSv1 :

 curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); 

(Этот «CURL_SSLVERSION_TLSv1» -констант недоступен для старых версий PHP, поэтому другой способ – просто удалить CURLOPT_SSLVERSION.)

Для меня Ни одна из этих вещей, упомянутых в других ответах, не работала, но я смог разобраться с исправлением, и это было по одной строке, но мне потребовалось некоторое время, чтобы узнать, какой файл, который я использовал sdk, не был файлом прослушивания ipn и что «PPHttpConfig» дало бы мне фатальную ошибку

поэтому я нашел, что это файл-слушатель, который они используют сейчас:

PayPal-PHP-SDK / PayPal / rest-апи-СДК-PHP / Библиотека / PayPal / kernel ​​/ PayPalHttpConfig.php

Я нашел внутри

CURLOPT_SSLVERSION => 1

Я изменил его на:

CURLOPT_SSLVERSION => 4

и это исправило это для меня.

Я второй. Потерянные часы пытаются понять это. На моем слушателе IPN мне пришлось удалить «force ssl v3». С этого момента мой IPN снова начнет работать.

Просто сделайте curl -v https://paypal.com

Он показывает: соединение SSL с использованием TLS_RSA_WITH_AES_256_CBC_SHA

У меня такая же ошибка при проверке IPN с помощью PayPal. Вот решения проблемы

Я работал с PHP 5.3 и PHP 5.3 больше не поддерживает SSL версию 3. У меня есть обновление с версией PHP с 5.4 и добавлено ниже строки кода. Это работа для меня.

 curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $req); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); #curl_setopt($ch, CURLOPT_SSLVERSION, 4); curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, 'TLSv1'); 

Используйте этот параметр в своем classе paypal при вызове функции PPHttpPost ()

 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_SSLVERSION, 6); //6 is for TLSV1.2 
  • javax.net.ssl.SSLException: Ошибка чтения: ssl = 0x9524b800: ошибка ввода-вывода во время системного вызова, сброс соединения с помощью одноранговой сети
  • Включить TLS 1.1 и 1.2 для клиентов на Java 7
  • Facebook JavaScript SDK через HTTPS, загрузка незащищенных элементов
  • Отключить просмотр SSL в Chrome
  • Java: загрузка SSL Keystore через ресурс
  • Как игнорировать проверку сертификата, когда ssl
  • JavaMail IMAP через SSL довольно медленно - Массовая выборка нескольких сообщений
  • Как переопределить шифрованный список, отправленный на сервер Android при использовании HttpsURLConnection?
  • Как получить файл .pem из .key и .crt файлов?
  • Использование CERT Tapioca на VM
  • Где получить сертификаты для Acrobat PDF
  • Interesting Posts

    Регулярное выражение для соответствия координат широты / долготы?

    Что эквивалентно шаблонам Java в C # generics

    Что такое «rvalue reference для * this»?

    Как избежать одиночной цитаты внутри awk

    Загружать только источники пакета и все зависимости

    Что происходит, когда вы увеличиваете целое число за пределами его максимального значения?

    Как перенести Windows из раздела существующего жесткого диска на новый (меньший) SSD?

    Как мне выполнить слово Stemming или Lemmatization?

    Как получить серийный номер жесткого диска из командной строки?

    Не удалось указать целевые платформы. Проверьте правильность пути sdk android.

    Установка Windows 7 на новый ноутбук на базе EFI не может войти в утилиту настройки Windows 7?

    Python install ставит все файлы / библиотеки в каталог c: root (Windows 7 64-bit)

    Как вернуть результат (startActivityForResult) из TabHost Activity?

    100% использование диска на окнах 10

    Зачем использовать «virtual» для свойств classа в определениях модели Entity Framework?

    Давайте будем гением компьютера.