cURL PHP Windows ГОСТ2012

Это мой первый пост на данном ресурсе. Помогите, пожалуйста, решить проблему. Под Windows запущен Open Server (5.2.2) - PHP 5.5, Apache 2.4+Nginx 1.10, openSSL 1.0.2l. С помощью cURL отправляю запрос POST на https (сервер использует шифрование ГОСТ 2012):

$postData = array(
    "document" => ""
);
$myCurl = curl_init('https://.....');
curl_setopt_array($myCurl, array(
    CURLOPT_POST => TRUE,
    CURLOPT_RETURNTRANSFER => TRUE,
    CURLOPT_HTTPHEADER => array(
        'Accept: application/json',
        'Content-Type: application/json'
    ),
    CURLOPT_POSTFIELDS => json_encode($postData)
));

Приходит ответ от сервера: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure

Пробовал так:

$postData = array(
    "document" => ""
);
$myCurl = curl_init('https://.....');
curl_setopt_array($myCurl, array(
    CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1_0,
    CURLOPT_SSLCERT => путь к сертификату, использумый сервером,
    CURLOPT_POST => TRUE,
    CURLOPT_RETURNTRANSFER => TRUE,
    CURLOPT_HTTPHEADER => array(
        'Accept: application/json',
        'Content-Type: application/json'
    ),
    CURLOPT_POSTFIELDS => json_encode($postData)
));

Ответ от сервера: could not load PEM client certificate, OpenSSL error error:0609E09C:digital envelope routines:pKEY_SET_TYPE:unsupported algorithm, (no key found, wrong pass phrase, or wrong file format?)

Через Internet Explorer ошибок нет. Через Chrome - ошибка ERR_SSL_VERSION_OR_CIPHER_MISMATCH. В чем может быть проблема?


Ответы (2 шт):

Автор решения: Daniel Protopopov

На эту тему есть достаточно ресурсов в Интернете, где говорится что стандартный OpenSSL не имеет механизмов общения для ГОСТ2012. Для этого нужно компилировать его самому и добавлять эту поддержку, что на Windows будет той ещё задачкой. Почитайте результаты поиска «windows openssl gost2012» на Гугле чтобы иметь представление об этом.

У IE проблемы не будет так как он, как я подозреваю, использует провайдер типа КриптоПро. Для того чтобы ваша программа могла устанавливать связь по ГОСТ2012, вам нужно будет скомпилировать ваш OpenSSL модуль, через который будет проходить ваша программа.

→ Ссылка
Автор решения: Сергей Шидловский

Установил Open Server на чистую винду. Выбрал модуль Apache 2.4+Nginx 1.17, PHP 7.2. В составе OpenSSL 1.1.1d. Попробовал тот же скрипт

$postData = array(
    "document" => ""
);
$myCurl = curl_init('https://.....');
curl_setopt_array($myCurl, array(
    CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1_0,
    CURLOPT_CAINFO => путь к сертификату, использумый сервером,
    CURLOPT_CERTINFO => TRUE,
    CURLOPT_POST => TRUE,
    CURLOPT_RETURNTRANSFER => TRUE,
    CURLOPT_HTTPHEADER => array(
        'Accept: application/json',
        'Content-Type: application/json'
    ),
    CURLOPT_POSTFIELDS => json_encode($postData)
));

Все заработало, ответ от сервера пришел. В первых вариантах использовал CURLOPT_SSLCERT для указания пути к сертификату сервера. Понял ошибку - исправил на CURLOPT_CAINFO. Пробовал другие версии PHP в составе OpenServer - соединение устанавливается только если OpenSSL версия 1.1.0 или выше.

При этом openssl_get_cipher_methods() не показывает GOST вообще, а в openssl_get_md_methods() присутствует GOST 31.11-2012.

Сторонние dll для ГОСТ не подключал.

→ Ссылка