Интеграция ЭЦП НУЦ РК в информационные системы на базе веб технологий

  • Tutorial

Я расскажу о тонкостях внедрения электронной цифровой подписи (ЭЦП) в информационные системы (ИС) на базе веб технологий в контексте Национального Удостоверяющего Центра Республики Казахстан (НУЦ РК).


В центре внимания будет формирование ЭЦП под электронными документами и, соответственно, NCALayer — предоставляемое НУЦ РК криптографическое программное обеспечение. В частности уделю внимание вопросам связанным с UX и объемом поддерживаемого функционала NCALayer.


Процесс разделю на следующие этапы:


  • формирование неизменного представления подписываемого документа (под подписываемым документом я буду подразумевать любые данные которые необходимо подписать, такие как: договор, бланк заказа, форма аутентификации и т.п.);
  • подписание документа в веб интерфейсе с помощью NCALayer;
  • проверка подписи на стороне сервера;
  • (при необходимости) подготовка подписи к долгосрочному хранению.

Формирование неизменного представления подписываемого документа


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


Рассмотрим простой пример — документы хранятся в виде записей в базе данных. Для подписания документа необходимо сформировать его представление в виде единого блока данных (конечно можно подписывать каждое поле записи поотдельности, но обычно так не делают), сделать это можно, к примеру, следующими способами:


  • извлечь все поля записи, привести их к строкам и соединить в одну строку;
  • сформировать XML или JSON представление;
  • сформировать PDF документ на базе шаблона с каким-то оформлением содержащий данные из записи;
  • и т.п.

Далее возможны два сценария каждый из которых имеет свои подводные камни:


  • ИС не хранит сформированного представления и каждый раз для проверки подписи под документом (в частности проверки неизменности данных) формирует его;
  • ИС хранит сформированное представление и использует его для проверки подписи.

В том случае, если ИС не хранит сформированного представления, разработчикам необходимо гарантировать что в будущем формируемые представления будут бинарно идентичны тем, которые были сформированы в первый раз не смотря на:


  • изменения схемы базы данных;
  • обновления механизма формирования представления (которое может так же зависеть от внешних библиотек которые, скорее всего, не стремятся к обеспечению бинарной идентичности).

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


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


Подписание документа в веб интерфейсе с помощью NCALayer


Для формирования цифровых подписей на стороне клиента НУЦ РК предоставляет единственный инструмент — сертифицированное программное обеспечение NCALayer которое представляет из себя WebSocket сервер, запускаемый на 127.0.0.1, которому можно отправлять запросы на выполнение криптографических (а так же некоторых смежных) операций. При выполнении некоторых операций NCALayer отображает диалоговые окна — то есть берет часть работы по получению пользовательского ввода на себя.


Описание API NCALayer доступно в составе комплекта разработчика. Для того, чтобы поэкспериментировать со взаимодействием с NCALayer по WebSocket можно воспользоваться страницей интерактивной документации KAZTOKEN mobile (KAZTOKEN mobile повторяет API NCALayer).


Взаимодействовать с NCALayer из браузера можно напрямую с помощью класса WebSocket, либо можно воспользоваться библиотекой ncalayer-js-client которая оборачивает отправку команд и получение ответов в современные async вызовы.


Замечу что весь основной функционал NCALayer доступен в модуле kz.gov.pki.knca.commonUtils, использовать модуль kz.gov.pki.knca.applet.Applet (наследие Java аплета) не рекомендую, так как, на мой взгляд, это не даст никаких преимуществ, но шансов выстрелить себе в ногу с ним больше — к примеру можно случайно разработать интерфейс который не будет поддерживать аппаратных носителей (токенов или смарт-карт) с несколькими ключевыми парами.


Модуль kz.gov.pki.knca.commonUtils берет на себя взаимодействие с пользователем связанное с выбором конкретного хранилища, которое нужно использовать для выполнения операции (так же он берет на себя выбор конкретного сертификата и соответствующего ключа, а так же ввод пароля или ПИН кода), но ему необходимо указать какой тип хранилищ нужно использовать. Типы хранилищ стоит разделить на два класса:


  • файловые, поддерживается единственный тип заданный константой 'PKCS12',
  • аппаратные (токены и смарт-карты), для перечисления тех типов, экземпляры которых в данный момент подключены в ПК пользователя, следует использовать запрос getActiveTokens.

Таким образом для того, чтобы предоставить пользователю возможность работать с любым поддерживаемым NCALayer хранилищем, можно воспользоваться одним из следующих подходов:


  • гибкий — отправить запрос getActiveTokens, в ответ получить массив имен доступных а данный момент типов хранилищ, добавить в него 'PKCS12' и спросить у пользователя каким он хотел бы в данный момент воспользоваться;
  • простой — отправить запрос getActiveTokens, в том случае, если он вернул массив несколькими именами, попросить пользователя отключить лишнее, если в массиве один элемент, использовать его, если массив пустой, использовать 'PKCS12'.

Для подписания данных рекомендую использовать следующие запросы (опять же чтобы снизить вероятность выстрела в ногу):


  • createCAdESFromBase64 — вычислить подпись под данными и сформировать CMS (CAdES);
  • createCMSSignatureFromBase64 — вычислить подпись под данными, получить на подпись метку времени (TSP) и сформировать CMS (CAdES) с внедренной меткой времени;
  • signXml — вычислить подпись под XML документом, сформированную подпись добавить в результирующий документ (XMLDSIG);
  • signXmls — аналогично signXml, но позволяет за один раз подписать несколько XML документов.

В качестве параметров каждому из них нужно будет передать тип хранилища, тип сертификата, подписываемые данные и дополнительные модификаторы.


Модуль kz.gov.pki.knca.commonUtils поддерживает следующие типы сертификатов:


  • 'AUTHENTICATION' — сертификаты для выполнения аутентификации;
  • 'SIGNATURE' — сертификаты для подписания данных.

NCLayer предоставит пользователю выбирать только из тех сертификатов, которые соответствуют указанному типу.


Упрощенный пример подписания произвольного блока данных с использованием ncalayer-js-client:


async function connectAndSign(base64EncodedData) {
  const ncalayerClient = new NCALayerClient();

  try {
    await ncalayerClient.connect();
  } catch (error) {
    alert(`Не удалось подключиться к NCALayer: ${error.toString()}`);
    return;
  }

  let activeTokens;
  try {
    activeTokens = await ncalayerClient.getActiveTokens();
  } catch (error) {
    alert(error.toString());
    return;
  }

  const storageType = activeTokens[0] || NCALayerClient.fileStorageType;

  let base64EncodedSignature;
  try {
    base64EncodedSignature = await ncalayerClient.createCAdESFromBase64(storageType, base64EncodedData);
  } catch (error) {
    alert(error.toString());
    return;
  }

  return base64EncodedSignature;
}

Проверка подписи на стороне сервера


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


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


С юридической точки зрения ориентироваться следует на Приказ Министра по инвестициям и развитию Республики Казахстан “Об утверждении Правил проверки подлинности электронной цифровой подписи”. В Приказе перечислены необходимые проверки которые должны выполнять информационные системы для обеспечения юридической значимости подписанных электронной цифровой подписью документов. Анализу этого документа, а так же некоторым техническим вопросам посвящена заметка Проверка цифровой подписи.


Выполнять проверки необходимо с применением сертифицированных средств, к примеру с помощью библиотек входящих в состав комплекта разработчика НУЦ РК, либо можно воспользоваться готовым решением SIGEX.


Подготовка подписи к долгосрочному хранению


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


Для фиксации момента подписания принято использовать метки времени TSP. Метку времени на подпись можно получить либо на клиенте (запрос createCMSSignatureFromBase64 интегрирует метку времени в CMS), либо на сервере. Метка времени позволит удостовериться в том, что момент подписания попадает в срок действия сертификата.


Для того, чтобы удостовериться в том, что сертификат не был отозван в момент подписания, следует использовать CRL или OCSP ответ. Этот нюанс и рекомендации по реализации описаны в разделе APPENDIX B — Placing a Signature At a Particular Point in Time документа RFC 3161.

AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 11

    +1

    Добрый день.
    Инфа не для холивара.
    Не только через NCALayer, можно взаимодействовать и подписывать.
    Я под 1С написал, всё работает.


    Автор молодец, я допустим не пишу статьи.

      0

      Добрый день,


      Да, согласен, в SDK НУЦ присутствует несколько сертифицированных библиотек, можно пользоваться ими. Но статья сфокусирована на ИС на базе веб технологий, для этого сценария НУЦ предоставляет NCALayer.


      Смею предположить что вы используете Java библиотеку — на сколько мне известно, поддержка токенов и карт реализована только в ней.

        +1
        Нужно помнить о том, что если требуется юридическая значимость электронной подписи, то в числе требований — наличие соответствующего сертификата у ПО. Это требование закона.

        Правда, как установить, что конкретная электронная подпись была создана с помощью конкретного ПО — задача не всегда решаемая. Т.е. все на усмотрение судьи и судебного эксперта.
          0

          У меня руководство было против внедрения ЭСФ в 1С, так как ключи хранятся, по сути, в открытом виде. Пришлось вместе с бухгалтером уговаривать, так как через веб интерфейс работать с большим объемом первички просто не реально.

            0

            Подскажите, пожалуйста, почему ключи должны храниться в открытом виде? В частности по какой причине не получается использовать токены или карты?

              0
              если мне не изменяет память, то 1С не поддерживает токены, только с файлового хранилища и нужно сохранить пароль, чтобы в будущем бухгалтер мог спокойно отправлять ЭСФ без запроса паролей
                0

                Понятно, согласен, через голый NCALayer подписывать массу документов пользователям не очень удобно — нужно при каждом подписании вводить пароль/ПИН и выбирать сертификат.


                Хотя для XML существует kz.gov.pki.knca.commonUtils.signXmls — можно несколько XML документов за раз подписать.

          0

          Весьма странно, что NCALayer не умеет добавлять OCSP проверки в подписи.


          Кстати можно писать собственные модули и регистрировать их. Уже кто только не добавился.


          Не хотите написать свой модуль, который будет на стороне клиента подписывать документы и сразу регистрировать в SIGEX?

            0

            По поводу модуля для NCALayer — это интересная идея.


            Для подписания файлов на данный момент существует SIGEX Desktop for Windows и ему для работы нужен NCALayer. Если же писать свой модуль, то можно будет расширить функционал — к примеру реализовать подписание нескольких файлов одним махом.

            +1
            Здравствуйте, хотел сделать веб сервис для университета, чтоб автоматически заполнять и подписывать ту волокиту бумаг, что от нас требует универ. Но сколько ни читал статей и рекомендаций, никак не пойму, могу ли я полноценно подписывать документы без комплекта разработчика. Ведь всё что мне нужно сделать — отправить запрос на вебсокет сервер NCALayer, он уже подпишет документ и вернет его обратно. Да, мы не сможем проверять подписи на стороне сервера, но это уже не наша проблема, а университета.
            Подпихните в нужную сторону, пожалуйста.

            И вот еще вопрос, сможет ли обычный разработчик-любитель, работающий для себя и в своё удовольствие, получить комплект разработчика?
              0

              Добрый день,


              Для подписания достаточно NCALayer, комплект разработчика НУЦ не обязателен. Как я писал в статье, подписать можно командой createCAdESFromBase64. Имейте в виду что после того, как NCALayer получит сообщение, он отобразит несколько окон для: выбора файлового хранилища (в том случае, если указан тип хранилища 'PKCS12'), ввода пароля/ПИН, выбора сертификата в хранилище.


              Вы можете все это испробовать в живую на странице https://kaztoken.kz/mobile-docs/ — достаточно выбрать в меню слева createCAdESFromBase64 и нажать на кнопку отправки запроса внизу справа (NCALayer должен быть локально запущен).


              Но важный момент заключается в том, что подписывать автоматически не правильно — это противоречит законодательству: Закрытые ключи электронной цифровой подписи не могут быть переданы другим лицам. (http://adilet.zan.kz/rus/docs/Z030000370_).


              Автоматически подписывать документы сертификатами НУЦ не хорошо по следующим причинам:


              • речь идет о юридически значимой подписи, но подписывающий (сам человек) не имеет представления о том, что именно он подписывает — все равно что заставить человека не глядя подписывать документы, причем не просто не глядя, а принудительно запретить ему просматривать что именно он подписывает;
              • стандартные сертификаты юридических и физических лиц не ограничены в применении какими-то информационными системами, то есть если каким-то образом ваша система вместо документа для университета сформирует договор дарения квартиры (в ИТ всякое бывает), то он так же будет автоматически подписан и будет иметь юридическую значимость — квартира перейдет другому собственнику;
              • в том случае, если кто-то имеет доступ к серверу вашей системы, то он сможет получить доступ и к закрытому ключу — то есть как минимум сможет воспользоваться им (а то и скопировать себе в том случае, если ключ в файловом хранилище, а не на токене или карте).

              Очень много рисков для того, кто передаст свой ключ ЭЦП для автоматизации подписания.


              По хорошему Вам стоит поступить так:


              • реализовать интерфейс автоматизирующий формирование документов и отображение их пользователям;
              • в этом интерфейсе реализовать интеграцию с NCALayer — то есть дать пользователям возможность просматривать и подписывать сформированные документы;
              • сформированную подпись проверять на стороне вашего сервера (в соответствии с законодательством РК не проверенная подпись юридической значимости не имеет).

              Вы можете взять все эти задачи на себя, либо ограничиться первой а для всего остального использовать готовое решение, к примеру https://sigex.kz (он бесплатный, не требует регистрации). В этом случае будет примерно следующая схема:


              • Ваша система формирует документ в каком-то формате (к примеру PDF или DOC или XLSX — как Вам удобнее);
              • пользователь получает этот документ (скачивает с вашего веб интерфейса, либо получает готовый по почте, либо получает сразу на файловой системе в том случае, если ваша система — это десктопное приложение);
              • пользователь подписывает документ через веб интерфейс https://sigex.kz, либо с помощью приложения SIGEX Desktop for Windows (https://sigex.kz/support/sigex-desktop-for-windows/);
              • в процессе подписания пользователь указывает электронный адрес университета для отправки уведомления (вероятно еще какой-то адрес для хранения отчетности на вашей стороне);
              • сервис проверяет подпись в соответствии с законодательством и отправляет уведомления о подписании в университет и остальным указанным получателям.

              И вот еще вопрос, сможет ли обычный разработчик-любитель, работающий для себя и в своё удовольствие, получить комплект разработчика?

              На это я Вам ответить не смогу — я не знаю какие у НИТ критерии. Попробуйте отправить им запрос (https://pki.gov.kz/developers/), думаю они Вас проконсультируют.

            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

            Самое читаемое