Русский
Русский
English
Статистика
Реклама

Цифровая подпись

Шифруем по-русски, или отечественные криптоалгоритмы

01.12.2020 18:05:13 | Автор: admin

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


Из новостей

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

До конца 2020 года планируется закончить создание национального удостоверяющего центра структуры, которая будет выдавать сайтам вРунете отечественные цифровые сертификаты, пишет Медуза. Также, по данным этого издательства отечественные цифровые сертификаты будут использовать криптоалгоритмы Магма и Кузнечик. Кроме того, отечественные алгоритмы шифрования по требованию Центробанка станут обязательными к использованию в платежных системах уже с 2024 года, пишет РБК.

Добавим к этому новость от газеты Коммерсантъ, в которой Магма и Кузнечик упоминаются в контексте тестируемых алгоритмов для использования в виртуальных сим-картах eSim.

Упомянутые выше и другие основные алгоритмы, используемые в отечественной криптографии стандартизованы и описаны в ГОСТах.

Направления ГОСТов

Отечественная криптография базируется на четырех основных объектах, которые мы рассмотрим далее.

Цифровая подпись

ГОСТ 34.10-2018 описывает алгоритмы формирования и проверки электронной цифровой подписи с помощью операций в группе точек эллиптической кривой и функции хеширования. Длины секретного ключа 256 бит и 512 бит.

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

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

Эллиптической кривой над конечным простым полем F_p , где p>3 , называется множество точек (x, y) , x,y\ \epsilon\ F_p , удовлетворяющих уравнению (в форме Вейерштрасса) y^2 = x^3 + ax + b (mod\ p) , где 4a^3+27b^2 \neq0 , a,\ b\ \epsilon\ F_p .

Альтернативный способ задать эллиптическую кривую

Отметим, что эллиптическую кривую можно задать уравнением не только в форме Вейерштрасса. Относительно новым способом задания эллиптической кривой является уравнение в форме Эдвардса x^2 + y^2 = 1+dx^2y^2, d\ \epsilon \ F_p\backslash \{ 0,1 \} .

Суммой точек (x_1,y_1) , (x_2,y_2) эллиптической кривой называется точка (x_3,y_3) , координаты которой определяются, как x_3 = \lambda^2 -x_1 -x_2(mod\ p) , y_3 = \lambda^2(x_1 -x_3) -y_1(mod\ p) , где \lambda = \frac{y_2 - y_1}{x_2-x_1} (mod\ p) .

Точка эллиптической кривой C = kP , может быть определена через сумму точек C = P+P+...+P .

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

Алгоритмы формирования и проверки электронной цифровой подписи.

Подпись создается по следующему алгоритму.

входные данные: сообщение Mи закрытый ключ подписи d .

к сообщению применяется хеш-функция(Стрибог) и вычисляется хеш-код сообщения h=h(M) , отметим, что хеш-код это строка бит.

определяется число e = \alpha(mod\ q) , где \alpha целое число, которое соответствует двоичному представлению хеш-кода h . Причем если \alpha(mod\ q) = 0 , то e принимается за 1.
q это порядок порядок циклической подгруппы группы точек эллиптической кривой, который является одним из параметров цифровой подписи. Также среди параметров есть P это базовая точка подгруппы.

на основе случайно сгенерированного целого числа k, 0<k<q , это число называют секретным ключом. Затем вычисляется точка на эллиптической кривой C = kP . Точка C имеет координаты (x_c,y_c) .

из координаты точки на эллиптической кривой и преобразования хеша вычисляется электронная подпись (r, s) , где r = x_c (mod\ q),\ s = (rd+ke)(mod\ q) . Если либо r , либо s равняется 0, то нужно вернуться к предыдущему шагу.

выходные данные: цифровая подпись (r, s) которую добавляют к сообщению.

Теперь перейдем к алгоритму проверки подписи.

входные данные: сообщение M c цифровой подписью (r, s) и ключ проверки подписи Q

полученная цифровая подпись проходит первичную проверку, если проверка не пройдена, то есть не выполнены неравенства 0<r<q,\ 0<s<q , то подпись неверна.

вычисляется хеш-код сообщения h=h(M) , опять же с помощью алгоритма Стрибог.

определяется число e = \alpha(mod\ q) , где \alpha целое число, которое соответсвует двоичному представлению хеш-кода h. Причем если \alpha(mod\ q) = 0 , то e принимается за 1. Затем определяется \nu = e^{-1}(mod\ q) .

вычисляется точка эллиптической кривой C = s\nu P -r\nu Q , из которой получается R = x_c (mod\ q) .

если r = R , то подпись верна

выходные данные: подпись вена/неверна

Хеш-функция

ГОСТ 34.11-2018 посвящен функции хеширования. В данном документе содержится описание алгоритма вычисления хеш-функции, известной из предыдущих версий стандарта, как Стрибог.

Стрибог принимает на вход сообщение произвольной длины, которое впоследствии разбивается на блоки размером 512 бит(с дополнением блоков при необходимости). После чего входные данные преобразуются в хеш-код фиксированной длинны 256 или 512 бит.

Подробное описание алгоритма вместе с разбором используемых в нем преобразований можно найти в статье @NeverWalkAloner.

Шифры

ГОСТ 34.12-2018 охватывает блочные шифры. Именно в этом ГОСТе описаны алгоритмы шифрования Кузнечик и Магма алгоритмы блочного шифрования с длинами шифруемых блоков 128 бит и 64 бита соответсвенно и длиной ключа шифрования 256 бит у обоих.

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

Приведем упрощенную схему работы Кузнечика при зашифровании.

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

@sevastyan01 в своей статье подробно описал алгоритм Кузнечик.

Зашифрование блока Магмой проходит в 32 раунда, для каждого раунда из исходного ключа шифрования генерируется раундовый ключ, причем алгоритм генерации ключей отличается от генерации ключей в Кузнечике.

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

Режимы работы шифров

ГОСТ 34.13-2018 содержит описание следующих режимов работы блочных шифров.

Режим простой замены

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

Расшифрование происходит аналогичным образом. Причем если при зашифровании было применено дополнение, то при расшифровании применяется обратная операция.

Режим гаммирования

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

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

Если общая длина гаммы не кратна длине блока, то последний блок гаммы усекается до размера блока. Блоки гаммы отличны друг от друга и имеют псевдослучайных характер.

Режимы гаммирования с обратной связью: по выходу, по шифротексту

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

Отличие режимов можно увидеть на схеме.

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

Режим простой замены с зацеплением

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

Режим выработки имитовставки

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

Каждый из стандартов действителен с 1 июня 2019 года в соответствии с приказом Федерального агентства по техническому регулированию и метрологии. Актуальные ГОСТы наследуют разработки, прописанные в предыдущих версиях.

Реализации алгоритмов ГОСТов

@ru_crypt в своей статье собрал множество вариантов реализации ГОСТовских алгоритмов на любой вкус.

Интерес к таблице подстановок

Рассмотрим ГОСТ 34.10-2018. В алгоритмах формирования и проверки цифровой подписи на начальных шагах используется хеш-функция Стрибог, которая определена в ГОСТ 34.11-2018.

Заглянем теперь в ГОСТ 34.12-2018. В данном документе в качестве параметра алгоритма Кузнечик для нелинейного биективного преобразования приводится таблица подстановок

\pi. Эта же таблица приведена в ГОСТ 34.11-2018, то есть используется и при хешировании.

Таблица \pi задает единственное нелинейное преобразование в алгоритме шифрования, которое значительно усложняет взлом шифра. То есть функция подстановки особенно важна для устойчивости шифра к взломам.

Разработчики Кузнечика и Стрибога утверждают, что сгенерировали таблицу \pi случайным образом. Однако в ряде работ был проведен криптоанализ таблицы подстановок и выявлено несколько способов ее генерации, причем не случайным образом.

Статьи с алгоритмами генерации таблицы \pi :

Reverse-Engineering the S-Box of Streebog, Kuznyechik and STRIBOBr1 Alex Biryukov, L eo Perrin, and Aleksei Udovenko

Exponential S-Boxes: a Link Between the S-Boxes of BelT and Kuznyechik/Streebog Lo Perrin and Aleksei Udovenko

Partitions in the S-Box of Streebog and Kuznyechik Lo Perrin

В конце каждой из статей приведены алгоритмы генерации таблицы подстановок, которые можно запустить в оригинальном виде с помощью SageMath.

Заключение

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

Подробнее..

Хакеры SolarWinds размазали свои байты в HTTP-трафике через регулярные выражения

21.12.2020 00:08:29 | Автор: admin

Валидная цифровая подпись на DLL со встроенным бэкдором

Практически по всем профильным СМИ прошла новость о взломе программного обеспечения SolarWinds в рамках глобальной кампании кибершпионажа. Здесь нужно понимать масштаб атаки: этот софт для мониторинга IT-инфраструктуры (CPU, RAM, сеть) используют тысячи частных компаний и государственных учреждений, включая АНБ, Пентагон, Госдеп и проч. В общей сложности 300 000 клиентов по всему миру (данная страница уже удалена с официального сайта SolarWinds, по ссылке копия из веб-архива).

Самое интересное в этой атаке: 1) внедрение бэкдора внутрь обновлений SolarWinds и 2) оригинальный механизм сокрытия данных в служебном HTTP-трафике программы SolarWinds. В двух словах расскажем о методе стеганографии (covert signaling), который здесь применялся.

Отдельные подробности об атаке опубликовала компания FireEye в отчёте от 13 декабря 2020 года. Эта американская компания должна защищать сети своих клиентов от подобных диверсий, но в итоге и сама пострадала от взлома вместе с ними.

Некоторые из клиентов SolarWinds:



Основные факты


  • Бэкдор обнаружен спустя семь месяцев после начала атаки, ему присвоено кодовое название SUNBURST. Учитывая масштаб заражения, это серьёзный фейл антивирусных компаний.
  • Заражённая DLL распространялась с обновлениями платформы SolarWinds Orion, которая служит для мониторинга корпоративной сети.


    Платформа SolarWinds Orion

Валидная цифровая подпись


Бэкдор обнаружен в библиотеке SolarWinds.Orion.Core.BusinessLayer.dll, которая подписана действительной цифровой подписью компании SolarWinds Worldwide, LLC (скриншот выше).

В частности, инфицирован ряд обновлений программы SolarWinds Orion за март-май 2020 года, которые распространялись с действительной цифровой подписью.

Это был стандартный файл Windows Installer Patch со всеми обычными ресурсами, включая заражённую библиотеку SolarWinds.Orion.Core.BusinessLayer.dll. После установки библиотека нормально загружалась в память штатным экзешником SolarWinds.BusinessLayerHost.exe.

Специалисты Microsoft пояснили, что злоумышленники использовали локальный взлом [on-premises compromise], чтобы получить доступ к доверенному сертификату подписи SAML-токенов организации [SolarWinds]. Это позволило им подделать токены SAML для всех существующих пользователей и аккаунтов организации, включая высокопривилегированные. Судя по всему, речь о физическом проникновении в офис компании (on-premises compromise).

Уникальные особенности


  • Алгоритм Domain Generation Algorithm (DGA) для генерации поддоменов и изменения DNS-запросов. Троян отправлял запрос на резолв поддомена avsvmcloud[.]com, а в DNS-ответе содержалась запись CNAME с указанием командного сервера.
  • Весь трафик маскировался под сетевой трафик по служебному протоколу Orion Improvement Program (OIP) через SolarWinds API. Таким образом, антивирусы и файрволы не могли отличить активность бэкдора от настоящей активности программы SolarWinds.
  • Программный код бэкдора внедрялся в стандартные программные компоненты.

Стеганография


А вот самая интересная часть как именно бэкдор маскировал пакеты в обычном сетевом трафике:

Для получения данных зловред использовал запросы HTTP GET или HTTP HEAD, и для отправки HTTP PUT или HTTP POST. Метод PUT использовался, когда полезная нагрузка меньше 10000 байт; в противном случае используется POST. HTTP-заголовок If-None-Match содержит заксоренное представление userID, вычисленного ранее, с добавлением случайного массива байтов той же длины.

Полезная нагрузка JSON в запросах HTTP POST и PUT содержит ключи userId, sessionId и steps. Сообщения с данными для отправки на сервер сжаты DEFLATE и однобайтовым XOR. Каждое сообщение отдельно кодируется Base64.

В наблюдаемом трафике тела HTTP-ответов скрываются под доброкачественные XML, связанные со сборками .NET. Но на самом деле данные распределены по многим строкам GUID и HEX. Команды извлекаются из тел HTTP-ответов путём поиска hex-строк с использованием следующего регулярного выражения: \{[0-9a-f-]{36}\}"|"[0-9a-f]{32}"|"[0-9a-f]{16}. Командные данные распределены по нескольким строкам, замаскированным под строки GUID и HEX. Все совпадающие подстроки в ответе фильтруются на наличие символов не-HEX, объединяются вместе и декодируются HEX. Первое значение DWORD показывает фактический размер сообщения, за которым сразу же следует сообщение, а затем необязательные мусорные байты. Извлечённое декодируется однобайтным XOR с использованием первого байта сообщения, а затем разархивируется DEFLATE. Первый символ это целое число ASCII, которое соответствует команде JobEngine с необязательными дополнительными аргументами, разделёнными пробелами.

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

Например, в 2010 году были повреждены иранские установки для обогащения урана. Очень продвинутый зловред Stuxnet слегка менял скорость вращения установок и в конце концов вывел их из строя. Соответственно, логично предположить, что заказчиками и разработчиками зловредров были спецслужбы США и Израиля, поскольку эти страны планомерно пытаются помешать изготовлению ядерного оружия в Иране, действуя не всегда дипломатическими методами.

Что касается бэкдора SUNBURST, то его приписывают скорее российским хакерам из группировки APT29 (Cozy Bear), исходя из хитроумности применяемых техник, выбора целей и физического проникновения в офис жертвы. Хотя достоверно заказчик и исполнитель не известны.

Правила Snort для обнаружения и блокировки трафика SUNBURST опубликованы в свободном доступе.


Подробнее..

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

07.07.2020 14:13:48 | Автор: admin

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


В центре внимания будет формирование ЭЦП под электронными документами и, соответственно, 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.

Подробнее..

Юридически значимый электронный документ (для РК) из веб формы без серверного кода

18.03.2021 20:06:33 | Автор: admin

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


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

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


Речь будет идти о сертификатах ЭЦП, выпущенных НУЦ РК.


Задачу я сформулирую следующим образом: на основе заранее согласованного шаблона сформировать в веб интерфейсе электронный документ, предоставить возможность подписать его ЭЦП, передать его для обработки группе менеджеров и обеспечить юридическую значимость в соответствии с законодательством РК.


Я буду использовать:


  • Vue.js для удобства разработки (постараюсь не писать ничего специфического, так, чтобы можно было легко переключиться на любой другой);
  • Bootstrap для базового оформления (его практически не будет заметно);
  • axios для упрощения сетевого взаимодействия;
  • pdfmake для создания PDF из JS;
  • ncalayer-js-client для взаимодействия с NCALayer;
  • SIGEX для проверки подписей и отправки документов по электронной почте.

Для реализации мне потребуются:


  • шаблон электронного документа, состоящий из фиксированной части и полей, которые должен заполнять пользователь;
  • действующий сертификат ЭЦП НУЦ РК;
  • установленный NCALayer.

В самой статье я приведу только ключевые части кода, а с полной реализацией можно ознакомиться тут: https://github.com/sigex-kz/example-sign-web-form


Веб форма


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


<form v-on:submit.prevent="compilePDF">  <h2>{{ formHeader }}</h2>  <p>{{ formIntro }}</p>  <div v-for="formItem in formItems" class="form-group">    <label>{{ formItem.label }}</label>    <input v-model="formItem.value" type="text" class="form-control">  </div>  <button type="submit" class="btn btn-primary">Сформировать документ</button></form>

Фиксированные части формы буду заполнять в объекте данных Vue.js для того, чтобы их можно было использовать и в HTML и в PDF:


new Vue({...  data: {    formHeader: 'Документ 1',    formIntro: 'Этот документ сформирован в браузере из данных веб формы, является примером, он никого ни к чему не обязывает и ничего не гарантирует, несмотря на то, что он может быть подписан ЭЦП.',    formItems: [      { label: 'Первый вопрос', value: '', },      { label: 'Второй вопрос', value: '', },      { label: 'Третий вопрос', value: '', },    ],...  },...

Генерация PDF в JS


Для формирования PDF воспользуюсь библиотекой pdfmake, она создает PDF файл из определения объекта JS.


Сначала сформирую объект определения и наполню его данными, после этого передам его в pdfmake и получу байты PDF файла в base64 кодировке:


async compilePDF() {  const pdfDefinition = {    content: [      { text: this.formHeader, fontSize: 20, bold: true, alignment: 'center', margin: [ 0, 0, 0, 20 ] },      { text: this.formIntro, fontSize: 15, margin: [ 0, 0, 0, 20 ] },    ],  };  for (const formItem of this.formItems) {    pdfDefinition.content.push(`${formItem.label}: ${formItem.value}`);  }  this.dataB64 = await new Promise((resolve) => {    const pdfDocGenerator = pdfMake.createPdf(pdfDefinition);    pdfDocGenerator.getBase64(resolve);  });},

Подписание PDF цифровой подписью


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


<p>Вы подписываете документ <a v-bind:href="`data:application/octet-stream;base64,${dataB64}`" target="_blank" v-bind:download="title">{{ title }}</a>.</p>

НУЦ РК предоставляет сертифицированное средство ЭЦП приложение NCALayer, его и буду использовать для формирования подписи. NCALayer это WebSocket сервер, чтобы не писать обработку отправки и получения команд вручную, воспользуюсь библиотекой ncalayer-js-client.


NCALayer поддерживает, как файловые хранилища ключей ЭЦП, так и защищенные аппаратные хранилища (токены и карты). Чтобы не перегружать пользователя излишними вопросами в первую очередь спрошу обнаружил ли NCALayer аппаратные хранилища. В том случае, если аппаратных хранилищ не обнаружено, переключусь на файловое:


const storageTypes = await this.ncaLayer.getActiveTokens();if (storageTypes.length == 0) {  this.storageType = 'PKCS12';} else {  this.storageType = storageTypes[0];}

Теперь можно подписать PDF. В зависимости от типа запрошенного хранилища, NCALayer отобразит соответствующий пользовательский интерфейс и завершит процедуру:


const signature = await this.ncaLayer.createCMSSignatureFromBase64(this.storageType, this.dataB64);

В том случае, если все прошло хорошо, на данный момент у меня имеются:


  • электронный документ в виде PDF файла;
  • цифровая подпись под электронным документом.

Проверка подписи и пересылка электронного документа по электронной почте


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


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


let response = await axios.post(  `${this.sigexURL}/api`,  {    title: this.title,    description: this.description,    signature,    emailNotifications: { to: ['some-manager@example.kz', this.email] },  },);this.sigexId = response.data.documentId;

Я запрошу отправку уведомлений не только своим коллегам менеджерам, но так же на тот адрес, который указал пользователь, так как пользователю подписанный электронный документ тоже может быть нужен.


Вторым этапом передам сервису на проверку подписанный документ:


const dataToSend = Uint8Array.from(atob(this.dataB64), c => c.charCodeAt(0)).buffer;response = await axios.post(  `${this.sigexURL}/api/${this.sigexId}/data`,  dataToSend,  {    headers: { 'Content-Type': 'application/octet-stream' },  },);

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


Итог


Проверим соответствие поставленной задаче:


  • на основе заранее согласованного шаблона сформировать в веб интерфейсе электронный документ реализовано в виде статической веб страницы и небольшого количества JS кода;
  • предоставить возможность подписать его ЭЦП реализовано с использованием рекомендуемого сертифицированного ПО;
  • передать его для обработки группе менеджеров реализовано путем отправки подписанных документов на электронный адрес ответственных менеджеров;
  • обеспечить юридическую значимость в соответствии с законодательством РК реализовано с помощью API сервиса SIGEX.
Подробнее..

Как команда it-animals в финале Цифрового Прорыва выиграла

24.05.2021 16:18:49 | Автор: admin

Данная статья написана в соавторстве с тимлидом @Restlin

Выбор кейса и наше видение его решения

Изначально выбор пал на кейс МВД: Разработка автономного программного решения лингвистического анализа и преобразования в тексте лица повествования.

Формулировка кейса:

Учитывая специфику деятельности определенных служб МВД России, при подготовке документов требуется преобразование в тексте лица повествования от первого лица в третье с учетом рода. Например, фраза в исходном тексте Я увидел, что Иванов пошёл ко мне в итоговом тексте должна быть преобразована в Он увидел, что Иванов пошёл к нему. Разработанное программное решение позволит в автоматическом режиме проводить процесс конвертации лица повествования, что позволит сотрудникам уделить больше времени на иные аспекты служебной деятельности. Кейс подготовлен Департаментом информационных технологий, связи и защиты информации МВД России.

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

Планировалось, что мы создадим веб-сервис, который умеет автоматически преобразовывать показания свидетеля из первого лица в третье.

Все складывалось как нельзя лучше до того момента, как мы не посмотрели видео с презентацией кейса от кейсодержателя, что на выходе они ждут:

1) локальное решение, работающее без доступа в сеть;

2) интегрированные офисные пакеты посредством макросов.

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

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

Формулировка кейса:

Согласно действующему законодательству Почта России обязана официально отвечать на поступающие запросы граждан, связанные с работой компании и качеством оказания услуг. Обращения поступают в профильное подразделение, где, после подготовки ответа, подписываются, сканируются и отправляются в соответствующий филиал или автору обращения. Процесс является трудоемким и ресурсоемким с точки зрения ручных операций и расходных материалов (бумага, расходы на оргтехнику). Участникам хакатона предлагается разработать программное решение - модуль подписания документов с помощью электронной подписи, который расширит функциональность существующей системы работы с обращениями (Террасофт Creatio). Модуль должен формировать электронную подпись для каждого файла отдельно и перед подписанием проверять срок действия сертификата электронной подписи уполномоченного сотрудника.

Почему он? У нас было понимание как работать с электронной подписью на Open source решениях: OpenSSL. Пригодился опыт Ильи в разработке СЭД - он знал о существовании php библиотеки tcpdf для генерации файла pdf с возможностью встроить электронную подпись. Плюс на текущем проекте pirs.online мы уже копали эту тему, и оттого данной задачей заниматься было приятно вдвойне.

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

Панические атаки и ведро валерьянки

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

Написали в чат поддержки ЦП (хвала за неиссякаемое терпение Ирине с вопросом: что нам делать и можно ли сменить кейс? К счастью, организаторам удалось переубедить представителей Почты России снять это ограничение и только тогда мы смогли приступить к решению.

А что потом? Технические подробности

Дальше пошло по накатанной: первый чекпоинт и наши идеи по реализации, полученное одобрение экспертов и практически бессонная ночь работы.

Нам повезло: роли между командой у нас распределены четко, и каждый занимается своей задачей. Марина - презентация и вычитка спитча Ильи. Илья отвечает за спитч, архитектуру, бэк. Дима и Кирилл - фуллстеки.

С точки зрения технической реализации функционал прототипа выглядел просто:

  • вход пользователя под одной из двух ролей: гость и администратор;

  • формирование обращения администратору (почте РФ);

  • рассмотрение обращения и формирование ответа;

  • можно прикрепить файлы к обращению и ответу;

  • создать сертификат пользователя в личном кабинете;

  • подписать файлы ответа электронной подписью;

  • выгрузить обращение с электронной подписью;

  • проверить электронную подпись в обращении.

Структура базы данных прототипа уместилась всего в 3 таблицы, размещенных в PostgreSQL:

  1. user - таблица пользователей с реквизитами и типами;

  2. message - таблица обращений и ответов. По сути это переписка клиента и администратора;

  3. file - таблица файлов, прикрепленных к обращениям и ответам.

Благодаря большому опыту команды с php-фреймворком Yii2 мы в короткие сроки разработали основной функционал приложения. А вот задача интеграции функционала по работе с электронными подписями была трудоемкой и нетривиальной.

Для работы с электронными подписями мы решили использовать OpenSSL, как открытый стандарт де-факто по работе с электронными подписями.

Как и ожидалось библиотека очень мощная, но из коробки не поддерживает отечественные алгоритмы шифрования. Какое-то время ушло на интеграцию и настройку криптографического движка (libengine-gost-openssl 1.1) на алгоритмы ГОСТ, в частности ГОСТ-2012. Затем мы создали и настроили удостоверяющий центр.

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

Пилим прототип дальше

PHP содержит функции для работы с openssl по созданию сертификатов и подписи файлов, но после тщательного изучения документации, выяснилось, что переключить openssl engine на ГОСТ невозможно.

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

Создание сертификата пользователя:

exec("openssl req -nodes -newkey gost2012_512 -keyout $eSignPath/client.key -pkeyopt paramset:A -out $eSignPath/client.csr -subj \"/C=RU/ST=Udm/L=Izhevsk/O=IT/OU=animals/CN=user-{$user->id}\" -config $caPath/openssl.cnf ");

exec("openssl ca -engine gost -keyfile $caPath/ca.key -cert $caPath/ca.crt -in $eSignPath/client.csr -out $eSignPath/client.crt -batch -config $caPath/openssl.cnf 2>&1", $output);

где $eSignPath - путь до папки с ключами пользователей, а $caPath - путь до папки удостоверяющего центра.

Удаление сертификата пользователя:

exec("openssl ca -config $caPath/openssl.cnf -keyfile $caPath/ca.key -cert $caPath/ca.crt -revoke $eSignPath/client.crt 2>&1", $output);

exec("openssl ca -gencrl -config $caPath/openssl.cnf -keyfile $caPath/ca.key -cert $caPath/ca.crt -out $caPath/crl.pem 2>&1", $output);

где $eSignPath - путь до папки с ключами пользователей, а $caPath - путь до папки удостоверяющего центра.

Подписание файла сертификатом пользователя:

exec("openssl smime -engine gost -sign -in $fp -out $fp.sig -nodetach -binary -signer $clientKeysPath/client.crt -inkey $clientKeysPath/client.key -outform SMIME 2>&1", $output);

где $fp - путь до файла, $clientKeysPath - путь до папки с ключами пользователя.

Проверка подписи файла:

$output = exec("openssl cms -engine gost -verify -in $sigPath -inform SMIME -CAfile $pathCA/ca.crt -out $fp -certsout $clientKeysPath/client.crt 2>&1");

где $fp - путь до файла, $clientKeysPath - путь до папки с ключами пользователя, $sigPath - путь до электронной подписи.

Долгие часы настройки openssl и его интеграции в веб-приложение увенчались успехом. К третьему чекпоинту прототип уже мог создавать сертификат пользователя, подписывать сертификатом обращение, а затем проверять подпись. Решение было рабочим, но чутье подсказывало: не хватает какой-то главной фишки.

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

Ночь субботы подходит к концу: мы голодные и злые все еще работаем в офисе. Тошнит от доставок, работы вагон, но мы верим в команду и в то, что победа близка. Договариваемся ехать домой, и доделывать уже там.

Начинаем реализовывать и понимаем на сколько в библиотеке tcpdf захардкодена работа с openssl. Вылазят проблемы невозможности смены движка и другие конфликты библиотеки с нашим решением. Создаем потомка библиотеки и заменяем всю генерацию подписи с хардкода openssl на наш костыль (херак-херак, и впродакшн) через локальный метод api:

$fields = [

'r' => 'api/sign',

'filePath' => $tempdoc,

'userId' => $user->id,

];

$query = http_build_query($fields);

$ch = curl_init();

$host = \Yii::$app->params['apiHost'] ?? '';

curl_setopt($ch, CURLOPT_URL, $host . '/index.php?' . $query);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$signature = curl_exec($ch);

/*if (empty($this->signature_data['extracerts'])) {

openssl_pkcs7_sign($tempdoc, $tempsign, $this->signature_data['signcert'], array($this->signature_data['privkey'], $this->signature_data['password']), array(), PKCS7_BINARY | PKCS7_DETACHED);

} else {

openssl_pkcs7_sign($tempdoc, $tempsign, $this->signature_data['signcert'], array($this->signature_data['privkey'], $this->signature_data['password']), array(), PKCS7_BINARY | PKCS7_DETACHED, $this->signature_data['extracerts']);

}*/

И все же мы успеваем в последний момент и к утру воскресенья прототип полностью работает!

Последний рывок и мы у цели

В середине дня воскресенья Илья подключается по Zoom к защите решения, жюри неумалимы, ну а мы ждем результатов.

Было страшновато: осознание, что ты соревнуешься с лучшими (в финал попали топ 5 команд из отборочных региональных туров) подстегивало выкладываться на полную.

Неожиданно результатов пришлось ждать до вечера, хотя на Северо-Западном хабе объявили победителей чуть ли не через час после защит. Время тянулось как доставка Почты России.

Офтоп: мы победители! 750 тысяч на команду, Карл! 750 за 2 дня, Карл! А значит едем на грандфинал Цифрового прорыва в Москву!

Репозиторий нашего решения

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru