Привет, меня зовут Никита Нятин. Я главный разработчик PHP в Уральском банке реконструкции и развития. Расскажу, как мы в банке внедряли интеграцию с Единой системой идентификации и аутентификации (ЕСИА) на PHP и какие проблемы пришлось решать.
![](https://habrastorage.org/getpro/habr/upload_files/2cd/2a4/638/2cd2a4638ee81b8b65938e6afece142e.jpg)
Зарождение идеи
В УБРиР есть сервис посадочных страниц, позволяющий клиентам оставлять заявки на кредит, вклад и РКО. В 2019 году у нас возникла идея упростить процесс заполнения заявки на кредит. Зачем клиенту указывать ФИО, адрес регистрации, если все эти сведения уже есть на сайте Госуслуг (ГУ), который также называют ЕСИА.
![](https://habrastorage.org/getpro/habr/upload_files/1b8/de2/2e9/1b8de22e92ffaa6e1302002b6b2462e4.png)
Как это работает: глазами клиента
Клиент нажимает на кнопку “Авторизоваться через Госуслуги”, после чего система его перенаправляет на сайт https://esia.gosuslugi.ru. Там клиента просят авторизоваться, указав свои логин и пароль от учетной записи.
![](https://habrastorage.org/getpro/habr/upload_files/a3a/5be/46a/a3a5be46a848345bdf617be67f557960.png)
После успешной авторизации нужно дать согласие на передачу своих данных ПАО КБ УБРиР.
![](https://habrastorage.org/getpro/habr/upload_files/248/d14/ffb/248d14ffb82b80d78f750758f518ff9b.png)
Когда согласие дано, клиент перенаправляется обратно на посадочную страницу, где уже заполнены ФИО и паспортные данные, полученные от сайта ГУ. Остается только убедиться, что все верно, и отправить заявку.
Неожиданная поломка
Первая версия интеграции была написана в 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. Этот сертификат нужно загрузить в карточку ИС на Техпортале.
Кстати, если открыть сертификат в текстовом редакторе, то там может оказаться абракадабра:
![](https://habrastorage.org/getpro/habr/upload_files/4a3/74e/81b/4a374e81b20bf9b3a099c4b481dd4cd0.png)
Это значит, что сертификат в бинарном формате. Если кликнуть по файлу сертификата в ОС Windows, появится диалоговое окно, в котором его можно преобразовать в другой формат - в X.509 (.CER) в кодировке Base-64:
![](https://habrastorage.org/getpro/habr/upload_files/cdc/9ac/85b/cdc9ac85bf8954edd2d498b72ac6abe8.png)
![](https://habrastorage.org/getpro/habr/upload_files/f83/45b/899/f8345b89929e30e6b79cfc2268b38f9f.png)
Полученный файл сертификата можно открыть в текстовом редакторе и увидеть цифры и латинские буквы между “------BEGIN CERTIFICATE—--” и “-----END CERTIFICATE—--”. Это значит, что сертификат в кодировке base64.
![](https://habrastorage.org/getpro/habr/upload_files/26f/76d/4a0/26f76d4a026e93c6adecd470557b8d32.png)
Закрытый ключ представляет собой папку с 6 файлами с расширением .key из контейнера КриптоПро:
header.key;
masks.key;
masks2.key;
name.key;
primary.key;
primary2.key.
Эти файлы понадобятся на сервере приложения при настройке интеграции с ЕСИА.
5. Подключение к тестовой среде ЕСИА
На этом этапе нужно отправить на адрес sd@sc.minsvyaz.ru заявку “Заявка на согласование права использования ЕСИА и на подключение ИС к <тестовой/промышленной> ЕСИА с целью использования программных интерфейсов ЕСИА для идентификации и аутентификации заявителей”.
Форма этой заявки приведена в Регламенте взаимодействия заявителей с операторами ЕСИА (Приложение Г). Вот как это выглядело у нас. Мы в Microsoft Word создали документ и заполнили его нужными данными.
![](https://habrastorage.org/getpro/habr/upload_files/c56/7c9/bb0/c567c9bb05fd25ffc6dc97401b6f9c33.png)
В пункте “Планируемые к использованию программные интерфейсы” мы указали следующее:
да;
скоупы:
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 Автор
Спасибо за идею. Если будет возможность, обязательно это опишем в следующей статье