Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

SignService — подписание документов ЭЦП

Русский | English

Настольное приложение (C# / Avalonia UI) для подписания документов электронной подписью (ЭЦП) в формате CMS/PKCS#7 и работы с файлами подписей. Логика подписания портирована из сервиса подписания документов ReportGGE.

Скачать: готовый SignService.exe (Windows x64, .NET не требуется) — на странице Releases.

Возможности

Подписание

  • Drag & drop файлов и целых папок в окно программы, добавление через «Обзор…», пакетное подписание со статусом по каждому файлу; приём путей аргументами командной строки («Открыть с помощью»);
  • откреплённая подпись (имя.sig рядом с документом — формат госпорталов) или прикреплённая (документ внутри .sig);
  • усиленный формат CAdES-BES по умолчанию: подписанные атрибуты signing-time и signing-certificate-v2 (RFC 5035, защита от подмены сертификата); certHash для ГОСТ-2012 считается Стрибогом (собственная реализация ГОСТ Р 34.11-2012, проверенная на векторах RFC 6986);
  • штамп времени (CAdES-T) по выбору: метка доверенного времени от службы TSA (RFC 3161), адрес настраивается; для ГОСТ-подписей запрос хешируется Стрибогом;
  • ГОСТ через КриптоПро: на Windows подпись создаётся нативным CryptoAPI (CryptSignMessage) — криптопровайдер сертификата (КриптоПро CSP для ГОСТ) выполняет операцию и при необходимости запрашивает PIN-код; OID хеша подбирается по типу ключа (ГОСТ Р 34.10-2012 256/512, 34.10-2001, RSA/ECDSA);
  • в подпись вкладывается вся цепочка сертификатов (для офлайн-проверки), цепочка кешируется для пакетного подписания.

Соподписание и проверка

  • подписи других лиц объединяются с вашей в один .sig: программа сама находит подписи документа в его папке по содержимому — имя файла подписи может быть любым («договор-.pdf .sig», .p7s, .p7m); у каждого файла выбирается «Добавить к „X.sig“ (8 подписантов)» или «Создать новую», а строка плана показывает, что произойдёт («будет добавлена подпись №9 к …»); переключатель «Добавить к существующей подписи / Создать новую» задаёт выбор по умолчанию. Подписи из других папок прикладываются кнопкой «+.sig» или перетаскиванием — к своему документу по содержимому;
  • перед заменой файла подписи без объединения и перед исключением подписантов программа спрашивает подтверждение и сохраняет резервную копию рядом; итог виден в строке файла: «Подписан: 9 (8 + ваша) → X.sig»;
  • повторная подпись тем же сертификатом заменяет свою старую, а не дублирует;
  • каждая объединяемая подпись проверяется криптографически: хеш документа, значение подписи и привязка сертификата CAdES — в том числе подписи КриптоПро с параметрами ГОСТ в signatureAlgorithm. Повреждённые подписи и подписи под другой версией исключаются с указанием подписанта; подписи, которые проверить не удалось (неизвестный алгоритм, нет сертификата), сохраняются и явно отмечаются;
  • приложенная подпись другого лица или смена сертификата возвращают уже подписанный файл в очередь — его можно соподписать;
  • входные подписи принимаются в DER/BER (включая неопределённые длины и «хвосты» файлов) и base64/PEM.

Инструменты (без создания подписи)

Операции доступны в меню «Инструменты» (с выбором файлов) и в контекстном меню файла из списка (ПКМ) — тогда берётся имя.sig рядом с документом.

  • Проверить ЭЦП… — проверка каждого подписанта CMS/CAdES: ГОСТ-2001, ГОСТ-2012 256/512, RSA и ECDSA без КриптоПро. Для откреплённой подписи выберите исходный документ; для прикреплённой он берётся из контейнера. Из контекстного меню («Подписанты и проверка ЭЦП…») проверка запускается сразу. Отчёт можно скопировать или сохранить в TXT;
  • Объединить .sig… — несколько файлов подписей склеиваются в один со всеми подписантами (принимаются и прикреплённые контейнеры — документ сохраняется); если документ известен (по имени или найден по содержимому), результат — «документ.sig», существующий файл не затирается;
  • Извлечь из .sig… — из криптоконтейнера достаются: вложенный документ (байт-в-байт), откреплённая подпись со всеми подписантами и отдельные .sig по каждому подписанту (в имени — ФИО из сертификата);
  • Разделить групповую подпись… — отдельный откреплённый .sig на каждого подписанта (вложенный документ сохраняется рядом);
  • Исключить подписанта из .sig… — подписант выбирается в списке (одинаковые ФИО различаются по серийному номеру сертификата); создаётся новый файл «имя (без подписанта).sig», исходный не меняется, последнего подписанта исключить нельзя;
  • Собрать контейнер… — документ упаковывается в прикреплённый .sig вместе с имеющимися подписями (обратная операция к извлечению);
  • Штамп на PDF… — копия документа с плашкой о подписании без подписи.

Доверенность (МЧД)

  • кнопка «Добавить доверенность…» — как в Контуре: выбираются файл МЧД (XML, формат EMCHD_1) и подпись руководителя (.sig; имя.xml.sig рядом подхватывается автоматически);
  • программа проверяет подпись руководителя открытым ключом сертификата, срок действия МЧД и то, что представитель в МЧД — владелец выбранного сертификата: личный ИНН (12 цифр) и СНИЛС сверяются, если указаны с обеих сторон; ИНН организации из сертификата с ИНН физлица не сравнивается;
  • сертификат руководителя, истёкший уже после выдачи МЧД, не отклоняет её — программа проверяет его на дату выдачи и предупреждает; истёкший до выдачи (или ещё не действовавший) — ошибка;
  • при подписании файлы МЧД (XML + .sig) копируются рядом с подписанным документом (в CMS-подпись МЧД не вкладывается — так же поступает Контур), а в визуальный штамп на PDF добавляется строка «Действует на основании МЧД № …»;
  • доверенность запоминается и перепроверяется в фоне при запуске и перед каждым пакетным подписанием (один раз на пакет).

Визуальный штамп на PDF

  • плашка «ДОКУМЕНТ ПОДПИСАН ЭЛЕКТРОННОЙ ПОДПИСЬЮ»: номер сертификата, владелец, срок действия, по желанию — дата подписания и логотип организации (PNG/JPEG);
  • параметры выбираются в диалоге перед операцией: страницы (первая, последняя, все или указанные, например «1,3-5»), дата, логотип; на каждой выбранной странице — отдельная плашка на каждого подписанта;
  • по умолчанию подписывается оригинал, а копия «имя (со штампом).pdf» — отдельный файл без подписи, который после каждого подписания пересоздаётся со всеми подписантами итоговой подписи (безопасно при соподписании: штамп не делает подписи недействительными);
  • отдельной галочкой доступен режим «подписывать копию со штампом» (штамп до подписи) — для случаев, когда принимающая сторона требует подпись именно под штампованным документом.

Сертификаты

  • выбор из хранилища «Текущий пользователь → Личное», фильтр просроченных, выбранный сертификат запоминается;
  • сохранение сертификата на компьютер (кнопка 💾), чтобы подписывать без подключённого ключа ЭЦП:
    • «в программе» — PFX-файл под паролем, виден только SignService;
    • «в хранилище Windows» — копия ключа ставится в системное хранилище, подписывать смогут и другие программы (КриптоАРМ, браузер и т.д.); работает и для сертификата с токена (экспорт + установка одним действием);
    • программа явно предупреждает о снижении безопасности; удаление — кнопкой 🗑 (PFX затирается; из хранилища удаляются только установленные программой записи); неэкспортируемые ключи сохранить нельзя — это ограничение токена/УЦ.

Прочее

  • лог операций всегда виден в главном окне — все действия с отметками времени;
  • окно «Настройки…»: штамп времени (CAdES-T) и адрес службы TSA;
  • окно «О программе»: версия, контакты автора, история версий, проверка обновлений;
  • автообновление: проверка новых версий на GitHub Releases при запуске (отключается) и обновление в один клик из окна «О программе» (Windows); прежний exe сохраняется резервной копией и восстанавливается, если новая версия не запустилась.

Доверие, отзыв и время подписи

Отчёт разделяет соответствие документу, значение подписи, привязку сертификата, цепочку доверия, статус отзыва и метку TSA. Корректная подпись сама по себе не подтверждает доверие к сертификату. Вложенный корень не становится доверенным: используются корни из хранилища ОС и явно выбранные в окне проверки сертификаты УЦ. Подписи сертификатов цепочки, CRL и OCSP проверяются управляемой библиотекой BouncyCastle.

По умолчанию проверка работает без сети. Для отзыва используются вложенные CRL и выбранные файлы .crl/.ocsp. Сетевые запросы к HTTP(S) службам CRL/OCSP УЦ включаются отдельной галочкой (настройка запоминается и действует и для МЧД). Недоступный файл выбранного доверенного корня пропускается с предупреждением. Просроченные, неподписанные, неполные (в том числе delta/indirect CRL) или недоступные доказательства дают неопределённый статус, а не «сертификат действителен»; данные об отзыве проверяются для всех сертификатов цепочки, кроме доверенного корня. Недостающие промежуточные сертификаты должны присутствовать в CMS или хранилище ОС.

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

МЧД перечитывается перед пакетным подписанием, проверяется и копируется как один снимок XML + SIG. Если сертификат руководителя истёк после выдачи МЧД, а метки TSA нет, время подписи не доказано — программа предупреждает и проверяет сертификат на дату выдачи. Конфликт с другим файлом МЧД останавливает операцию до сохранения подписи. Полномочия руководителя, содержание полномочий и отзыв самой МЧД в реестре не устанавливаются одной криптографической проверкой; при отсутствии подтверждений программа показывает предупреждение.

Требования

  • Windows 10/11 — готовый exe со страницы Releases (самодостаточный);
  • для создания ГОСТ-подписей — установленный КриптоПро CSP и личный сертификат;
  • проверка и объединение ГОСТ-подписей работают без КриптоПро на Windows/Linux/macOS;
  • сборка из исходников: .NET 8 SDK (Windows/Linux/macOS; вне Windows подписание доступно алгоритмами платформы — RSA/ECDSA, ГОСТ — только через CSP на Windows).

Сборка и запуск

dotnet build SignService.sln -c Release
dotnet run --project src/SignService
dotnet run --project tests/SignService.Tests -c Release   # тесты

На рабочем компьютере используйте -- --skip-user-store в конце команды тестов, чтобы пропустить сценарии, изменяющие личное хранилище сертификатов и данные приложения. Полный набор запускается в изолированном CI на Linux и Windows. Управляемые тесты проверки ГОСТ, CRL/OCSP и TSA выполняются без КриптоПро и OpenSSL; интерфейс проверяется без экрана (Avalonia.Headless).

Публикация самодостаточного exe:

dotnet publish src/SignService -c Release -r win-x64 --self-contained true \
  -p:PublishSingleFile=true \
  -p:IncludeNativeLibrariesForSelfExtract=true \
  -p:EnableCompressionInSingleFile=true \
  -o publish

Как пользоваться

  1. Запустите программу — в списке появятся сертификаты с закрытым ключом.
  2. Выберите сертификат, режим подписи и «Добавить к существующей подписи» или «Создать новую»; у каждого файла видно, к какой подписи добавится ваша. При необходимости включите штамп на PDF (параметры спросит диалог), штамп времени — в «Настройках…».
  3. Перетащите файлы в окно (или «Обзор…») и нажмите «Подписать» — рядом с каждым файлом появится имя.sig.
  4. Операции с готовыми подписями — в меню «Инструменты» и в контекстном меню файла (ПКМ); ход работы виден в логе.

История изменений — в CHANGELOG.md и в окне «О программе».

Автор

Зайнуллин Марат Илгамович

Структура проекта

src/SignService/
├── Services/
│   ├── CertificateProvider.cs   # доступ к сертификатам (X509Store)
│   ├── DocumentSigner.cs        # подпись CMS/PKCS#7: ГОСТ-OID, цепочка, кеш
│   ├── NativeSign.cs            # CryptSignMessage (CryptoAPI) — ГОСТ через КриптоПро
│   ├── CadesAttributes.cs       # атрибуты CAdES-BES: signing-time, signing-cert-v2
│   ├── Streebog.cs              # ГОСТ Р 34.11-2012 для certHash (векторы RFC 6986)
│   ├── CmsMerger.cs             # объединение/разбор/сборка подписей на ASN.1
│   ├── CmsExtractor.cs          # файловые операции: извлечение, объединение, разделение
│   ├── SignatureDiscovery.cs    # поиск подписей документа по содержимому
│   ├── SignatureVerifier.cs     # проверка подписантов (BouncyCastle, ГОСТ без CSP)
│   ├── CertificateValidator.cs  # цепочка доверия (PKIX) и хранилища ОС
│   ├── RevocationChecker.cs     # отзыв сертификатов: CRL и OCSP
│   ├── PowerOfAttorneyService.cs # МЧД: разбор EMCHD_1, проверка, копирование
│   ├── BerDer.cs                # нормализация BER → definite-length
│   ├── AtomicFile.cs            # запись файлов через временный файл
│   ├── CertificateVault.cs      # сертификат на ПК: PFX и хранилище Windows
│   ├── TimestampClient.cs       # штамп времени TSA (RFC 3161) для CAdES-T
│   ├── PdfStamper.cs            # визуальный штамп на PDF (страницы, подписанты, лого)
│   ├── UpdateService.cs         # автообновление через GitHub Releases
│   └── AppSettings.cs           # настройки (сертификат, режимы, штампы, доверие)
├── ViewModels/                  # MVVM: главное окно, файлы, сертификаты
└── Views/                       # окна: главное, проверка ЭЦП, штамп, подписанты, настройки…
tests/SignService.Tests/         # интеграционные тесты и смоук интерфейса (CI: Linux и Windows)
.github/release/                 # сборка архива релиза: скрипт и тексты лицензий

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages