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 шт):
На эту тему есть достаточно ресурсов в Интернете, где говорится что стандартный 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 для ГОСТ не подключал.