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

УКЭП с TSP, OSCP и C .NET Core 3.1

Я построю свой собственный сервис для подписания документов - FOX Я построю свой собственный сервис для подписания документов - FOX

Важное вступление

В гайде описывается формирование отсоединенной подписи вформате PKCS7 (рядом с файлом появится файл в формате .sig). Такую подпись может запросить нотариус, ЦБ и любой кому нужно долгосрочное хранения подписанного документа. Удобство такой подписи в том, что при улучшении ее до УКЭП CAdES-X Long Type 1 (CMS Advanced Electronic Signatures [1]) в нее добавляется штамп времени, который генерирует TSA (Time-Stamp Protocol [2]) и статус сертификата на момент подписания (OCSP [3]) - подлинность такой подписи можно подтвердить по прошествии длительного периода (Усовершенствованная квалифицированная подпись [4]).

Код основан на репозиториях corefx и DotnetCoreSampleProject - в последнем проще протестировать свои изменения перед переносом в основной проект и он будет отправной точкой по сборке corefx. Судя по записям с форума компании [5], решение для .NET Core в стадии бета-тестирования. Далее по тексту я также буду ссылаться на этот форум. Разработка велась в Visual Studio Community 2019.

Для получения штампа времени использован TSP-сервис http://qs.cryptopro.ru/tsp/tsp.srf

Что имеем на входе?

  1. КриптоПро CSP версии 5.0 - для поддержки Российских криптографических алгоритмов (подписи, которые выпустили в аккредитованном УЦ в РФ)

  2. КриптоПро TSP Client 2.0 - нужен для штампа времени

  3. КриптоПро OCSP Client 2.0 - проверит не отозван ли сертификат на момент подписания

  4. КриптоПро .NET Client - таков путь

  5. Любой сервис по проверке ЭП - я использовал Контур.Крипто как основной сервис для проверки ЭП и КриптоАРМ как локальный. А еще можно проверить ЭП на сайте Госуслуг

  6. КЭП по ГОСТ Р 34.11-2012/34.10-2012 256 bit, которую выпустил любой удостоверяющий центр

Лицензирование ПО и версии
  1. КриптоПро CSP версии 5.0 - у меня установлена версия 5.0.11944 КС1, лицензия встроена в ЭП.

  2. КриптоПро TSP Client 2.0 и КриптоПро OCSP Client 2.0 - лицензии покупается отдельно, а для гайда мне хватило демонстрационного срока.

  3. КриптоПро .NET Client версии 1.0.7132.2 - в рамках этого гайда я использовал демонстрационную версию клиентской части и все действия выполнялись локально. Лицензию на сервер нужно покупать отдельно.

  4. Контур.Крипто бесплатен, но требует регистрации. В нем также можно подписать документы КЭП, УКЭП и проверить созданную подпись загрузив ее файлы.

Так, а что надо на выходе?

А на выходе надо получить готовое решение, которое сделает отсоединенную ЭП в формате .sig со штампом времени на подпись и доказательством подлинности. Для этого зададим следующие критерии:

  1. ЭП проходит проверку на протале Госуслуг, через сервис для подтверждения подлинности ЭП формата PKCS#7 в электронных документах;

  2. КриптоАРМ после проверки подписи

    1. Заполнит поле "Время создания ЭП" - в конце проверки появится окно, где можно выбрать ЭП и кратко посмотреть ее свойства

      Стобец "Время создация ЭП"Стобец "Время создация ЭП"
    2. В информации о подписи и сертификате (двойной клик по записе в таблице) на вкладке "Штампы времени" в выпадающем списке есть оба значения и по ним заполнена информация:

      1. Подпись:

      2. Доказательства подлинности:

    3. В протоколе проверки подписи есть блоки "Доказательства подлинности", "Штамп времени на подпись" и "Время подписания". Для сравнения: если документ подписан просто КЭП, то отчет по проверке будет достаточно коротким в сравнении с УКЭП.

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

    Усовершенствованная подпись подтвержденаУсовершенствованная подпись подтверждена

Соберем проект с поддержкой ГОСТ Р 34.11-2012 256 bit

Гайд разделен на несколько этапов. Основная инструкция по сборке опубликована вместе с репозиторием DotnetCoreSampleProject - периодически я буду на нее ссылаться.

Первым делом создадим новую папку

... и положим туда все необходимое.

Инструкция делится на 2 этапа - мне пришлось выполнить оба, чтобы решение заработало. В папку добавьте подпапки .\runtime и .\packages

I - Сборка проекта без сборки corefx для Windows

  1. Установите КриптоПро 5.0 и убедитесь, что у вас есть действующая лицензия. - для меня подошла втроенная в ЭП;

  2. Установите core 3.1 sdk и runtime и распространяемый пакет Visual C++ для Visual Studio 2015 обычно ставится вместе со студией; прим.: на II этапе мне пришлось через установщик студии поставить дополнительное ПО для разработки на C++ - сборщик требует предустановленный DIA SDK.

  3. Задайте переменной среды DOTNET_MULTILEVEL_LOOKUP значение 0 - не могу сказать для чего это нужно, но в оригинальной инструкции это есть;

  4. Скачайте 2 файла из релиза corefx (package_windows_debug.zip и runtime-debug-windows.zip) - они нужны для корректной сборки проекта. В гайде рассматривается версия v3.1.1-cprocsp-preview4.325 от 04.02.2021:

    1. package_windows_debug.zip распакуйте в .\packages

    2. runtime-debug-windows.zip распакуйте в .\runtime

  5. Добавьте источник пакетов NuGet в файле %appdata%\NuGet\NuGet.Config - источник должен ссылаться на путь .\packages в созданной вами папке. Пример по добавлению источника есть в основной инструкеии. Для меня это не сработало, поэтому я добавил источник через VS Community;

  6. Склонируйте NetStandard.Library в .\ и выполните PowerShell скрипт (взят из основной инструкции), чтобы заменить пакеты в $env:userprofile\.nuget\packages\

    git clone https://github.com/CryptoProLLC/NetStandard.LibraryNew-Item -ItemType Directory -Force -Path "$env:userprofile\.nuget\packages\netstandard.library"Copy-Item -Force -Recurse ".\NetStandard.Library\nugetReady\netstandard.library" -Destination "$env:userprofile\.nuget\packages\"
    
  7. Склонируйте репизиторий DotnetCoreSampleProject в .\

  8. Измените файл.\DotnetSampleProject\DotnetSampleProject.csproj - для сборок System.Security.Cryptography.Pkcs.dll и System.Security.Cryptography.Xml.dll укажите полные пути к .\runtime;

  9. Перейдите в папку проекта и попробуйте собрать решение. Я собирал через Visual Studio после открытия проекта.

II - Сборка проекта со сборкой corefx для Windows

  1. Выполните 1-3 и 6-й шаги из I этапа;

  2. Склонируйте репозиторий corefx в .\

  3. Выполните сборку запустив .\corefx\build.cmd - на этом этапе потребуется предустановленный DIA SDK

  4. Выполните шаги 5, 7-9 из I этапа. Вместо условного пути .\packages укажите .\corefx\artifacts\packages\Debug\NonShipping, а вместо .\runtime укажите .\corefx\artifacts\bin\runtime\netcoreapp-Windows_NT-Debug-x64

На этом месте у вас должно получиться решение, которое поддерживает ГОСТ Р 34.11-2012 256 bit.

Немного покодим

Потребуется 2 COM библиотеки: "CAPICOM v2.1 Type Library" и "Crypto-Pro CAdES 1.0 Type Library". Они содержат необходимые объекты для создания УКЭП.

В этом примере будет подписываться BASE64 строка, содержащая в себе PDF-файл. Немного доработав код можно будет подписать hash-значение этого фала.

Основной код для подписания был взят со страниц Подпись PDF с помощью УЭЦП- Page 2 (cryptopro.ru) и Подпись НЕОПРЕДЕЛЕНА при создании УЭЦП для PDF на c# (cryptopro.ru), но он использовался для штампа подписи на PDF документ. Код из этого гайда переделан под сохранение файла подписи в отдельный файл.

Условно процесс можно поделить на 4 этапа:

  1. Поиск сертификата в хранилище - я использовал поиск по отпечатку в хранилище пользователя;

  2. Чтение байтов подписанного файла;

  3. Создание УКЭП;

  4. Сохранение файла подписи рядом с файлом.

using CAdESCOM;using CAPICOM;using System;using System.Globalization;using System.IO;using System.Security.Cryptography;using System.Security.Cryptography.X509Certificates;using System.Security.Cryptography.Xml;using System.Text;using System.Threading.Tasks;using System.Xml;public static void Main(){  //Сертификат для подписиX509Certificate2 gostCert = GetX509Certificate2("отпечаток");  //Файл, который предстоит подписать  byte[] fileBytes = File.ReadAllBytes("C:\\Тестовое заявление.pdf");  //Файл открепленной подписи  byte[] signatureBytes = SignWithAdvancedEDS(fileBytes, gostCert);  //Сохранение файла подписи  File.WriteAllBytes("C:\\Users\\mikel\\Desktop\\Тестовое заявление.pdf.sig", signatureBytes);}//Поиск сертификата в хранилищеpublic static X509Certificate2 GetX509Certificate2(string thumbprint){  X509Store store = CreateStoreObject("My", StoreLocation.CurrentUser);  store.Open(OpenFlags.ReadOnly);  X509Certificate2Collection certCollection =    store.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false);  X509Certificate2Enumerator enumerator = certCollection.GetEnumerator();  X509Certificate2 gostCert = null;  while (enumerator.MoveNext())    gostCert = enumerator.Current;  if (gostCert == null)    throw new Exception("Certificiate was not found!");  return gostCert;}//Создание УКЭПpublic static byte[] SignWithAdvancedEDS(byte[] fileBytes, X509Certificate2 certificate){  string signature = "";    try  {    string tspServerAddress = @"http://qs.cryptopro.ru/tsp/tsp.srf";    CPSigner cps = new CPSigner();    cps.Certificate = GetCAPICOMCertificate(certificate.Thumbprint);    cps.Options = CAPICOM_CERTIFICATE_INCLUDE_OPTION.CAPICOM_CERTIFICATE_INCLUDE_WHOLE_CHAIN;    cps.TSAAddress = tspServerAddress;    CadesSignedData csd = new CadesSignedData();    csd.ContentEncoding = CADESCOM_CONTENT_ENCODING_TYPE.CADESCOM_BASE64_TO_BINARY;    csd.Content = Convert.ToBase64String(fileBytes);    //Создание и проверка подписи CAdES BES    signature = csd.SignCades(cps, CADESCOM_CADES_TYPE.CADESCOM_CADES_BES, true, CAdESCOM.CAPICOM_ENCODING_TYPE.CAPICOM_ENCODE_BASE64);    csd.VerifyCades(signature, CADESCOM_CADES_TYPE.CADESCOM_CADES_BES, true);        //Дополнение и проверка подписи CAdES BES до подписи CAdES X Long Type 1     //(вторая подпись остается без изменения, так как она уже CAdES X Long Type 1)    signature = csd.EnhanceCades(CADESCOM_CADES_TYPE.CADESCOM_CADES_X_LONG_TYPE_1, tspServerAddress, CAdESCOM.CAPICOM_ENCODING_TYPE.CAPICOM_ENCODE_BASE64);    csd.VerifyCades(signature, CADESCOM_CADES_TYPE.CADESCOM_CADES_X_LONG_TYPE_1, true);  }  catch (Exception ex)  {    throw ex;  }  return Convert.FromBase64String(signature);}

Пробный запуск

Для подписания возьмем PDF-документ, который содержит надпись "Тестовое заявление.":

Больше для теста нам ничего не надоБольше для теста нам ничего не надо

Далее запустим программу и дождемся подписания файла:

Готово. Теперь можно приступать к проверкам.

Проверка в КриптоАРМ

Время создания ЭП заполнено:

Штамп времени на подпись есть:

Доказательства подлинности также заполнены:

В протоколе проверки есть блоки "Доказательства подлинности", "Штамп времени на подпись" и "Время подписания":

Важно отметить, что серийный номер параметров сертификата принадлежит TSP-сервису http://qs.cryptopro.ru/tsp/tsp.srf

Проверка на Госуслугах

Проверка в Контур.Крипто

Done.

Гайд написан с исследовательской целью - проверить возможность подписания документов УКЭП с помощью самописного сервиса на .NET Core 3.1 с формированием штампов подлинности и времени подписания документов.

Безусловно это решение не стоит брать в работу "как есть" и нужны некоторые доработки, но в целом оно работает и подписывает документы подписью УКЭП.

Это вообще законно?

С удовольствием узнаю ваше мнение в комментариях.

Ссылки на публичные источники

[1] CMS Advanced Electronic Signatures (CAdES) - https://tools.ietf.org/html/rfc5126#ref-ISO7498-2

[2] Internet X.509 Public Key Infrastructure Time-Stamp Protocol (TSP) - https://www.ietf.org/rfc/rfc3161.txt

[3] X.509 Internet Public Key Infrastructure Online Certificate Status Protocol - OCSP - https://tools.ietf.org/html/rfc2560

[4] Усовершенствованная квалифицированная подпись Удостоверяющий центр СКБ Контур (kontur.ru)

[5] Поддержка .NET Core (cryptopro.ru)

[6] http://qs.cryptopro.ru/tsp/tsp.srf - TSP-сервис КриптоПро

UPD1: Поменял в коде переменную, куда записываются байты файла подписи.

Также я забыл написать немного про подпись штампа времени - он подписывается сертификатом владельца TSP-сервиса. По гайду это ООО "КРИПТО-ПРО":

Источник: habr.com
К списку статей
Опубликовано: 13.03.2021 18:22:01
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Net

Разработка под windows

Net core

Укэп

C

Категории

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

  • Имя: Макс
    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