Найти в Дзене

Запросы с клиентским сертификатом без curl на php

Клиентские SSL-сертификаты используются для идентификации клиента или пользователя и аутентификации клиента на сервере. Обычно в таком случае используется двухфакторная идентификация – через логин/пароль, а также через сертификат. Необходимость в передачи сертификата в запросе появилась при добавлении возможности входа на сайт через Сбер ID в модуль Входа по ID для 1с-битрикс. Для запросов к API Сбер Id требуется передать помимо ключей еще и сертификат. В интернете навалом примеров исопльзования для этого curl. Но эта библиотека может быть не установлена на сервере, а разработку можулей стараемся делать таким образом, чтобы как можно меньше приходилось чтото настраивать и устанавливать дополнительно. В таком случае меньше обращений в поддержку за помощью. Поэтому приведу пример передачи сертификата без curl. Так как в инете не нашел такой информации, только отдельные части наводящие на решение. Сбер дает скачать запароленный контейнер с сертификатом и приватным ключом в формате
Оглавление

Клиентские SSL-сертификаты используются для идентификации клиента или пользователя и аутентификации клиента на сервере. Обычно в таком случае используется двухфакторная идентификация – через логин/пароль, а также через сертификат.

Необходимость в передачи сертификата в запросе появилась при добавлении возможности входа на сайт через Сбер ID в модуль Входа по ID для 1с-битрикс.

Для запросов к API Сбер Id требуется передать помимо ключей еще и сертификат. В интернете навалом примеров исопльзования для этого curl. Но эта библиотека может быть не установлена на сервере, а разработку можулей стараемся делать таким образом, чтобы как можно меньше приходилось чтото настраивать и устанавливать дополнительно. В таком случае меньше обращений в поддержку за помощью.

Поэтому приведу пример передачи сертификата без curl. Так как в инете не нашел такой информации, только отдельные части наводящие на решение.

Распаковка контейнера с сертификатом

Сбер дает скачать запароленный контейнер с сертификатом и приватным ключом в формате PKCS#12. Первый делом нужно извлечь эти данные из контейнера.

$contanerContent = 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($contanerContent, $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');