Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Утилита для подписания XML-документов по стандарту XMLDSig с требованиями ГИИС ДМДК, используя КриптоПро CSP

License

imdeniil/giis-signer

Repository files navigation

GIIS DМДК XML Signer

Python Version License: MIT Platform

Утилита для подписания XML-документов по стандарту XMLDSig с требованиями ГИИС ДМДК (Государственная информационная система мониторинга драгоценных металлов и драгоценных камней), используя КриптоПро CSP.

Особенности

  • ✅ Подписание XML-документов по стандарту XMLDSig
  • ✅ Поддержка алгоритмов ГОСТ Р 34.10-2012 и ГОСТ Р 34.11-2012
  • ✅ Интеграция с КриптоПро CSP через COM-интерфейс
  • ✅ Применение Exclusive Canonicalization (ExcC14N)
  • ✅ Поддержка SMEV-трансформации для государственных систем
  • ✅ GUI и CLI интерфейсы
  • ✅ Standalone exe-файлы (без установки Python)
  • ✅ Готов к использованию в производстве

Безопасность

Анализ безопасности

Последний анализ: GIIS-Signer-GUI.exe на VirusTotal

Exe-файлы созданы с помощью PyInstaller и содержат:

  • Весь код Python приложения
  • Необходимые библиотеки и зависимости
  • Python runtime

⚠️ Важно: Exe-файлы НЕ содержат и НЕ хранят закрытые ключи. Все криптографические операции выполняются через КриптоПро CSP с использованием сертификатов из хранилища Windows.

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

Связанные репозитории

Проект использует следующие специализированные библиотеки для работы с ГОСТ криптографией:

  • xmlcanon - Реализация Exclusive XML Canonicalization (ExcC14N) для Python
  • smev-transform - Реализация SMEV-трансформации для электронной подписи государственных документов
  • giis-srv-selector - Утилита для выбора сервера ГИИС ДМДК (тестовый/продуктовый)

Все библиотеки разработаны специально для обеспечения совместимости с требованиями ГИИС ДМДК и других государственных информационных систем РФ.

Требования

Системные требования

  • ОС: Windows (из-за зависимости от КриптоПро CSP)
  • Python: >= 3.8
  • КриптоПро CSP: Установлен и настроен
  • КриптоПро ЭЦП Browser plug-in: Установлен (скачать)
  • Сертификат: ГОСТ Р 34.10-2012 (256 бит) в хранилище сертификатов Windows

Python-зависимости

  • pywin32>=305 - для работы с COM-интерфейсом КриптоПро
  • lxml>=4.9.0 - для обработки XML

Установка

1. Установка КриптоПро CSP

Скачайте и установите КриптоПро CSP с официального сайта.

Также установите КриптоПро ЭЦП Browser plug-in для работы с COM-интерфейсом.

2. Установка Python и uv

Убедитесь, что у вас установлен Python 3.8 или выше.

Установите uv package manager:

# Windows (PowerShell)
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"

Или используйте pip:

pip install uv

3. Установка утилиты

Вариант А: Из Git репозитория

# Клонирование репозитория
git clone https://github.com/yourusername/giis-signer.git
cd giis-signer

# Создание виртуального окружения и установка зависимостей
uv venv
uv sync
uv pip install -e .

Вариант Б: Копирование папки на новый ПК

Если вы скопировали папку проекта на новый компьютер:

# Перейдите в папку проекта
cd путь\к\giis-signer

# Создайте виртуальное окружение
uv venv

# Установите зависимости из lockfile
uv sync

# Установите пакет в editable режиме для регистрации entry points
uv pip install -e .

Запуск GUI приложения:

# Вариант 1: Через entry point (рекомендуется)
.venv\Scripts\giis-signer-gui.exe

# Вариант 2: Через Python модуль
.venv\Scripts\python.exe -m giis_signer.gui.app

Запуск CLI:

# Вариант 1: Через entry point
.venv\Scripts\giis-signer.exe template.xml -t <thumbprint> -o signed.xml

# Вариант 2: Через Python модуль
.venv\Scripts\python.exe -m giis_signer.cli template.xml -t <thumbprint> -o signed.xml

Использование

GUI приложение (Рекомендуется)

Запустите GUI приложение:

giis-signer-gui

Возможности GUI:

  • ✅ Интуитивно понятный интерфейс
  • ✅ Двухпанельный режим: входной XML → подписанный XML
  • ✅ Импорт/экспорт XML файлов
  • ✅ Копирование результата в буфер обмена
  • ✅ Выбор сертификата из списка с подробной информацией
  • ✅ Автосохранение последнего выбранного сертификата
  • ✅ Кнопки очистки полей (по отдельности и вместе)
  • ✅ Поддержка темной и светлой темы
  • ✅ Сохранение размера окна и последних директорий
  • ✅ Авто-определение Element ID для подписания из XML
  • ✅ Возможность ручной корректировки Element ID
  • ✅ Кнопка обновления Element ID (активируется при ручном изменении)
  • ✅ Неблокирующие toast-уведомления вместо модальных окон

Командная строка

Базовый пример (Element ID определяется автоматически)

giis-signer template.xml -t c755d5b4b7e1554b632f0c989427eba47b176c3a -o signed.xml

Примечание: Element ID автоматически определяется из XML. Если не найден, используется "body".

Пример с указанием субъекта сертификата

giis-signer template.xml -s "CN=Иванов Иван Иванович" -o signed.xml

Пример с явным указанием Element ID

giis-signer input.xml -t <thumbprint> -e "requestBody" -o output.xml

Пример с кастомными параметрами

giis-signer input.xml -t <thumbprint> -e "RequestBody" -n "Signature" -o output.xml

Параметры CLI

Параметр Описание Обязательный
input Путь к входному XML-файлу (SOAP-шаблон) ✅ Да
-o, --output Путь к выходному файлу (stdout если не указан) ❌ Нет
-t, --thumbprint Отпечаток сертификата (SHA1, HEX) ⚠️ Один из -t или -s
-s, --subject Имя субъекта сертификата ⚠️ Один из -t или -s
-e, --element-id ID элемента для подписания (авто-определение или body) ❌ Нет
-n, --signature-element Имя элемента для вставки подписи (по умолчанию: CallerSignature) ❌ Нет

Использование как библиотеки

from giis_signer import CryptoProSigner, XMLSigner

# Инициализация подписанта
signer = CryptoProSigner(thumbprint="c755d5b4b7e1554b632f0c989427eba47b176c3a")

# Поиск сертификата
certificate = signer.find_certificate()
print(f"Найден сертификат: {certificate.SubjectName}")

# Создание XML подписанта
xml_signer = XMLSigner(signer)

# Чтение XML-шаблона
with open("template.xml", "r", encoding="utf-8") as f:
    soap_xml = f.read()

# Подписание документа
signed_xml = xml_signer.sign_soap_request(
    soap_xml,
    element_id="body",
    signature_element_name="CallerSignature"
)

# Сохранение результата
with open("signed.xml", "w", encoding="utf-8") as f:
    f.write(signed_xml)

Формат SOAP-документа

Входной XML-документ должен иметь следующую структуру:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                  xmlns:ns="urn://xsd.dmdk.goznak.ru/exchange/3.0">
   <soapenv:Header/>
   <soapenv:Body>
      <ns:SendGetContractorRequest>
        <ns:CallerSignature></ns:CallerSignature>
        <ns:RequestData id="body">
           <ns:INN>7813252159</ns:INN>
        </ns:RequestData>
      </ns:SendGetContractorRequest>
   </soapenv:Body>
</soapenv:Envelope>

Ключевые элементы:

  • id="body" - элемент, который будет подписан (Element ID может быть любым)
  • <ns:CallerSignature> - элемент, куда будет вставлена подпись

Примечание: В GUI приложении Element ID автоматически определяется из XML по паттерну <ns:RequestData id="...">. Значение можно изменить вручную перед подписанием.

Алгоритм подписания

  1. Каноникализация ExcC14N → применяется к элементу с id="body"
  2. SMEV-трансформация → применяется к результату каноникализации
  3. Хеширование ГОСТ Р 34.11-2012 → вычисление дайджеста трансформированных данных
  4. Формирование SignedInfo → создание метаданных подписи с DigestValue
  5. Каноникализация SignedInfo → применение ExcC14N к SignedInfo
  6. Подписание → создание подписи с помощью КриптоПро (ГОСТ Р 34.10-2012)
  7. Реверс подписи → обязательное требование КриптоПро CSP
  8. Формирование Signature → создание финальной XML-структуры с подписью

Поддерживаемые алгоритмы

Тип Алгоритм URI
Каноникализация Exclusive XML Canonicalization 1.0 http://www.w3.org/2001/10/xml-exc-c14n#
Трансформация SMEV Transform urn://smev-gov-ru/xmldsig/transform
Подпись ГОСТ Р 34.10-2012 (256 бит) urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-256
Хеширование ГОСТ Р 34.11-2012 (256 бит) urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-256

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

giis-signer/
├── giis_signer/               # Основной пакет
│   ├── __init__.py            # Экспорты модуля
│   ├── cli.py                 # CLI-интерфейс
│   ├── cryptopro_signer.py    # Интеграция с КриптоПро CSP
│   ├── xml_signer.py          # Формирование XMLDSig подписи
│   ├── diagnostics.py         # Утилиты диагностики
│   └── gui/                   # GUI приложение
│       ├── __init__.py        # Инициализация модуля
│       ├── app.py             # Главное окно приложения
│       ├── certificate_dialog.py      # Диалог выбора сертификата
│       ├── certificate_manager.py     # Менеджер сертификатов
│       ├── config.py          # Конфигурация и настройки
│       └── toast.py           # Toast-уведомления
├── examples/                  # Примеры шаблонов
│   ├── template.xml           # Базовый SOAP-шаблон
│   └── template_custom_id.xml # Шаблон с кастомным Element ID
├── docs/                      # Документация
│   ├── TRANSIT.md             # Актуальное состояние проекта
│   ├── CHANGELOG.md           # История версий
│   ├── CRYPTOPRO_COM.md       # Документация COM-интерфейса
│   ├── CLASSES.md             # Структура классов
│   ├── FILES.md               # Файловая структура
│   ├── TECH.md                # Технический стек
│   └── Эталонный алгоритм СМЭВ3 на java.md
├── dist/                      # Сборки приложения
│   ├── GIIS-Signer-GUI.exe    # GUI исполняемый файл
│   ├── GIIS-Signer-CLI.exe    # CLI исполняемый файл
│   └── README.txt             # Инструкция для пользователей
├── giis-signer-gui.spec       # Спецификация сборки GUI
├── giis-signer-cli.spec       # Спецификация сборки CLI
├── giis-signer-gui.manifest   # Windows manifest для GUI
├── main_logo.ico              # Иконка приложения
├── main_logo.svg              # Векторный логотип
├── pyproject.toml             # Конфигурация проекта
├── uv.lock                    # Lockfile зависимостей
├── README.md                  # Этот файл
└── LICENSE                    # Лицензия MIT

Отладка и диагностика

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

python -m giis_signer.diagnostics --check-cryptopro

Проверяет:

  • Доступность COM-объектов КриптоПро
  • Список доступных сертификатов в хранилище

Диагностика подписи

# Краткая проверка
python -m giis_signer.diagnostics --check-signature signed.xml

# Полная диагностика
python -m giis_signer.diagnostics --check-signature signed.xml --full

Проверяет:

  • Корректность структуры подписи
  • Валидность DigestValue
  • Соответствие требованиям ГИИС ДМДК

Использование в коде

from giis_signer import check_cryptopro_available, list_certificates, check_signature

# Проверка КриптоПро
if check_cryptopro_available():
    list_certificates()

# Проверка подписи
is_valid = check_signature("signed.xml", verbose=True)

Известные особенности

Критические требования

  • ⚠️ DigestValue - ОБЯЗАТЕЛЬНО в формате Base64 (не HEX)
  • ⚠️ Реверс подписи - ОБЯЗАТЕЛЕН для совместимости с КриптоПро
  • ⚠️ Порядок трансформаций - ExcC14N → SMEV (не наоборот!)
  • ⚠️ Атрибут id - использовать маленькие буквы: id="body" (не Id или ID)
  • ⚠️ Форматирование - не изменяйте форматирование подписанного XML, это нарушит целостность

Поиск отпечатка сертификата

Windows:

  1. Откройте certmgr.msc
  2. Перейдите в "Личные" → "Сертификаты"
  3. Откройте нужный сертификат → вкладка "Состав"
  4. Найдите поле "Отпечаток" и скопируйте значение
  5. Удалите пробелы: c7 55 d5 b4...c755d5b4...

PowerShell:

Get-ChildItem Cert:\CurrentUser\My | Select-Object Subject, Thumbprint

Устранение неполадок

Ошибка: "Недопустимая строка с указанием класса"

Причина: КриптоПро CSP не установлен или COM-объекты не зарегистрированы.

Решение:

  1. Убедитесь, что КриптоПро CSP установлен
  2. Перезапустите компьютер после установки
  3. Проверьте версию КриптоПро (требуется 4.0 или выше)

Ошибка: "Сертификат не найден"

Причина: Неверный отпечаток или сертификат отсутствует в хранилище.

Решение:

  1. Проверьте отпечаток (без пробелов, верхний регистр)
  2. Убедитесь, что сертификат находится в хранилище "Личные"
  3. Используйте tests/test_com.py для просмотра доступных сертификатов

Ошибка ГИИС ДМДК: код -12 (нарушена целостность)

Причина: Проблема с каноникализацией SignedInfo.

Решение:

  1. Убедитесь, что используется актуальная версия утилиты
  2. Не изменяйте форматирование подписанного XML вручную
  3. Проверьте соответствие шаблона требованиям ГИИС ДМДК

Вклад в проект

Приветствуются любые улучшения проекта:

  1. Форкните репозиторий
  2. Создайте ветку для изменений (git checkout -b feature/improvement)
  3. Зафиксируйте изменения (git commit -am 'Add new feature')
  4. Отправьте в репозиторий (git push origin feature/improvement)
  5. Создайте Pull Request

Лицензия

Проект распространяется под лицензией MIT.

Авторы

Проект разработан для работы с ГИИС ДМДК (Государственная информационная система мониторинга драгоценных металлов и драгоценных камней).

Поддержка

При возникновении проблем:

  1. Проверьте раздел Устранение неполадок
  2. Изучите документацию в папке docs/
  3. Создайте Issue в репозитории с подробным описанием проблемы

Благодарности

  • КриптоПро - за разработку КриптоПро CSP
  • SMEV - за спецификацию SMEV-трансформации
  • Сообщество разработчиков - за вклад в проект

⚠️ Важно: Утилита предназначена исключительно для легального использования в соответствии с законодательством Российской Федерации. Убедитесь, что у вас есть все необходимые права и лицензии на использование КриптоПро CSP и ГОСТ-сертификатов.

About

Утилита для подписания XML-документов по стандарту XMLDSig с требованиями ГИИС ДМДК, используя КриптоПро CSP

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •  

Languages