Привет, меня зовут Никита Нятин. Я главный разработчик PHP в Уральском банке реконструкции и развития. Расскажу, как мы в банке внедряли интеграцию с Единой системой идентификации и аутентификации (ЕСИА) на PHP и какие проблемы пришлось решать.
Зарождение идеи
В УБРиР есть сервис посадочных страниц, позволяющий клиентам оставлять заявки на кредит, вклад и РКО. В 2019 году у нас возникла идея упростить процесс заполнения заявки на кредит. Зачем клиенту указывать ФИО, адрес регистрации, если все эти сведения уже есть на сайте Госуслуг (ГУ), который также называют ЕСИА.
Как это работает: глазами клиента
Клиент нажимает на кнопку “Авторизоваться через Госуслуги”, после чего система его перенаправляет на сайт https://esia.gosuslugi.ru. Там клиента просят авторизоваться, указав свои логин и пароль от учетной записи.
После успешной авторизации нужно дать согласие на передачу своих данных ПАО КБ УБРиР.
Когда согласие дано, клиент перенаправляется обратно на посадочную страницу, где уже заполнены ФИО и паспортные данные, полученные от сайта ГУ. Остается только убедиться, что все верно, и отправить заявку.
Неожиданная поломка
Первая версия интеграции была написана в 2019 году и создавалась в рамках монолитного приложения, написанного на PHP 7.1. Реализовать интеграцию было непросто, но оно того стоило - клиенты стали пользоваться этой возможностью.
Радость длилась почти год, пока в августе 2020 года не истек сертификат, с помощью которого шло взаимодействие с ГУ. При попытке авторизоваться клиенты наблюдали ошибку. Это было для нас сюрпризом, поскольку мы не вели учет срока действия этого сертификата. Но это было не самое страшное. Оказывается, что с 1 апреля 2020 года RSA-сертификаты не могли использоваться для подписей запросов к ЕСИА.
Для устранения сбоя требовались следующие шаги:
получить в Удостоверяющем центре (УЦ) сертификат, выпущенный с использованием криптографического алгоритма ГОСТ Р 34.10-2012;
доработать нашу систему, чтобы она начала поддерживать работу с электронными подписями, выпущенными с использованием этого криптографического алгоритма.
Это было что-то! Интеграцию мы не смогли починить за один день, и за неделю не смогли, и за месяц тоже. Это было связано с тем, что первая версия интеграции была написана на скорую руку, без создания документации. Нам пришлось снова во всем разбираться и заново пройти процесс подключения к ЕСИА.
Как подключить сайт компании к ЕСИА
Нам пришлось изучить официальные документы по интеграции с ЕСИА и прочитать много статей. Какие шаги в итоге пришлось пройти, чтобы интеграция свершилась:
1. Регистрация руководителя организации на Госуслугах
Зарегистрировать компанию в ЕСИА может представитель, имеющий право действовать без доверенности. У него должна быть подтверждённая учётная запись физического лица. В нашем случае руководство банка уже было зарегистрировано на ГУ.
2. Регистрация компании на Госуслугах
Для этого нужна квалифицированная электронная подпись (КЭП), которую можно получить в одном из аккредитованных Минцифрой России удостоверяющих центров. С ее помощью юридическое лицо подписывает документы и подтверждает различные запросы на портале. Для того, чтобы работать с электронной подписью, необходимо установить криптозащиту на устройство. Это программное обеспечение может быть как платное, так и бесплатное. Подробнее - в инструкции или видео. В нашем случае банк был уже зарегистрирован на ГУ.
3. Регистрация информационной системы на технологическом портале Госуслуг
Доступ к порталу получают сотрудники организации, включенные в специальную группу “Технологический портал” и имеющие личную учетную запись на Госуслугах, это - обязательное условие для получения прав доступа к Техпорталу. После регистрации система заносится в реестр информационных систем (ИС) и получает мнемонику, то есть буквенно-цифровой код системы (к примеру, ROMASHKA, VECTOR, 123555_3S).
Существует небольшое Руководство пользователя технологического портала ЕСИА (47 страниц). В нем наглядно показано, как можно добавить новую ИС.
В нашем банке нашелся сотрудник, который уже имел доступ в портал, - он создал для нас новую ИС. Увы, этого было недостаточно. В руководстве написано: “создание записи ИС не означает, что данные ИС получают возможности по использованию программных интерфейсов ЕСИА. Для получения таких возможностей необходимо выполнить действия согласно Регламенту информационного взаимодействия Участников с Оператором ЕСИА и Оператором эксплуатации инфраструктуры электронного правительства”.
В разделе 1 “Введение” этого регламента приведена удобная таблица “Основные задачи заявителей”, где есть нужный нам пункт - “Подключиться к ЕСИА с целью идентификации и аутентификации пользователей своей системы (вход через Госуслуги)”. Там как раз описаны шаги, которые мы сейчас рассматриваем.
4. Получение сертификата и закрытого ключа для новой ИС
Сертификат должен удовлетворять следующим требованиям:
выдан аккредитованным Удостоверяющим центром. Благо в г. Екатеринбурге, где расположен главный офис УБРиР, есть два таких аккредитованных УЦ;
соответствует алгоритму формирования электронной подписи ГОСТ Р 34.10-2021 или алгоритму криптографического хэширования ГОСТ Р 34.11-2012;
должен содержать ОГРН юридического лица (ЮЛ), являющегося оператором ИС (может быть выпущен как на сотрудника ЮЛ, так и на организацию). Таким образом, в сертификате должна содержаться информация о том, что этот ключ относится именно к нашему банку.
При первичном получении сертификата нужно было посетить офис Контура (ООО Сертум-Про), при перевыпуске сертификата посещение не требуется - достаточно сформировать заявку в личном кабинете Контура. Далее там же выпускаются новые сертификат и ключ, которые записываются на виртуальную флешку (виртуальный образ с расширением .img).
Полученный сертификат - это файл с названием из 40 цифр, к примеру, 1151593111080991181175644517328337074622.cer. Этот сертификат нужно загрузить в карточку ИС на Техпортале.
Кстати, если открыть сертификат в текстовом редакторе, то там может оказаться абракадабра:
Это значит, что сертификат в бинарном формате. Если кликнуть по файлу сертификата в ОС Windows, появится диалоговое окно, в котором его можно преобразовать в другой формат - в X.509 (.CER) в кодировке Base-64:
Полученный файл сертификата можно открыть в текстовом редакторе и увидеть цифры и латинские буквы между “------BEGIN CERTIFICATE—--” и “-----END CERTIFICATE—--”. Это значит, что сертификат в кодировке base64.
Закрытый ключ представляет собой папку с 6 файлами с расширением .key из контейнера КриптоПро:
header.key;
masks.key;
masks2.key;
name.key;
primary.key;
primary2.key.
Эти файлы понадобятся на сервере приложения при настройке интеграции с ЕСИА.
5. Подключение к тестовой среде ЕСИА
На этом этапе нужно отправить на адрес sd@sc.minsvyaz.ru заявку “Заявка на согласование права использования ЕСИА и на подключение ИС к <тестовой/промышленной> ЕСИА с целью использования программных интерфейсов ЕСИА для идентификации и аутентификации заявителей”.
Форма этой заявки приведена в Регламенте взаимодействия заявителей с операторами ЕСИА (Приложение Г). Вот как это выглядело у нас. Мы в Microsoft Word создали документ и заполнили его нужными данными.
В пункте “Планируемые к использованию программные интерфейсы” мы указали следующее:
да;
скоупы:
fullname, birthdate, birthplace, email, mobile, contacts, id_doc, snils, inn;
файл сертификата:
1151593111080991181175644517328337074622.cer.
Этот заполненный документ мы отправили на адрес sd@sc.minsvyaz.ru, не забыв прикрепить к сообщению файл сертификата нашей ИС.
Кстати, нас также интересовал другой вопрос: можно ли для тестовой среды использовать сертификат/ключ, который относится к промышленной среде? В октябре 2020 мы получили по email от Федерального ситуационного центра (sd@sc.minsvyaz.ru) такой ответ: “сертификат ИС может быть использован как для тестовой, так и для продуктивной среды”.
На форуме КриптоПро некоторые пользователи говорят, что неправильно использовать промышленный сертификат в тестовой среде. Тем не менее этот вариант допустим, поэтому мы им воспользовались, чтобы не тратить время.
6. Разработка или покупка сервиса интеграции с ЕСИА
Когда администраторы ГУ открывают доступ, компании нужно подключить свою систему к ЕСИА, чтобы она могла принимать и отправлять запросы. Минцифры не позволит подключиться к промышленной среде ЕСИА, если интеграция не будет работать в тестовой среде. В нашем случае мы решили не искать стороннее решение, а написать свой коннектор к ЕСИА на языке PHP.
7. Подключение к промышленной среде ЕСИА
Когда интеграция на тестовом стенде начинает работать, можно отправлять заявку на подключение ИС к промышленной среде. Форма заявки та же, что и в п.5, но только для промышленной среды.
Вот и все шаги, выполнив которые, мы смогли, наконец, порадоваться созданной интеграции с ЕСИА. Но не все так солнечно, поскольку технически непросто реализовать сервис авторизации в п.6. Об этом расскажем дальше.
Создаем свой сервис интеграции с ЕСИА
При создании собственного сервиса нам пришлось учитывать несколько ключевых моментов.
В OpenSSL нет поддержки ГОСТ
Алгоритм ГОСТ есть в библиотеке OpenSSL. Вернее, был. Начиная с версии OpenSSL 1.1.0 gost engine был удален из основного пакета, так как недостаточно активно поддерживался (см. CHANGES.md). Это значит, что по умолчанию шифрование алгоритмом ГОСТ в openssl не доступно. Тем не менее, работа над движком ГОСТ продолжается, но уже в рамках отдельного репозитория gost-engine/engine.
Подключаемся к проду по SSH и смотрим, поддерживает ли библиотека openssl шифрование ГОСТ:
openssl ciphers | grep GOST
Если эта команда ничего не вернет, значит, поддержки ГОСТ на сервере нет. У нас так и получилось.
Мы побоялись сломать прод из-за возможных сбоев при подключении gost engine к OpenSSL. Также выяснили, что другой проект в нашем банке хочет взаимодействовать с ЕСИА. Поэтому было решено создать отдельный сервис - esia-connector.
Задачи этого сервиса:
сгенерировать ссылку, перейдя по которой, пользователь окажется на сайте Госуслуг, где нужно авторизоваться и согласиться предоставить банку свои данные;
при помощи токена запросить данные пользователя в ГУ и сохранить их в базе данных сервиса;
предоставить другим сервисам Банка доступ к этим данным. Простое REST API, которое позволит другим внутренним сервисам получить доступ к данным клиента.
Генерация секретного .pem ключа из шести файлов КриптоПро
В УЦ мы уже получили сертификат и файлы секретного ключа для нашей ИС. Файлы секретного ключа из контейнера КриптоПро представляют собой папку, в которой расположены 6 файлов с расширением .key:
header.key;
masks.key;
masks2.key;
name.key;
primary.key;
primary2.key.
Нам нужно получить из них один файл в формате .pem. Для этого мы проделали серию шагов:
скачали и распаковали .zip-файл проекта https://github.com/garex/nodejs-gost-crypto;
создали в корне этого проекта (где файл package.json) папку "keys" и поместили туда шесть файлов от КриптоПро с расширением .key;
открыли консоль и перешли в корень этого проекта;
убедились, что у нас на ПК установлен Node.js:
node -v;установили зависимости:
npm install;запустили команду на экспорт приватного ключа:
node bin/export-cryptopro-key.js -c ./keys > private-key.pem.
В итоге у нас появился файл private-key.pem. На удивление, объем его крайне мал - всего 4 строчки, например:
—----BEGIN PRIVATE KEY—----
MEgCAQFwHwYIkoUDBwEBAQwEwYHKoUDAgIkAAYIkAAYIKoUDBwEBAgIEIgQgtWkIBZW5
mUvc6UE12SuwcdsTcXXD6hqcXZPYmNcdusE=
—----END PRIVATE KEY—----
Несмотря на свой небольшой размер, он помог нам установить связь с ЕСИА.
Генерация ссылки для авторизации на портале ЕСИА
Нам нужно было как-то сгенерировать ссылку, перейдя по которой, пользователь окажется на сайте Госуслуг. Может быть, так?
<a href="https://esia.gosuslugi.ru">Авторизоваться через Госуслуги</a>
Если бы все было так просто. Вы можете перейти по этой ссылке, авторизоваться, но волшебства не случится, ведь мы не сообщаем ЕСИА, что у клиента нужно спросить разрешения поделиться своими данными с банком.
На самом деле, генерация этой ссылки - непростая задача. Лучше ее поручить сторонней библиотеке: https://github.com/fr05t1k/esia. Она поддерживает PHP 8.
Но и тут снова никаких чудес не произошло - эта библиотека просто так работать не будет. Нам нужно создать окружение, где есть openssl с поддержкой ГОСТ, а также php-fpm, nginx.
Создаем окружение при помощи Docker
Нам помог проект https://github.com/rnixik/docker-openssl-gost. Однако на момент написания этой статьи он использовал устаревшие версии библиотек. Поэтому нам пришлось самостоятельно решать, как добавить к свежей версии PHP поддержку ГОСТ. Это было непросто, но после пары недель изысканий нам это удалось.
Решение на удивление оказалось простым:
берем актуальный docker-образ PHP, к примеру php:8-fpm-bullseye;
на основе этого образа в Dockerfile делаем сборку gost-engine из ветки openssl_1_1_1;
редактируем конфиг OpenSSL, чтобы подключить gost-engine.
Проект для демонстрации интеграции с ЕСИА
Лучше один раз попробовать, чем сто раз услышать или увидеть. Мы создали тестовый проект https://github.com/yesnik/esia-mini.
Установив его, вы сами сможете подключиться к тестовому стенду ЕСИА, загрузить оттуда данные тестовой учетной записи и на практике понять, как это все работает.
Как видите, очень даже возможно добавить поддержку ГОСТ к свежему образу PHP и настроить связь с Госуслугами.
А как же КриптоПро?
Оказывается, что для связи с ЕСИА необходимо использовать сертифицированный криптопровайдер. Безопасность должна быть безопасной. Одним из таких решений является КриптоПро. Для реализации интеграции с ГУ на проде нам пришлось его приобрести. У этого решения есть свои особенности подключения к PHP, но это тема отдельной статьи. А так, для тренировки общения с тестовым стендом ЕСИА вполне подойдет наш проект.
Список источников
Документы
Комментарии (5)
murzix
07.12.2022 09:59Как решали вопрос с нормализацией сообщения в XML перед вычислением подписи при формировании пакета запроса?
yesnik Автор
08.12.2022 10:38В нашем случае мы взаимодействуем с Госуслугами при помощи json-сообщений. Вся логика формирования запросов сокрыта в используемой нами opensource библиотеке https://github.com/fr05t1k/esia
harvester
08.12.2022 11:04Спасибо за статью, оказывается я прошёл те же шаги по созданию сервиса, значит всё делал правильно, просто на тот момент не с кем было посоветоваться. Госуслуги за полгода, кажется, начали долбить письмами о переходе на гост, странно, что Вы пропустили этот поток. Openssl даже не пытался поставить, начитавшись о проблемах, сразу взял криптопро, тогда ещё 4ю версию можно было. Интересных Вам задач, удачи.
des1roer
ждем ликбез по крипто про + php + docker
yesnik Автор
Спасибо за идею. Если будет возможность, обязательно это опишем в следующей статье