Проблемы с подключением к SSL-зашифрованному веб-сервису с PHP - PullRequest
4 голосов
/ 27 сентября 2010

Я получил два файла сертификатов от провайдера, один в формате .cer и один в формате .p7b.Затем я преобразовал p7b-сертификат в p12-сертификат.С этим сертификатом я могу подключиться к wsdl из моего браузера.Затем я приступил к преобразованию этого сертификата в формат .pem, используя некоторые инструкции, найденные на этом сайте.

openssl pkcs12 -clcerts -nokeys -out test.pem -in mycert.p12
openssl pkcs12 -nocerts -out key.pem -in mycert.p12

, а затем расчесал сертификат с ключом с помощью следующей команды:

cat test.pem key.pem > cert.pem

Вот моя конструкция для класса веб-службы:

public function __construct() {
    $wsdl_url = 'https://url.to/web_service?wsdl';
    $pass = 'passphrase';
    $cert = 'cert.pem';

    try {
        $this->client = new SoapClient($wsdl_url, array('local_cert' => $cert, 'passphrase' => $pass));
    } catch(SoapFault $e) {
        print_r($e);
    }
}

И вот ошибка:

SSL operation failed with code 1. OpenSSL Error messages: error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca in /var/www/html/..

Попытка проверить сертификат с помощью:

openssl verify cert.pem

выдает мне следующую ошибку:

error 20 at 0 depth lookup:unable to get local issuer certificate

Я также пытался создать .pem-сертификат с помощью следующей команды openssl:

openssl pkcs12 -in mycert.p12 -out mycert.pem

Подтверждение этого дает мне ОК, но PHPвыдает мне следующую ошибку:

Unable to set local cert chain file `mycert.pem'; Check that your cafile/capath settings include details of your certificate and its issuer

Я предполагаю, что должна быть возможность каким-то образом заставить его работать, так как я могу получить доступ к wsdl через мой браузер, используя .p12-сертификат.Но я не могу найти решение о том, как мне поступить.Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 29 октября 2010

Я думаю, что он не может найти корневой сертификат, выдавший сертификат, который вам был предоставлен.

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

Для проверки openssl x509 -text -noout -in key.pem

Проверьте вывод и найдите эмитента. Если эмитент не совпадает с CN сертификата, вам нужен корневой сертификат от подписывающего органа, предоставившего ваш сертификат.

Обычно его можно получить с помощью браузера, чтобы открыть свой адрес wsdl, проверить цепочку сертификатов и экспортировать корневой сертификат из вкладки иерархии.

Где вы сохраните его в вашей ситуации, я не уверен, но будет что-то, что будет указывать на хранилище доверия какого-то типа.

0 голосов
/ 27 сентября 2010

Я думаю, у вас есть несколько проблем здесь. Во-первых, я не думаю, что ваши параметры для локального сертификата используются конструктором для объекта SoapClient. Массив параметров не поддерживает параметры конфигурации SSL. Во-вторых, учитывая, что опции, которые вы предоставляете SoapClient, не используются, Open SSL жалуется на то, что сертификат на удаленном хосте является самосертифицированным сертификатом.

Я думаю, что можно обойти это, но без игры с кодом я не могу быть уверен во всех вариантах. Я думаю, что вам нужно создать собственный контекст потока, используя stream_context_create (), чтобы установить нужные вам параметры SSL (посмотрите на http://ca.php.net/stream_context_create и параметры контекста для SSL). Затем его можно передать объекту SoapClient как параметр stream_context в массиве конфигурации. Используя stream_context, вы можете установить различные опции SSL, которые вам нужны, и они переопределят значения по умолчанию.

Извините, я не могу более точно указать параметры, которые нужно установить. Надеемся, что игра с контекстом потока решит вашу проблему.

...