Отправка клиентского SSL-сертификата в PHP без cURL: пример с stream_context_create для Сбер ID
Клиентские SSL-сертификаты используются для идентификации клиента или пользователя и аутентификации клиента на сервере. Обычно в таком случае используется двухфакторная идентификация – через логин/пароль, а также через сертификат.
Необходимость в передаче сертификата в запросе появилась при добавлении возможности входа на сайт через Сбер ID в модуль Входа по ID для 1С-Битрикс.
Для запросов к API Сбер ID требуется передать помимо ключей еще и сертификат. В интернете навалом примеров использования для этого curl. Но эта библиотека может быть не установлена на сервере, а разработку модулей стараемся делать таким образом, чтобы как можно меньше приходилось что-то настраивать и устанавливать дополнительно. В таком случае меньше обращений в поддержку за помощью.
Поэтому приведу пример передачи сертификата без curl. Так как в инете не нашел такой информации, только отдельные части, наводящие на решение.
Распаковка контейнера с сертификатом
Сбер дает скачать запароленный контейнер с сертификатом и приватным ключом в формате PKCS#12. Первым делом нужно извлечь эти данные из контейнера.
$containerContent = file_get_contents($arFile['tmp_name']);
if (!function_exists('openssl_pkcs12_read')) {
throw new \BXmaker\AuthID\Exception\BaseException(self::getMessage(
'ERROR_OPENSSL_LIBRARY_NOT_FOUND'
));
}
if (!openssl_pkcs12_read($containerContent, $certificates, $filePassword)) {
throw new \BXmaker\AuthID\Exception\BaseException(self::getMessage(
'ERROR_CERTIFICATE_FILE_READ'
));
}
\Bitrix\Main\IO\File::putFileContents(
$serviceDir . '/client.crt',
$certificates['cert'] . implode('', $certificates['extracerts'])
);
\Bitrix\Main\IO\File::putFileContents(
$serviceDir . '/private.key',
$certificates['pkey']
);
Запрос с передачей клиентского сертификата методом POST или GET
Все что нужно сделать - дополнить опции контекста запроса данными о путях до файлов сертификата и приватного ключа. Передаются они в метод - stream_context_create подробнее о методе - https://www.php.net/manual/ru/function.stream-context-create.php
В реализации для 1С-Битрикс это будет выглядеть примерно так
$oHttpClient = new \Bitrix\Main\Web\HttpClient();
$oHttpClient->setTimeout(10);
$oHttpClient->setStreamTimeout(10);
//$oHttpClient->disableSslVerification();
$oHttpClient->setContextOptions([
'ssl' => [
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true,
'local_cert' => '/storage/client.crt',
'local_pk' => '/storage/private.key',
]
]);
$oHttpClient->get('https://oauth.sber.ru/api/v2/auth/completed');