ИНТЕГРАЦИЯ PHP ESIA

ИНТЕГРАЦИЯ PHP ESIA pos gosuslugi

Время на прочтение

Привет, Хабр! В одном из постов блога мой коллега Иван писал

о нашем блокчейн-сервисе для онлайн-голосований WE. Vote. Он подробно разобрал, как работает WE. Vote с точки зрения технологий. Но чтобы сервисы удаленного голосования можно было использовать для принятия официальных решений юрлиц, не хватает еще одного важного компонента — достоверной верификации участников. В России для этого можно провести интеграцию с ЕСИА (Единой Системой Идентификации и Аутентификации) — проще говоря, с Госуслугами. Интеграция эта заметно отличается от интеграции с другими OAuth2-сервисами, как, например, Google или VK. В этом посте мы постараемся помочь тем, кто захочет интегрировать ЕСИА в свой сервис через стек, подобный нашему, а также дадим несколько полезных ссылок по ЕСИА в принципе.

ИНТЕГРАЦИЯ PHP ESIA
Содержание
  1. Зачем нам ЕСИА?
  2. Стек и схема интеграции
  3. Формирование подписи
  4. Создание ссылки для редиректа на страницу ЕСИА
  5. Получение авторизационного токена ЕСИА
  6. Запрос токена идентификации
  7. Получение данных о пользователе
  8. Полезные материалы по теме
  9. Как работает ЕСИА
  10. Получите сертификат
  11. Как организации подключиться к ЕСИА
  12. Зарождение идеи
  13. Как это работает: глазами клиента
  14. Неожиданная поломка
  15. Как подключить сайт компании к ЕСИА
  16. 1. Регистрация руководителя организации на Госуслугах 
  17. 2. Регистрация компании на Госуслугах 
  18. 3. Регистрация информационной системы на технологическом портале Госуслуг
  19. 4. Получение сертификата и закрытого ключа для новой ИС
  20. 5. Подключение к тестовой среде ЕСИА
  21. 6. Разработка или покупка сервиса интеграции с ЕСИА
  22. 7. Подключение к промышленной среде ЕСИА
  23. Создаем свой сервис интеграции с ЕСИА
  24. В OpenSSL нет поддержки ГОСТ
  25. Генерация секретного .pem ключа из шести файлов КриптоПро
  26. Генерация ссылки для авторизации на портале ЕСИА
  27. Создаем окружение при помощи Docker
  28. Проект для демонстрации интеграции с ЕСИА
  29. А как же КриптоПро?
  30. Список источников
  31. Документы

Зачем нам ЕСИА?

Согласно Федеральному закону № 225-ФЗ

от 28.06.2021 «О внесении изменений в часть первую Гражданского кодекса Российской Федерации», многие организаций в РФ получили право проводить официальные собрания и голосования по корпоративным вопросам дистанционно.

Ранее решения с юридической силой требовали очных собраний или голосований по почте. Голосования по почте не отличаются надежностью, а собрать много руководителей со всей России в одном месте — это кошмар с точки зрения затрат.

Чтобы проводить мероприятия принятия решения дистанционно в соответствии с новым федеральным законом, необходимо предоставить возможность достоверного установления личности участников. В России это возможно через проверку доступа к верифицированному аккаунту на Госуслугах.

Стек и схема интеграции

Для интеграции мы используем:

  • Typescript, ReactJS, NestJS

  • КриптоПро CSP 4

Схема интеграции
Схема интеграции

Формирование подписи

Прежде чем разбирать все по порядку, кое о чем стоит подумать заранее. В отличие от других интеграций, запросы к ЕСИА должны сопровождаться подписью ГОСТ Р 34.10/11-2012, а не просто API key. Создать такую подпись можно с помощью утилиты КриптоПро CSP

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

. Инструкция по запуску есть в README.md.

В процесс сборки Docker образа сервиса с утилитой КриптоПро мы встроили:

  • Установку утилиты КриптоПро СSP 4 из .deb пакета

  • Установку лицензии КриптоПро

  • Загрузку корневого сертификата тестовой или основной среды ЕСИА

  • Загрузку пользовательского сертификата с PIN кодом

  • REST-сервер с методом, позволяющим создавать подписи

Таким образом вся криптография собрана в отдельном самостоятельном компоненте, который можно использовать, когда необходимо что-нибудь подписать. Вот как это выглядит на бэкенде:

   private async signParams(params: Record<string, string>) {
 const time = moment().format('YYYY.MM.DD HH:mm:ss ZZ')
 const state = uuid()
 const clientId = this.clientId
 const scope = this.scope

 const { data: { result: clientSecret } } = await axios.post<{ result: string }>(
   `${this.cryptoProServiceAddress}/cryptopro/sign`,
   { text: [scope, time, clientId, state].join('') },
 )

 return {
   ...params,
   timestamp: time,
   client_id: clientId,
   scope,
   state,
   client_secret: clientSecret.replace(/\n/g, ''),
 }
}  
  

С созданием подписей разобрались, теперь последовательно разберем, как реализовать схему выше.

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

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

   async getAuthLink(redirectLink: string) {
 const params = await this.signParams({
   redirect_uri: redirectLink,
   response_type: 'code',
   access_type: 'offline',
 })
 const authQuery = new URLSearchParams(params)
 const authURL = `${this.esiaHost}/aas/oauth2/ac`
 return `${authURL}?${authQuery}`
}  
  

В redirectLink
необходимо указать адрес страницы, на которую ЕСИА перенаправит пользователя после успешной аутентификации. Созданную ссылку возвращаем на фронтенд и перенаправляем на нее пользователя.

Получение авторизационного токена ЕСИА

Запрос токена идентификации

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

   async getTokens(code: string) {
 try {
   const params = await this.signParams({
     grant_type: 'authorization_code',
     token_type: 'Bearer',
     redirect_uri: 'no',
     code,
   })
   const authURL = `${this.host}/aas/oauth2/te`
   const authQuery = new URLSearchParams(params)
   const { data: tokens } = await axios.post(`${authURL}?${authQuery}`)
   return {
     idToken: tokens.id_token,
     accessToken: tokens.access_token,
     refreshToken: tokens.refresh_token,
   }
 } catch (e) {
   const status = e.response ? e.response.status : 500
   const message = e.response ? e.response.data.error_description : e.message
   throw new HttpException('Failed to get auth tokens: ' + message, status)
 }
}  
  

Получение данных о пользователе

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

   getUserIdFromToken(idToken: string) {
 const decodedIdToken = verify(idToken, this.esiaPublicKey, {
   algorithms: ['RS256'],
   audience: 'WE_VOTE',
 }) as EsiaParsedToken
 return decodedIdToken['urn:esia:sbj']['urn:esia:sbj:oid']
}

async getUserInfo(tokens: EsiaTokens) {

 const { idToken, accessToken } = tokens
 const oId = this.getUserIdFromToken(idToken)

 const [{ data: mainInfo }, { data: contactsInfo }] = await Promise.all([
   axios.get(`${this.esiaHost}/rs/prns/${oId}`, {
     headers: {
       Authorization: `Bearer ${accessToken}`,
     },
   }),
   axios.get(`${this.esiaHost}/rs/prns/${oId}/ctts?embed=(elements)`, {
     headers: {
       Authorization: `Bearer ${accessToken}`,
     },
   }),
 ])

 const email = contactsInfo.elements.find(({ type }: { type: string }) => type === 'EML')

 return {
   id: oId,
   firstName: mainInfo.firstName,
   lastName: mainInfo.lastName,
   surName: mainInfo.middleName,
   trusted: mainInfo.trusted,
   email: email ? {
     value: email.value.toLowerCase(),
     verified: email.vrfStu === 'VERIFIED',
   } : null,
 }
}  
  

На этом шаге мы уже имеем все необходимые данные о пользователе. Остается только занести их в свою систему и закончить авторизацию.

Полный код интеграционного модуля на бэкенде
   import { HttpException } from '@nestjs/common'
import * as moment from 'moment'
import { v4 as uuid } from 'uuid'
import { URLSearchParams } from 'url'
import axios from 'axios'
import { verify } from 'jsonwebtoken'

type EsiaTokens = {
 idToken: string,
 accessToken: string,
}

type EsiaParsedToken = {
 'urn:esia:sbj': {
   'urn:esia:sbj:oid': string,
 },
}

export class EsiaApiService {
 private readonly clientId = 'WE_VOTE'
 private readonly scope = ['openid', 'email', 'fullname'].join(' ')

 constructor(
   private readonly esiaHost: string, // 'https://esia-portal1.test.gosuslugi.ru' или 'https://esia.gosuslugi.ru'
   private readonly esiaPublicKey: string, // можно взять из http://esia.gosuslugi.ru/public/esia.zip
   private readonly cryptoProServiceAddress: string, // адрес сервиса по созданию подписей e.g 'http://127.0.0.1:3037'
 ) {
 }

 async getAuthLink(redirectLink: string) {
   const params = await this.signParams({
     redirect_uri: redirectLink,
     response_type: 'code',
     access_type: 'offline',
   })
   const authQuery = new URLSearchParams(params)
   const authURL = `${this.esiaHost}/aas/oauth2/ac`
   return `${authURL}?${authQuery}`
 }

 private async signParams(params: Record<string, string>) {
   const time = moment().format('YYYY.MM.DD HH:mm:ss ZZ')
   const state = uuid()
   const clientId = this.clientId
   const scope = this.scope

   const { data: { result: clientSecret } } = await axios.post<{ result: string }>(
     `${this.cryptoProServiceAddress}/cryptopro/sign`,
     { text: [scope, time, clientId, state].join('') },
   )

   return {
     ...params,
     timestamp: time,
     client_id: clientId,
     scope,
     state,
     client_secret: clientSecret.replace(/\n/g, ''),
   }
 }

 async getTokens(code: string) {
   try {
     const params = await this.signParams({
       grant_type: 'authorization_code',
       token_type: 'Bearer',
       redirect_uri: 'no',
       code,
     })
     const authURL = `${this.esiaHost}/aas/oauth2/te`
     const authQuery = new URLSearchParams(params)
     const { data: tokens } = await axios.post(`${authURL}?${authQuery}`)
     return {
       idToken: tokens.id_token,
       accessToken: tokens.access_token,
       refreshToken: tokens.refresh_token,
     }
   } catch (e) {
     const status = e.response ? e.response.status : 500
     const message = e.response ? e.response.data.error_description : e.message
     throw new HttpException('Failed to get auth tokens: ' + message, status)
   }
 }

 getUserIdFromToken(idToken: string) {
   const decodedIdToken = verify(idToken, this.esiaPublicKey, {
     algorithms: ['RS256'],
     audience: this.clientId,
   }) as EsiaParsedToken
   return decodedIdToken['urn:esia:sbj']['urn:esia:sbj:oid']
 }

 async getUserInfo(tokens: EsiaTokens) {

   const { idToken, accessToken } = tokens
   const oId = this.getUserIdFromToken(idToken)

   const [{ data: mainInfo }, { data: contactsInfo }] = await Promise.all([
     axios.get(`${this.esiaHost}/rs/prns/${oId}`, {
       headers: {
         Authorization: `Bearer ${accessToken}`,
       },
     }),
     axios.get(`${this.esiaHost}/rs/prns/${oId}/ctts?embed=(elements)`, {
       headers: {
         Authorization: `Bearer ${accessToken}`,
       },
     }),
   ])

   const email = contactsInfo.elements.find(({ type }: { type: string }) => type === 'EML')

   return {
     id: oId,
     firstName: mainInfo.firstName,
     lastName: mainInfo.lastName,
     surName: mainInfo.middleName,
     trusted: mainInfo.trusted,
     email: email ? {
       value: email.value.toLowerCase(),
       verified: email.vrfStu === 'VERIFIED',
     } : null,
   }
 }

}  
  

Надеюсь, статья оказалась для вас полезной. Желаю, чтобы у вас все получилось без особых проблем! 

Читайте также:  К успеху: выбор правильной управляющей компании ПФР

Полезные материалы по теме

Текущая версия страницы пока не проверялась
опытными участниками и может значительно отличаться от версии
, проверенной 26 июня 2022 года; проверки требуют 4 правки
.


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

  • идентификация
    и аутентификация
    пользователей
  • управление идентификационными данными
  • авторизация
    уполномоченных лиц органов исполнительной власти при доступе к функциям ЕСИА
  • ведение информации о полномочиях пользователей в отношении информационных систем [3]

    .


2013 — Постановлением Правительства Российской Федерации от 25 января 2013 года № 33 «Об использовании простой электронной подписи при оказании государственных и муниципальных услуг» предусмотрено создание в ЕСИА регистра органов и организаций, имеющих право создания (замены) и выдачи ключа простой электронной подписи в целях оказания государственных и муниципальных услуг. Однако информация о сроках исполнения данного постановления и появлении соответствующих функциональных возможностей в ЕСИА отсутствует.


Например, сценарий идентификации и аутентификации выглядит следующим образом:

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

    .

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

  1. Разработать модуль авторизации ЕСИА в соответствии с одним из доступных стандартов: SAML 2.0 или OpenID Connect 1.0.
  2. Зарегистрировать ИС в специальном регистре информационных систем оператора ЕСИА [25]

    .
  1. С помощью веб-интерфейса ЕСИА осуществляется регистрация учётной записи руководителя организации и учётной записи юридического лица (органа государственной власти).
  2. С помощью веб-интерфейса Технологического портала ЕСИА регистрируется учётная запись информационной системы.
  3. Генерируется закрытый ключ и сертификат открытого ключа (в одном из аккредитованных удостоверяющих центрах).
  4. С помощью веб-интерфейса Технологического портала ЕСИА загружается сертификат информационной системы.
  5. Направляется заявка на подключение ИС к тестовой среде ЕСИА;
  6. Производится отладка взаимодействия;
  7. Направляется заявка на подключение ИС к промышленной среде ЕСИА [25]

    .

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

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

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

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

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

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

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

Пройдите идентификацию по действующему квалифицированному сертификату и получите сертификат электронной подписи удалённо.

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


Облако – лого


Облако – лого

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

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

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

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

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

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

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

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

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

Время на прочтение

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

ИНТЕГРАЦИЯ PHP ESIA

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

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

(ГУ), который также называют ЕСИА

.

ИНТЕГРАЦИЯ PHP ESIA

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

ИНТЕГРАЦИЯ PHP ESIA

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

ИНТЕГРАЦИЯ PHP 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
. Этот сертификат нужно загрузить в карточку ИС на Техпортале.

Читайте также:  Не пропустите, когда приходят девушки: захватывающие события для всех

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

ИНТЕГРАЦИЯ PHP ESIA

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

ИНТЕГРАЦИЯ PHP ESIA
ИНТЕГРАЦИЯ PHP ESIA

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

ИНТЕГРАЦИЯ PHP ESIA

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

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

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

Форма этой заявки приведена в Регламенте взаимодействия заявителей с операторами ЕСИА

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

ИНТЕГРАЦИЯ PHP 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 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 поддержку ГОСТ. Это было непросто, но после пары недель изысканий нам это удалось.

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

  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, но это тема отдельной статьи. А так, для тренировки общения с тестовым стендом ЕСИА вполне подойдет наш проект.

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

Документы

Оцените статью