Иногда бывает необходимо протестировать соединение с каким-либо сервером через https-протокол, а именно с использованием SSL-сертификата. В описанном примере у нас есть клиентский файл сертификата client.crt и файл обмена информацией client.p12 предоставленные сервером (как, например, свои сертификаты предоставляет сервер API Яндекс.Директ) и клиентский сертификат «подписан» серверным с помощью приватного ключа.
Более подробное описание взаимодействия SSL-клиента и SSL-сервера конечно можно найти в сети, например, в этой древней статье «Apache 2 with SSL/TLS: Step-by-Step» а тут я только приложу картинку отсюда:
Для установления тестового соединения будем использовать локальный веб-сервер Apache с включенными в настройках PHP библиотеками OpenSSL и CURL.
И для начала, с помощью php-функции openssl_pkcs12_read возьмем из файла client.p12 сертификат клиента в формате *.pem и приватный ключ в том же формате, код из коммента к документаци:
$certs = array(); $pkcs12 = file_get_contents( "client.p12" ); // Сертификат без пароля доступа openssl_pkcs12_read( $pkcs12, $certs, "" ); print_r( $certs ); |
Получим:
Array ( [cert] => --- BEGIN CERTIFICATE --- MIICdzCCAeCgAwIBAgIBATANBgkqhkiG9w0BAQUFADAsMRAwDgYDVQQKEwdTZWNj dXJlMRgwFgYDVQQLEw9TZWNjdXJlIFJvb3QgQ0EwHhcNMDQxMTI4MDEwMDIwWhcN ... ou0Kuxqk6E66ZpNjdIf9Q0i2k6LjPdobZEY1iLRLIuY8hHBdiN1kwlHC1lmAh7y9 f+PBRX7AX5zK4aE= --- END CERTIFICATE --- [pkey] => --- BEGIN RSA PRIVATE KEY --- AgMBAAGjeTB3MB0GA1UdDgQWBBQ50isUEV6uFPZ0L4RbRm41+i1CpTBIBgNVHSME QTA/gBQ50isUEV6uFPZ0L4RbRm41+i1CpaEkpCIwIDEeMBwGA1UEAxMVVGVzdC1P ... NxfJ7yfo0PkqNnjHfvnb5W07GcfGgLx5/U3iUROObYlwKlr6tQzMoysNQ/YtN3pp 52sGsqaOOWpYlAGOaM8j57Nv/eXogQnDRT0txXqoVEbunmM= [extracerts] = Array ( ) )
Первый элемент массива будет содержимым файла clientcert.pem, соответственно второй — privatekey.pem.
Для установления SSL-соединения используем популярный вариант с использованием CURL с заданием SSL-опций функцией curl_setopt:
$url = 'https://sslserver.com/'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, '2'); curl_setopt($ch, CURLOPT_SSLCERT, 'C:\AppServ\www\certs\clientcert.pem'); curl_setopt($ch, CURLOPT_SSLKEY, 'C:\AppServ\www\certs\privatekey.pem'); curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); $result = curl_exec ($ch); echo $result; if ($result == NULL) { echo "Error:\n"; echo curl_errno($ch) . " - " . curl_error($ch) . "\n"; } curl_close ($ch); |