Информация, не найденная в витрине esia, и интеграция с esia для большей путаницы, чем кажется

Информация, не найденная в витрине esia, и интеграция с esia для большей путаницы, чем кажется

Изменения в законодательстве, начинающие действовать с начала 2018 года и включающие в себя самые разнообразные области нашей с вами жизнедеятельности (закон о мессенджерах, о телемедицине и т.д.) объединяет одно – все большее проникновение информационных сервисов в нашу жизнь. Естественным является факт, что как и в реальной жизни, для получения человеком какой-либо услуги ему требуется пройти идентификацию. В офф-лайновой жизни средством авторизации является паспорт гражданина, а в он-лайн сфере таковым средством правительство решило признать ЕСИА — единая система идентификации и аутентификации.

Вот о ней и хотелось бы поговорить. Это ознакомительная статья, можно сказать ликбез. Для знакомства людей, которые еще не знают, что при необходимости можно использовать ЕСИА у себя в проектах и идти в ногу со временем вместе с государством. И так, что же это за зверь и как его рассматривает правительство.

Минкомсвязь России в рамках инфраструктуры электронного правительства создала и развивает Единую систему идентификации и аутентификации (ФГИС ЕСИА), цель которой — упорядочить и централизовать процессы регистрации, идентификации, аутентификации и авторизации пользователей.

1. Предоставляет информационным системам решение по достоверной идентификации пользователей (физических и юридических лиц, органов государственной власти).

Достоверность достигается за счет того, что:

  • регистрация лица в ЕСИА сопряжена с проверкой значимых для удостоверения личности критериев;
  • ЕСИА обеспечивает защиту размещённой в ней информации в соответствии с законодательством Российской Федерации.

2. Является ориентированной на пользователя и предоставляет возможности:

  • идентификации и аутентификации с использованием единой учетной записи и широкого спектра поддерживаемых методов аутентификации при доступе к различным информационным системам органов государственной власти;
  • управления своими персональными данными, размещенными в ЕСИА, и контроля над их предоставлением в информационные системы органов государственной власти.

Основные функциональные возможности ЕСИА:

  • идентификация и аутентификация пользователей, в том числе:
    • однократная аутентификация, которая дает пользователям ЕСИА следующее преимущество: пройдя процедуру идентификации и аутентификации в ЕСИА, пользователь может в течение одного сеанса работы обращаться к любым информационным системам, использующим ЕСИА, при этом повторная идентификация и аутентификация не требуется;
    • поддержка различных методов аутентификации: по паролю, по электронной подписи, а также двухфакторная аутентификация (по постоянному паролю и одноразовому паролю, высылаемому в виде sms-сообщения);
    • поддержка уровней достоверности идентификации пользователя (упрощённая учетная запись, стандартная учетная запись, подтвержденная учетная запись).
  • ведение идентификационных данных, а именно – ведение регистров физических, юридических лиц, органов и организаций, должностных лиц органов и организаций и информационных систем;
  • авторизация уполномоченных лиц органов государственной власти при доступе к следующим функциям ЕСИА:
    • ведение регистра должностных лиц органов власти в ЕСИА;
    • ведение справочника полномочий в отношении информационной системы и предоставление пользователям ЕСИА (зарегистрированным в ЕСИА как должностные лица) полномочий по доступу к ресурсам систем, зарегистрированным в ЕСИА;
    • делегирование вышеуказанных полномочий уполномоченным лицам нижестоящих органов государственной власти.
  • ведение и предоставление информации о полномочиях пользователей в отношении информационных систем, зарегистрированных в ЕСИА.

В данный момент подключить систему к ЕСИА может любая государственная организация, а также отдельные виды коммерческих организаций: страховые компании, кредитные организации (банки), профессиональные участники рынка ценных бумаг, негосударственные пенсионные фонды, микрофинансовые и микрокредитные организации, а также операторы связи.

Законодательство со временем корректируется, и вместе с ним расширяется перечень организаций, которым разрешено подключиться к ЕСИА.

Люди, не знакомые с ситуацией, при слове «государственная» сразу представляют себе каналы связи, которые необходимо защитить при помощи отечественных криптоалгоритмов со всеми вытекающими затратами, лицензиями и оборудованием. Но, как бы смешно это не было (или печально), главная площадка для идентификации в стране – работает с иностранной криптографией (а куда деваться).

Поэтому, если вы хотите воспользоваться услугами данной платформы, то можете размещать свои ресурсы где у годно в нашей огромной стране, в том числе и в нашей инфраструктуре Cloud4Y.

Что же может получить коммерческая организация из ЕСИА?

Перечень доступных к получению сведений зависит от:

  1. Категории организации, подключающейся к ЕСИА
  2. Использованного способа подключения к ЕСИА

Минкомсвязь ограничивает перечень данных, доступных коммерческим организациям. Обычно разрешают получать только сведения о ФИО, реквизитах паспорта (серия и номер, кем и когда выдан), гражданстве, а также признака «подтвержденности» аккаунта и идентификатора аккаунта в ЕСИА.

Государственные организации могут получать из ЕСИА полный набор данных о пользователе и его организациях. Это следующие сведения:

  1. личные данные (ФИО, пол, дата и место рождения, гражданство)
  2. данные идентификационных документов (СНИЛС, ИНН, общегражданский и заграничный паспорт, свидетельство о рождении, водительское удостоверение, военный билет, полис ОМС)
  3. контактная информация (email, мобильный и домашний телефон, адреса регистрации и проживания)
  4. сведения о детях (личные данные и документы)
  5. сведения о транспортных средствах (номер и свидетельство о регистрации)
  6. сведения об организациях и ИП (наименование, ОГРН, ИНН/КПП, организационно-правовая форма, юридический адрес, контакты, филиалы, списки сотрудников, полномочия сотрудников, транспортные средства организации)
  7. данные учетной записи (идентификатор аккаунта в ЕСИА, признак «подтвержденности» аккаунта)

Сведения предоставляются в том объеме, в каком они заполнены пользователем в ЕСИА, а также при условии согласия пользователя на предоставления этих сведений.

Как подключиться?

Чтобы подключить сайт своей организации, нужно пройти несколько довольно несложных процедур.

Информация, не найденная в витрине esia, и интеграция с esia для большей путаницы, чем кажется

В общих чертах для подключения к ЕСИА нужно:

  1. Убедиться, что вашей организации можно подключать свои системы к ЕСИА.
  2. Директору организации с помощью веб-приложения «Профиль ЕСИА» зарегистрировать организацию в ЕСИА.

    Информация, не найденная в витрине esia, и интеграция с esia для большей путаницы, чем кажется

    Информация, не найденная в витрине esia, и интеграция с esia для большей путаницы, чем кажется

  3. Ему также нужно прикрепить к учетной записи организации ответственного сотрудника и назначить ему право доступа в специальное приложение — Технологический портал ЕСИА. Если директор не планирует делегировать дальнейшие операции своему сотруднику, то тогда он все равно должен явно предоставить доступ себе к Технологическому порталу ЕСИА.

    Назначенному ответственному сотруднику организации нужно с помощью веб-приложения «Технологический портал ЕСИА»:

  4. Зарегистрировать учетную запись системы в ЕСИА. Мнемонику для системы придумать, либо использовать существующую мнемонику точки подключения к СМЭВ, если подключаемая к ЕСИА система раньше уже была подключена к СМЭВ.
  5. Загрузить в карточку системы ее сертификат.

    Ответственному сотруднику организации нужно:

  6. Поочередно подать по электронной почте заполненные в соответствии с регламентом заявки на использование программных интерфейсов ЕСИА в тестовой и промышленной среде.

    Информация, не найденная в витрине esia, и интеграция с esia для большей путаницы, чем кажется

    Разработчикам подключаемой системы:

  7. Доработать систему для подключения к ЕСИА, самостоятельно разработав код взаимодействия с ЕСИА в соответствии с действующим документом «Методические рекомендации по использованию ЕСИА» или использовать готовые решения, благо такие на рынке есть.
  8. Отладить взаимодействие в тестовой и промышленной среде ЕСИА.

Информация, не найденная в витрине esia, и интеграция с esia для большей путаницы, чем кажется

Здесь нужно заметить, что с 01.01.2018 г. взаимодействие по протоколу SAML 2.0 больше не будет разрешено (только для действующих систем). Для подключения к ЕСИА необходимо будет использовать протокол OAuth 2.0 / OpenID Connect (сейчас доступны оба варианта).

Аутентификация пользователя в системе

Рекомендуемый сценарий аутентификации пользователя при интеграции по OpenID Connect 1.0 в его базовом виде происходит по следующему сценарию:

  1. Пользователь нажимает на веб-странице системы-клиента кнопку «Войти через ЕСИА».
  2. Система-клиент формирует и отправляет в ЕСИА запрос на аутентификацию и перенаправляет браузер пользователя на специальную страницу предоставления доступа.
  3. ЕСИА осуществляет аутентификацию пользователя одним из доступных способов. Если пользователь ещё не зарегистрирован в ЕСИА, то он может перейти к процессу регистрации.
  4. Когда пользователь аутентифицирован, ЕСИА сообщает пользователю, что система-клиент запрашивает данные о нем в целях проведения идентификации и аутентификации, предоставляя перечень запрашиваемых системой-клиентом сведений.
  5. Если пользователь дает разрешение на проведение аутентификации системой-клиентом, то ЕСИА выдает системе-клиенту специальный авторизационный код.
  6. Система-клиент формирует в адрес ЕСИА запрос на получение маркера идентификации, включая в запрос полученный ранее авторизационный код.
  7. ЕСИА проверяет корректность запроса (например, что система-клиент зарегистрирована в ЕСИА) и авторизационного кода и передает системе-клиенту маркер идентификации.
  8. Система-клиент извлекает идентификатор пользователя из маркера идентификации. Если идентификатор получен, а маркер проверен, то система-клиент считает пользователя аутентифицированным. После получения маркера идентификации система-клиент использует REST-сервисы ЕСИА для получения дополнительных данных о пользователе, предварительно получив соответствующий маркер доступа.

Информация, не найденная в витрине esia, и интеграция с esia для большей путаницы, чем кажется

Подключаться или нет?

За операторов, в связи со вступлением в действие закона о мессенджерах данный вопрос практически решен.

Напомним, в соответствии с Федеральным законом №245 «О внесении изменений в Федеральный закон «О связи» от 29 июля 2017 года, операторы связи обязаны проверять достоверность сведений об абоненте. В законе закреплен перечень способов проверки, одним из которых является использование Единого портала государственных и муниципальных услуг или информационных систем госорганов при наличии подключения к ним у операторов через СМЭВ.

Поправки в ФЗ «О связи» вступают в силу 1 июня 2018. До этого времени операторы связи смогут протестировать работу своих систем со СМЭВ и ЕСИА.
Информация, не найденная в витрине esia, и интеграция с esia для большей путаницы, чем кажется

Становится ли чебурнет всё ближе? Официальных заявлений о планах сделать выход в Интернет возможным только через ЕСИА нами не найдено. На данный момент, по официальным данным, в ЕСИА зарегистрировано около 50 миллионов пользователей (физических лиц) и около 300 000 организаций.

Предисловие

Передо мной стояла задача по интеграции нашего сервиса с госуслугами. Казалось ничего сложного не предстоит, но учитывая что наш сервис базируется на технологии ASP.NET всё было не так оптимистично. В начале были поиски.. много поисков, которые привели к множеству разрозненной и чаще всего неактуальной информации. Так же были найдены уже готовые решения, но как заявляли некоторые товарищи на форумах за такое могут и по головке погладить. Поэтому было решено писать самому.

Эта статья скорее больше актуализация и дополнение информации из этой статьи.

Информация, не найденная в витрине esia, и интеграция с esia для большей путаницы, чем кажется

Введение

На сайте Минцифр есть методичка максимально раздутая и очень запутанная, но пользоваться ею нам всё равно придётся. Мы будем работать с ЕСИА версии 3.11 (актуальная на момент написания статьи). Кратко наши действия заключаются вот в чем:

  1. Регистрация ИС в регистре информационных систем ЕСИА

  2. Регистрация ИС в тестовой среде

  3. Выполнение доработки системы для взаимодействия с ЕСИА

Звучит довольно просто, но каждый шаг целая отдельная история приключений. Регистрация ИС в ЕСИА приключение для бюрократа. Поэтому в этой статье мы немного посмотрим на второй шаг, и детально распишем реализацию.

Всё необходимое

Наш инвентарь для путешествия:

  • Контейнер закрытого ключа с сертификатом нашей организации

Немного о КриптоПРО CSP + .Net Core 5+

Вот тут и начинаются первые проблемы. На момент написания статьи у КриптоПРО .Net нет поддержки .Net Core 5 и выше. Есть сборка под .Net Core 3.1 но и она выглядит сомнительно. Поэтому было решено поднять сервис для .Net Framework 4.8 который будет использовать средства КриптоПРО CSP для подписания с использованием <abbr title="Электронная цифровая подпись" data-title="

Больше проверок:  Выплаты за экономические последствия

Электронная цифровая подпись

” data-abbr=”ЭЦП”>ЭЦП, а так же проверки ответов от ЕСИА.

Немного о контейнере закрытого ключа и сертификата

Когда мы начинали делать эту задачу у нас была <abbr title="Квалифицированная электронная подпись" data-title="

Квалифицированная электронная подпись

” data-abbr=”КЭП”>КЭП на токене, но как оказалось на нём был неэкспортируемый контейнер. Скажу сразу, что экспортировать контейнер с такого токена запрещено ФНС. Поэтому необходимо заранее получить токен на имя сотрудника с экспортируемым контейнером. Так как его необходимо будет скопировать на сервер.

Приступаем

Кабинет тестовой среды - Технологический порталйт
Кабинет тестовой среды – Технологический порталйт

Здесь ищем нашу систему по Мнемонике или полному названию, если таковой нет то создаём. Напротив нашей системы есть две кнопки:
Первая кнопка – изменить нашу ИС (информация о ИС, редиректы и тд)
Вторая кнопка – наши сертификаты с помощью которых мы подписываем сообщения в ЕСИА

Информация, не найденная в витрине esia, и интеграция с esia для большей путаницы, чем кажется

Настройка ИС

Есть важный момент в настройки ИС. Это URL системы. Тут мы указываем ссылки куда ЕСИА может делать переадресацию при запросе от нашей ИС. На эти точки будет приходить авторизационный код (Если он указан в запросе).

Информация, не найденная в витрине esia, и интеграция с esia для большей путаницы, чем кажется

Сертификаты ИС

Информация, не найденная в витрине esia, и интеграция с esia для большей путаницы, чем кажется

Здесь мы можем загрузить наш сертификаты или же удалить их. Есть один важный момент, каждая ИС может иметь только один уникальный сертификат. А связи с тем, что на тестовой среде все системы регистрируются под одним пользователем и сертификаты тестовые одни на всех часта такая ситуация, что кто-то удаляет у вас сертификат и загружает к себе. А ваши запросы теперь падают с ошибкой) Но если у вас уже готов ЭЦП на сотудника, то лучше используйте её.

Реализуем

Устанавливаем сертификаты

Такс~ Всё готово. Качаем сертификаты по ссылке из методички. Специально не буду вставлять, так как может измениться.

Информация, не найденная в витрине esia, и интеграция с esia для большей путаницы, чем кажется

Здесь нам интересен сертификат ТЕСИА ГОСТ 2012.cer – это сертификат с помощью которого ЕСИА подписывает сообщения отправляя в нашу ИС. (Соответственно для продуктовой среды свой сертификат). Устанавливаем сертификат как доверенный. Здесь ничего сложного думаю разберётесь.

Информация, не найденная в витрине esia, и интеграция с esia для большей путаницы, чем кажется

Теперь устанавливаем тестовый контейнер и сертификат. Для примера будем использовать предоставленные ЕСИА контейнеры, но вы можете использовать свои. Всё это лежит внутри архива.

Сам архив со всеми тестовыми контейнерами
Сам архив со всеми тестовыми контейнерами
Мы возьмём именно 006 так как на него зарегистрирована наша ИС
Мы возьмём именно 006 так как на него зарегистрирована наша ИС
Информация, не найденная в витрине esia, и интеграция с esia для большей путаницы, чем кажется

Теперь открываем КриптоПРО CSP. Выбираем установить личный сертификат и указываем Тестовое ведомство Фамилия006 ИО.cer и нажимаем найти автоматически. Выполняем оставшиеся шаги сами.

Механизм подписания

Пожалуй начинается самая важная и самая запутанная часть всего пути. Здесь мы реализуем сервис для работы с подписью. И так делаю выжимку из методических материалов, чтобы Вам не пришлось читать много текста.

Для получения авторизационный ссылки – ссылка на которую мы будем переадресовывать пользователя для авторизации в ЕСИА. Нам необходимо собрать ссылку из параметров.

  1. client_id – наша Мнемоника

  2. client_secret – Отсоединённая подпись от параметров запроса в кодировке UTF-8

  3. redirect_uri – ссылка на которую ЕСИА будет переадресовывать пользователя вместе с авторизационным кодом

  4. scope – перечень запрашиваемой информации. Например fullname birthdate gender

  5. response_type – тип ответа от ЕСИА, в нашем случае это просто строчка code

  6. state – Идентификатор текущего запроса. Генерируется таким образом Guid.NewGuid().ToString("D");

  7. timestamp – время запроса авторизационного кода в формате yyyy.MM.dd HH:mm:ss Z. Генерируется таким образом DateTime.UtcNow.ToString("yyyy.MM.dd HH:mm:ss +0000");

  8. client_certificate_hash – это fingerprint сертификата в HEX-формате.

Обозначили наш зоопарк. Самый важный зверь здесь client_secret

Получаем client_certificate_hash

В методическом указании от Минцифр есть ссылка на специальную утилиту с помощью которой мы можем получить этот хэш. Разархивировали архив и видим перед нами sh. Windows пользователи не пугаемся, на самом деле тут же лежит .exe файл. Чтобы вычислить хэш нашего сертификат просто необходимо из cmd запустить вот такой скрипт:

cpverify.exe test.cer -mk -alg GR3411_2012_256 -inverted_halfbytes 0

Формирование client_secret

Такс перед тем как просто получит client_secret нам необходимо сделать:

  • ASP.Net Framework 4.8 WebAPI – тот самый сервис который будет работать с КриптоПРО CSP

Пропустим множество шагов создания этого сервиса и перейдём сразу к его настройки для работы с КриптоПРО CSP.

Настройка сервиса для работы с КриптоПРО CSP

Добавляем ссылки на DLL КриптоПРО.
Переходим по пути C:\Program Files (x86)\Crypto Pro.NET SDK\Assemblies\4.0
Выбираем всё что нам нужно. (подробная информация)

Информация, не найденная в витрине esia, и интеграция с esia для большей путаницы, чем кажется

Теперь мы имеем доступ к API КриптоПРО CSP из кода .Net Framework

Теперь создаём контроллер:

Код контроллера

Итак нам необходимо получать строку для подписания. Создадим метод

const string CertSerialNumber = "01f290e7008caed0904b967783fd0e4ad6";
const string EsiaCertSerialNumber = "0125657e00a1ae59804d92116214e53466";

[HttpGet]
public string Get(string msg)
{
    msg = Base64UrlEncoder.Decode(msg);

    var data = Encoding.UTF8.GetBytes(msg);

    var client_secret = Sign(data);

    return client_secret;
}

Мы заранее укажем константами серийные номера сертификатов.
В методе Get получаем строку в Base64Url формате, чтобы спокойно передавать наши длинные сообщения.
Декодируем строку из Base64Url в текст. После чего переводим текст в байты используя UTF-8. А теперь подписываем.

string Sign(byte[] data)
{
    var gost3411 = new Gost3411_2012_256CryptoServiceProvider();
    var hashValue = gost3411.ComputeHash(data);
    gost3411.Clear();
    var signerCert = GetSignerCert();
    var SignedHashValue = GostSignHash(hashValue,
        signerCert.PrivateKey as Gost3410_2012_256CryptoServiceProvider, "Gost3411_2012_256");
    var client_secret = Base64UrlEncoder.Encode(SignedHashValue);

    return client_secret;
}

И так что мы тут делаем. С помощью ГОСТ 34.11-2012 мы вычисляем хэш нашего сообщения. И используя полученный сертификат подписываем сообщение.

X509Certificate2 GetSignerCert()
{
    var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
    store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);
    var certificates = store.Certificates.Find(X509FindType.FindBySerialNumber, CertSerialNumber, false);

    if (certificates.Count != 1)
    {
        return null;
    }

    var certificate = certificates[0];

    if (certificate.PrivateKey == null)
    {
        return null;
    }

    return certificate;
}

Здесь мы открываем наш склад с контейнерами и ищем именно тот где лежит наш сертификат. После чего извлекаем из него сертификат.

byte[] GostSignHash(byte[] HashToSign, Gost3410_2012_256CryptoServiceProvider key, string HashAlg)
{
    try
    {
        //Создаем форматтер подписи с закрытым ключом из переданного 
        //функции криптопровайдера.
        var Formatter = new Gost2012_256SignatureFormatter(
            (Gost3410_2012_256CryptoServiceProvider) key);

        //Устанавливаем хэш-алгоритм.
        Formatter.SetHashAlgorithm(HashAlg);

        //Создаем подпись для HashValue и возвращаем ее.
        return Formatter.CreateSignature(HashToSign);
    }
    catch (CryptographicException e)
    {
        Console.WriteLine(e.Message);
        return null;
    }
}

С помощью этого кода как раз и создаётся наша подпись на хэш строки. Здесь используется ГОСТ 34.10-2012.

Итак контроллер готов. Теперь переходим в наш основной проект на .Net Core

Создаём строку подписания. Просто выполняем конкатенацию параметры без разделителей. Здесь я использую IOptions чтобы брать параметры из appsettings.json.

var msg = $"{esiaSettings.Value.ClientId}{esiaSettings.Value.Scope}{timestamp}{state}{redirectUri}";

Мы получил строку для подписания. Теперь нам необходимо эту строку закодировать в Base64Url и отправляем её на подписание в написанный нами заранее сервис

private string GetClientSecret(string msg){
  var client = new HttpClient();

  var msgBase64 = Base64UrlEncoder.Encode(msg);
  
  var response = await client.GetAsync($"{cryptoProSettings.Value.BaseUrl}/Get?msg={msgBase64}");
  
  var clientSecret = await response.Content.ReadAsStringAsync();
  
  clientSecret = JsonConvert.DeserializeObject<string>(clientSecret);
  
  return clientSecret;
}

Собираем ссылку для авторизации в Госуслугах

Наконец-то мы получили этот долгожданный секрет. Но вы могли бы подумать это всё, дальше всё просто и ясно. Не тут то было! Дело в том, что ЕСИА требует Base64 Url Safe кодироку. И она немного отличается от Base64Url кодировки доступной из коробки .Net
Итак дело за малым, собираем нашего гомункула из секрета и параметров.

Класс помощник для сборки ссылки

Возможно излишне, но мне понравился метод сбора вот таким способом.

public class RequestBuilder
{
    List<RequesItemClass> items = new List<RequesItemClass>();
    public void AddParam(string name, string value)
    {
        items.Add(new RequesItemClass { name = name, value = value });
    }
    public override string ToString()
    {
        return string.Join("&", items.Select(a => a.name + "=" + a.value));
    }
}

public class RequesItemClass
{
    public string name;
    public string value;
}
Код сборки ссылки
async Task<string> UrlBuild(string redirectUri)
{
    using var client = new HttpClient();

    var timestamp = DateTime.UtcNow.ToString("yyyy.MM.dd HH:mm:ss +0000");
    var state = Guid.NewGuid().ToString("D");

    var msg = $"{esiaSettings.Value.ClientId}{esiaSettings.Value.Scope}{timestamp}{state}{redirectUri}";

    var clientSecret = await GetClientSecret(msg);

    var builder = new RequestBuilder();
    builder.AddParam("client_secret", clientSecret);
    builder.AddParam("client_id", esiaSettings.Value.ClientId);
    builder.AddParam("scope", esiaSettings.Value.Scope);
    builder.AddParam("timestamp", timestamp);
    builder.AddParam("state", state);
    builder.AddParam("redirect_uri", redirectUri);
    builder.AddParam("client_certificate_hash", esiaSettings.Value.ClientCertificateHash);
    builder.AddParam("response_type", "code");
    builder.AddParam("access_type", "online");

    //Вот тут самый важный момент на который было потрачено множество времени. Просто заменяем символы на безопасные
    var url = esiaSettings.Value.EsiaAuthUrl + "?" + builder.ToString().Replace("+", "%2B")
        .Replace(":", "%3A")
        .Replace(" ", "+");

    return url;
}

Получаем ссылку на подобии вот такой:
Здесь https://esia-portal1.test.gosuslugi.ru/aas/oauth2/v2/ac ссылка на конечную точку получения авторизационно кода, указана в методическом материале.

https://esia-portal1.test.gosuslugi.ru/aas/oauth2/v2/ac?client_secret=v_c33_-LpkyKJbopTEYqBMbGZrBy9r9u1pzbRmMLNlJPcBnPTJj6Xx5DuxXba3EZZoXdMsb0YIwPDCoF0dfYjQ&client_id=MEMONIKA&scope=fullname+birthdate+gender&timestamp=2022.12.23+16%3A37%3A45+%2B0000&state=3a19c4d7-594b-496f-aa6e-970c75a925a4&redirect_uri=https%3A//api.site/users/esia&client_certificate_hash=EED1079A4FF154E117EAA196DCB551930807825DE1DE15EAF7607F354BA47423&response_type=code&access_type=online

Теперь перенаправляем пользователя по этой ссылке и ожидаем пока он авторизуется. После авторизации ЕСИА переадресует его на нашу ссылку и отправит туда в виде аргументов авторизационный код и state.

Получение токена доступа

Теперь время получить токен взамен на авторизационный код.

Метод для получение токена
public async Task<EsiaAuthToken> GetToken(string authorizationCode, string redirectUrl)
{
    var timestamp = DateTime.UtcNow.ToString("yyyy.MM.dd HH:mm:ss +0000");
    var state = Guid.NewGuid().ToString("D");

    var msg =
        $"{esiaSettings.Value.ClientId}{esiaSettings.Value.Scope}{timestamp}{state}{redirectUrl}{authorizationCode}";

    var clientSecret = await GetClientSecret(msg);

    var requestParams = new List<KeyValuePair<string, string>>
    {
        new KeyValuePair<string, string>("client_id", esiaSettings.Value.ClientId),
        new KeyValuePair<string, string>("code", authorizationCode), //Здесь мы передаём полученный код
        new KeyValuePair<string, string>("grant_type", "authorization_code"),  //Просто указываем тип
        new KeyValuePair<string, string>("state", state),
        new KeyValuePair<string, string>("scope", esiaSettings.Value.Scope),
        new KeyValuePair<string, string>("timestamp", timestamp),
        new KeyValuePair<string, string>("token_type", "Bearer"),  //Какой токен мы хотим получить
        new KeyValuePair<string, string>("client_secret", clientSecret),
        new KeyValuePair<string, string>("redirect_uri", redirectUrl),
        new KeyValuePair<string, string>("client_certificate_hash", esiaSettings.Value.ClientCertificateHash)
    };

    using var client = new HttpClient();
    using var response = await client.PostAsync(esiaSettings.Value.EsiaTokenUrl,
        new FormUrlEncodedContent(requestParams));
    response.EnsureSuccessStatusCode();
    var tokenResponse = await response.Content.ReadAsStringAsync();

    var token = JsonConvert.DeserializeObject<EsiaAuthToken>(tokenResponse);

    if (!await ValidatingAccessToken(token))
    {
        throw new Exception("Ошибка проверки маркера индентификации");
    }

    return token;
}

Тут всё простенько, снова генерируем client_secret указываем остальные параметры и отправляем запрос в ЕСИА на получение токена. Тестовый Uri https://esia-portal1.test.gosuslugi.ru/aas/oauth2/v3/te

Класс токена
public class EsiaAuthToken
{
    /// <summary>
    /// Токен доступа
    /// </summary>
    [JsonProperty("access_token")]
    public string AccessToken { get; set; }

    /// <summary>
    /// Идентификатор запроса
    /// </summary>
    public string State { get; set; }

    string[] parts => AccessToken.Split('.');

    /// <summary>
    /// Хранилище данных в токене
    /// </summary>
    public EsiaAuthTokenPayload Payload
    {
        get
        {
            if (string.IsNullOrEmpty(AccessToken))
            {
                return null;
            }

            if (parts.Length < 2)
            {
                throw new Exception($"При расшифровке токена доступа произошла ошибка. Токен: {AccessToken}");
            }

            var payload = Encoding.UTF8.GetString(Base64UrlEncoder.DecodeBytes(parts[1]));
            return JsonConvert.DeserializeObject<EsiaAuthTokenPayload>(payload);
        }
    }

    /// <summary>
    /// Сообщение для проверки подписи
    /// </summary>
    [Newtonsoft.Json.JsonIgnore]
    public string Message
    {
        get
        {
            if (string.IsNullOrEmpty(AccessToken))
            {
                return null;
            }

            if (parts.Length < 2)
            {
                throw new Exception($"При расшифровке токена доступа произошла ошибка. Токен: {AccessToken}");
            }

            return parts[0] + "." + parts[1];
        }
    }

    /// <summary>
    /// Сигнатура подписи
    /// </summary>
    [Newtonsoft.Json.JsonIgnore]
    public string Signature
    {
        get
        {
            if (string.IsNullOrEmpty(AccessToken))
            {
                return null;
            }

            if (parts.Length < 2)
            {
                throw new Exception($"При расшифровке токена доступа произошла ошибка. Токен: {AccessToken}");
            }

            return parts[2];
        }
    }

    public class EsiaAuthTokenPayload
    {
        [JsonConstructor]
        public EsiaAuthTokenPayload(string tokenId, string userId, string nbf, string exp, string iat, string iss,
            string client_id)
        {
            TokenId = tokenId;
            UserId = userId;
            BeginDate = EsiaHelper.DateFromUnixSeconds(double.Parse(nbf));
            ExpireDate = EsiaHelper.DateFromUnixSeconds(double.Parse(exp));
            CreateDate = EsiaHelper.DateFromUnixSeconds(double.Parse(iat));
            Iss = iss;
            ClientId = client_id;
        }

        /// <summary>
        /// Идентификатор токена
        /// </summary>
        [JsonProperty("urn:esia:sid")]
        public string TokenId { get; private set; }

        /// <summary>
        /// Идентификатор пользователя
        /// </summary>
        [JsonProperty("urn:esia:sbj_id")]
        public string UserId { get; private set; }

        /// <summary>
        /// Время начала действия токена
        /// </summary>
        [JsonPropertyName("nbf")]
        public DateTime BeginDate { get; private set; }

        /// <summary>
        /// Время окончания действия токена
        /// </summary>
        [JsonPropertyName("exp")]
        public DateTime ExpireDate { get; private set; }

        /// <summary>
        /// Время выпуска токена
        /// </summary>
        [JsonPropertyName("iat")]
        public DateTime CreateDate { get; private set; }

        /// <summary>
        /// Организация, выпустившая маркер
        /// </summary>
        [JsonPropertyName("iss")]
        public string Iss { get; private set; }

        /// <summary>
        /// Адресат маркера
        /// </summary>
        [JsonPropertyName("client_id")]
        public string ClientId { get; private set; }
    }
  }

  public static class EsiaHelper
  {
      public static DateTime DateFromUnixSeconds(double seconds)
      {
          var date = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);

          return date.AddSeconds(seconds).ToLocalTime();
      }
  }

Проверка токена

Итак помимо того, что нам нужно получить токен, нам так же необходимо проверить его.

Больше проверок:  Проверка правильности реестра

Сам токен состоит из 3 частей.
1 часть – заголовок JWT токена
2 часть – payload токена, там вся основная информация о токене
3 часть – RAW подпись в формате UTF-8

Код конечной точки для проверки подписи
[HttpPost]
public bool Verify(VerifyMessage message)
{
    try
    {
        return VerifyRawSignString(message.Message, message.Signature);
    }
    catch (Exception ex)
    {
        return false;
    }
}

public class VerifyMessage
{
    public string Signature { get; set; }
    public string Message { get; set; }
}
Код проверки подписи на нашем сервисе
/// <summary>
/// Проверка подписи JWT в формате HEADER.PAYLOAD.SIGNATURE.
/// </summary>
/// <param name="message">HEADER.PAYLOAD в формате Base64url</param>
/// <param name="signature">SIGNATURE в формате Base64url</param>
bool VerifyRawSignString(string message, string signature)
{
    var signerCert = GetEsiaSignerCert();

    var messageBytes = Encoding.UTF8.GetBytes(message);
    var signatureBytes = Base64UrlEncoder.DecodeBytes(signature);
    //Переварачиваем байты, так как используется RAW подпись
    Array.Reverse(signatureBytes, 0, signatureBytes.Length);

    using (var GostHash = new Gost3411_2012_256CryptoServiceProvider())
    {
        var csp = (Gost3410_2012_256CryptoServiceProvider) signerCert.PublicKey.Key;
        //Используем публичный ключ сертификата для проверки  
        return csp.VerifyData(messageBytes, GostHash, signatureBytes);
    }
}
Код получения сертификата ЕСИА
X509Certificate2 GetEsiaSignerCert()
{
    var store = new X509Store(StoreName.AddressBook, StoreLocation.CurrentUser);
    store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);
    var certificates = store.Certificates.Find(X509FindType.FindBySerialNumber, EsiaCertSerialNumber, false);

    var certificate = certificates[0];

    return certificate;
}

Здесь используем введённые ранее константы. И Получаем сертификат из доверенных сертификатов.

Отправка токена на проверку
public async Task<bool> ValidatingAccessToken(EsiaAuthToken token)
{
    if (token.Payload.ExpireDate <= DateTime.Now ||
        token.Payload.BeginDate >= DateTime.Now ||
        token.Payload.CreateDate >= DateTime.Now ||
        token.Payload.ExpireDate <= token.Payload.BeginDate ||
        token.Payload.CreateDate > token.Payload.BeginDate ||
        token.Payload.CreateDate > token.Payload.ExpireDate ||
        token.Payload.Iss != esiaSettings.Value.ISS ||
        token.Payload.ClientId != esiaSettings.Value.ClientId)
    {
        return false;
    }

    var client = new HttpClient();

    var requestParams = new List<KeyValuePair<string, string>>
    {
        new KeyValuePair<string, string>("signature", token.Signature),
        new KeyValuePair<string, string>("message", token.Message)
    };

    var response = await client.PostAsync($"{cryptoProSettings.Value.BaseUrl}/Verify",
        new FormUrlEncodedContent(requestParams));

    response.EnsureSuccessStatusCode();
    var resultResponse = await response.Content.ReadAsStringAsync();

    var result = JsonConvert.DeserializeObject<bool>(resultResponse);

    return result;
}

Этот код используем в нашем основном сервисе.
Проверяем поля токена на актуальность, чтобы его не могли подделать. А потом уже проверяем подпись токена, как указано в методических указаниях.

Получение данных пользователя из ЕСИА

public async Task<EsiaUser> ExecuteAsync(string esiaUserId, string accessToken)
{
    using (var client = new HttpClient())
    {
        client.DefaultRequestHeaders.Clear();
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);

        var response = await client.GetStringAsync($"{esiaSettings.Value.EsiaRestUrl}/prns/{esiaUserId}");
        var user = JsonConvert.DeserializeObject<EsiaUser>(response);
        user.Id = user.Id ?? esiaUserId;

        return user;
    }
}
Код класса EsiaUser
public class EsiaUser
{
    /// <summary>
    /// Идентификатор
    /// </summary>
    [JsonProperty("oid")]
    public string Id { get; set; }

    /// <summary>
    /// Фамилия
    /// </summary>
    [JsonProperty("firstName")]
    public string FirstName { get; set; }

    /// <summary>
    /// Имя
    /// </summary>
    [JsonProperty("lastName")]
    public string LastName { get; set; }

    /// <summary>
    /// Отчество
    /// </summary>
    [JsonProperty("middleName")]
    public string MiddleName { get; set; }

    /// <summary>
    /// Дата рождения
    /// </summary>
    [JsonProperty("birthdate")]
    public string Birthdate { get; set; }

    /// <summary>
    /// Пол
    /// </summary>
    [JsonProperty("gender")]
    public string Gender { get; set; }

    /// <summary>
    /// Подтвержден ли пользователь
    /// </summary>
    [JsonProperty("trusted")]
    public bool Trusted { get; set; }
}

Заключение

Наконец мы закончили интеграцию с ЕСИА. Это был длинный путь полный странных вещей. Неясных решений и множество потраченного времени. Надеюсь этой статьёй я помог Вам реализовать задачу интеграции гораздо быстрее и легче. Спасибо за потраченное время.

Просмотры

Привет, меня зовут Никита Нятин. Я главный разработчик PHP в Уральском банке реконструкции и развития. Расскажу, как мы в банке внедряли интеграцию с Единой системой идентификации и аутентификации (ЕСИА) на PHP и какие проблемы пришлось решать.

Информация, не найденная в витрине esia, и интеграция с esia для большей путаницы, чем кажется

Зарождение идеи

В УБРиР есть сервис посадочных страниц, позволяющий клиентам оставлять заявки на кредит, вклад и РКО. В 2019 году у нас возникла идея упростить процесс заполнения заявки на кредит. Зачем клиенту указывать ФИО, адрес регистрации, если все эти сведения уже есть на сайте Госуслуг (ГУ), который также называют ЕСИА.

Информация, не найденная в витрине esia, и интеграция с esia для большей путаницы, чем кажется

Как это работает: глазами клиента

Информация, не найденная в витрине esia, и интеграция с esia для большей путаницы, чем кажется

После успешной авторизации нужно дать согласие на передачу своих данных ПАО КБ УБРиР.

Информация, не найденная в витрине esia, и интеграция с esia для большей путаницы, чем кажется

Когда согласие дано, клиент перенаправляется обратно на посадочную страницу, где уже заполнены ФИО и паспортные данные, полученные от сайта ГУ. Остается только убедиться, что все верно, и отправить заявку.

Неожиданная поломка

Первая версия интеграции была написана в 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. Этот сертификат нужно загрузить в карточку ИС на Техпортале.

Кстати, если открыть сертификат в текстовом редакторе, то там может оказаться абракадабра:

Информация, не найденная в витрине esia, и интеграция с esia для большей путаницы, чем кажется

Это значит, что сертификат в бинарном формате. Если кликнуть по файлу сертификата в ОС Windows, появится диалоговое окно, в котором его можно преобразовать в другой формат – в X.509 (.CER) в кодировке Base-64:

Информация, не найденная в витрине esia, и интеграция с esia для большей путаницы, чем кажется
Информация, не найденная в витрине esia, и интеграция с esia для большей путаницы, чем кажется

Полученный файл сертификата можно открыть в текстовом редакторе и увидеть цифры и латинские буквы между “——BEGIN CERTIFICATE—–” и “—–END CERTIFICATE—–”. Это значит, что сертификат в кодировке base64.

Информация, не найденная в витрине esia, и интеграция с esia для большей путаницы, чем кажется

Закрытый ключ представляет собой папку с 6 файлами с расширением .key из контейнера КриптоПро:

Эти файлы понадобятся на сервере приложения при настройке интеграции с ЕСИА.

5. Подключение к тестовой среде ЕСИА

Форма этой заявки приведена в Регламенте взаимодействия заявителей с операторами ЕСИА (Приложение Г). Вот как это выглядело у нас. Мы в Microsoft Word создали документ и заполнили его нужными данными.

Информация, не найденная в витрине esia, и интеграция с esia для большей путаницы, чем кажется

В пункте “Планируемые к использованию программные интерфейсы” мы указали следующее: 

  • скоупы: fullname, birthdate, birthplace, email, mobile, contacts, id_doc, snils, inn;

  • файл сертификата: 1151593111080991181175644517328337074622.cer.

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

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.

Задачи этого сервиса:

  1. сгенерировать ссылку, перейдя по которой, пользователь окажется на сайте Госуслуг, где нужно авторизоваться и согласиться предоставить банку свои данные;

  2. при помощи токена запросить данные пользователя в ГУ и сохранить их в базе данных сервиса;

  3. предоставить другим сервисам Банка доступ к этим данным. Простое REST API, которое позволит другим внутренним сервисам получить доступ к данным клиента.

Генерация секретного .pem ключа из шести файлов КриптоПро

В УЦ мы уже получили сертификат и файлы секретного ключа для нашей ИС. Файлы секретного ключа из контейнера КриптоПро представляют собой папку, в которой расположены 6 файлов с расширением .key:

Нам нужно получить из них один файл в формате .pem. Для этого мы проделали серию шагов:

  1. скачали и распаковали .zip-файл проекта https://github.com/garex/nodejs-gost-crypto;

  2. создали в корне этого проекта (где файл package.json) папку “keys” и поместили туда шесть файлов от КриптоПро с расширением .key;

  3. открыли консоль и перешли в корень этого проекта;

  4. убедились, что у нас на ПК установлен Node.js:
    node -v;

  5. установили зависимости:
    npm install;

  6. запустили команду на экспорт приватного ключа:
    node bin/export-cryptopro-key.js -c ./keys > private-key.pem.

В итоге у нас появился файл private-key.pem. На удивление, объем его крайне мал – всего 4 строчки, например:

—----BEGIN PRIVATE KEY—----
MEgCAQFwHwYIkoUDBwEBAQwEwYHKoUDAgIkAAYIkAAYIKoUDBwEBAgIEIgQgtWkIBZW5
mUvc6UE12SuwcdsTcXXD6hqcXZPYmNcdusE=
—----END PRIVATE KEY—----

Несмотря на свой небольшой размер, он помог нам установить связь с ЕСИА.

Генерация ссылки для авторизации на портале ЕСИА

Нам нужно было как-то сгенерировать ссылку, перейдя по которой, пользователь окажется на сайте Госуслуг. Может быть, так?

<a data-hren="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 поддержку ГОСТ. Это было непросто, но после пары недель изысканий нам это удалось.

Решение на удивление оказалось простым:

  1. берем актуальный docker-образ PHP, к примеру php:8-fpm-bullseye;

  2. на основе этого образа в Dockerfile делаем сборку gost-engine из ветки openssl_1_1_1;

  3. редактируем конфиг OpenSSL, чтобы подключить gost-engine.

Проект для демонстрации интеграции с ЕСИА

Лучше один раз попробовать, чем сто раз услышать или увидеть. Мы создали тестовый проект https://github.com/yesnik/esia-mini

Установив его, вы сами сможете подключиться к тестовому стенду ЕСИА, загрузить оттуда данные тестовой учетной записи и на практике понять, как это все работает.

Как видите, очень даже возможно добавить поддержку ГОСТ к свежему образу PHP и настроить связь с Госуслугами.

А как же КриптоПро?

Оказывается, что для связи с ЕСИА необходимо использовать сертифицированный криптопровайдер. Безопасность должна быть безопасной. Одним из таких решений является КриптоПро. Для реализации интеграции с ГУ на проде нам пришлось его приобрести. У этого решения есть свои особенности подключения к PHP, но это тема отдельной статьи. А так, для тренировки общения с тестовым стендом ЕСИА вполне подойдет наш проект.

Список источников

Документы

Система ЕСИА часто ассоциируется с порталом Госуслуги, но технически это не одно и то же. Однако регистрация в ЕСИА — это, по сути, регистрация на Госуслугах, поэтому учётная запись на портале идентична учётной записи в ЕСИА и содержит одинаковые персональные данные пользователя.

В то же время с помощью учётной записи в единой системе идентификации можно получить доступ не только к порталу госуслуг, но и другим государственным и муниципальным системам. Более того, многие коммерческие сайты и порталы в последнее время активно используют для регистрации на ресурсах и (или) доступа к их функциям авторизацию посредством ЕСИА. Это быстро и удобно. Учётная запись в ЕСИА, таким образом, служит надёжным и безопасным средством проверки персональных данных и идентификации конкретного лица.

В целом система ЕСИА служит для:

  1. Создания физическими лицами, ИП или юридическими лицами единой учётной записи, которая даёт доступ к различным информационным системам, сайтам и порталам, использующим такой способ регистрации, авторизации и (или) идентификации пользователя.
  2. Взаимодействия различных информационных систем на уровне средств подтверждения личности пользователя (идентификации), проверки его данных (аутентификации) и предоставления разрешения на доступ (авторизации).
  3. Авторизации пользователей на государственных, региональных и муниципальных ресурсах для получения соответствующих услуг в электронном виде. Например, для запроса и получения информации, справок, оформления документов, совершения регистрационных действий, записи на приём в то или иное ведомство.
  4. Авторизации пользователей на негосударственных ресурсах (сайтах, порталах, системах), которые подключены к ЕСИА и используют учётные записи в этой системе (с согласия их владельцев) для разрешения доступа.

Как работает ЕСИА

Чтобы получить доступ ко всем возможностям учётной записи ЕСИА, нужно подтвердить личность. Проще всего это сделать через партнёров оператора единой системы идентификации. Например, клиенты Сбербанка могут пройти идентификацию по СберID в режиме онлайн. Подобные сервисы есть и у других банков-партнёров. Подтвердить личность дистанционно также можно с помощью квалифицированной электронной подписи. Если эти варианты недоступны, то идентификацию проходят в центрах обслуживания (нужен паспорт и СНИЛС). Ближайший офис можно найти на карте на портале Госуслуги. И ещё один вариант — заказать в личном кабинете код подтверждения, который придёт заказным письмом Почтой России.

Получите сертификат ЭЦП

Пройдите идентификацию и получите сертификат удалённо с помощью смартфона и биометрического загранпаспорта.

Получить консультацию по оформлению электронной подписи
Облако – лого
Облако – лого

Процесс взаимодействия ЕСИА при авторизации пользователей в различных системах выглядит так:

  1. Пользователь хочет получить доступ к какой-либо информационной системе (ресурсу), которая использует авторизацию через ЕСИА, и выбирает этот способ.
  2. Ресурс направляет в ЕСИА соответствующий электронный запрос.
  3. Для подтверждения подлинности пользователя система перенаправляет его с ресурса на свою страницу входа в систему. Если вход прошёл успешно, система запрашивает у пользователя разрешение на предоставление ресурсу доступа к личным данным.
  4. Если пользователь был успешно проверен и разрешил стороннему ресурсу доступ к своим данным, система передаёт ресурсу необходимую информацию для авторизации пользователя.
  5. После поступления данных ресурс даёт пользователю доступ в свою систему.

На практике весь процесс занимает несколько секунд.

Как организации подключиться к ЕСИА

Юридические лица подключаются к ЕСИА через личный кабинет руководителя. Для подключения используется функция «Добавить организацию» и выбирается необходимый статус: ИП, организация, орган власти.

Для формирования учётной записи юридического лица необходимо, чтобы у руководителя была подтвержденная учётная запись. Для подключения к системе используется квалифицированная электронная подпись, сертификат которой оформлен на руководителя.

При регистрации юрлица потребуется заполнить все данные об организации, указанные в регистрационной форме. После проверки сведений и их подтверждения (это делается в автоматическом режиме) будет создана учётная запись организации в ЕСИА.

Дополнительная возможность для учётных записей организаций — подключение авторизации пользователей через ЕСИА для доступа к сайту или другому интернет-ресурсу организации. Для этого нужно предоставить сведения о подключаемой системе, при необходимости доработать её под требования ЕСИА, запустить работу подключённой системы в тестовом режиме, а после подтверждения работоспособности — в рабочем режиме.

Чтобы получить электронную подпись, оставьте заявку. Наши специалисты помогут вам оформить электронную подпись для физических и юридических лиц — удалённо, быстро и по выгодной цене.

идентификация
идентификация

Обучающий материал «Подтверждение учетной записи в Единой системе идентификации и аутентификации» появился на сайте Министерства связи и массовых коммуникаций РФ.

Он предназначен для госслужащих, ответственных за подтверждение учетных записей граждан, самостоятельно созданных последними на сайте gosuslugi.ru.

В небольшой pdf-презентации рассказывается, как найти учетную запись клиента, как подтвердить личность пользователя, куда обратиться при возникновении ошибок в процессе работы в приложении и т.д.

Кроме скриншотов системы «Центр регистрации» с пошаговыми инструкциями, пособие приводит стандартные фразы, которые оператор должен произносить в той или иной ситуации. Особенно трогательно выглядят указания в скобках: «Обратитесь к Клиенту по Имени Отчеству».

По всей видимости, презентация создана для обучения сотрудников МФЦ и «Почты России», в офисах которой, как сообщал D-Russia.ru, открываются пункты подтверждения личности граждан.

Скриншот обучающего материала «Подтверждение учетной записи в Единой системе идентификации и аутентификации»
Скриншот обучающего материала «Подтверждение учетной записи в Единой системе идентификации и аутентификации»

Следите за нашим Телеграм-каналом, чтобы не пропускать самое важное!

Поделиться: