Проверка SSL(https) -соединения с сертификатом на локальном сервере PHP+cURL+Apache

Иногда бывает необходимо протестировать соединение с каким-либо сервером через https-протокол, а именно с использованием SSL-сертификата. В описанном примере у нас есть клиентский файл сертификата client.crt и файл обмена информацией client.p12 предоставленные сервером (как, например, свои сертификаты предоставляет сервер API Яндекс.Директ) и клиентский сертификат «подписан» серверным с помощью приватного ключа.

Более подробное описание взаимодействия SSL-клиента и SSL-сервера конечно можно найти в сети, например, в этой древней статье «Apache 2 with SSL/TLS: Step-by-Step» а тут я только приложу картинку отсюда:

Взаимодействие SSL-клиента/Браузера и SSL-сервера при установке соединения

Для установления тестового соединения будем использовать локальный веб-сервер 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);


Добавление комментария:

 css.php