Гис жкх api python

Saved searches

Use saved searches to filter your results more quickly

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.

Этот пример демонстрирует реализацию ЭЦП для ГИС ЖКХ на Python и OpenSSL.

slavama/signature-demo

This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Sign In Required

Please sign in to use Codespaces.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching Xcode

If nothing happens, download Xcode and try again.

Launching Visual Studio Code

Your codespace will open once ready.

There was a problem preparing your codespace, please try again.

Latest commit

Git stats

Files

Failed to load latest commit information.

README.md

Пример ЭЦП XML-файла для ГИС ЖКХ

Этот пример демонстрирует реализацию ЭЦП для ГИС ЖКХ на Python и OpenSSL.

  1. Настройка окружения ======================
  1. Установить openssl версии старше 1.0
  2. Для поддержки ГОСТ добавить в конфигурационный файл:
openssl_conf = openssl_def [openssl_def] engines = engine_section [engine_section] gost = gost_section [gost_section] soft_load=1 default_algorithms = ALL 
openssl_conf = openssl_def [openssl_def] engines = engine_section [engine_section] gost = gost_section [gost_section] engine_id = gost dynamic_path = ./gost.dll default_algorithms = ALL 

Добавить в переменные окружения путь к конфигу OpenSSL:

OPENSSL_CONF=c:\OpenSSL-Win32\bin\openssl.cfg 
  1. Установить зависимости: pip install -r requirements.txt
  1. Использование ================ python sign.py cert.key in.xml f9f93de1-05b6-11e5-b4ae-1c6f65dfe2b1 > out.xml

About

Этот пример демонстрирует реализацию ЭЦП для ГИС ЖКХ на Python и OpenSSL.

Источник

Взаимодействие с ГИС ЖКХ с помощью stunnel и openssl по ГОСТу

Встала перед нами в полный рост задача наладить взаимодействие с ГИС ЖКХ. Согласно документации, предполагается использование небезызвестного отечественного ПО для шифрования туннеля и формирования ЭЦП по ГОСТу, но это не наш метод. Вооружившись гуглом и консолью, я и slavam реализовали необходимый функционал подручными средствами.
Всё необходимое ПО есть как на Linux, так и на Windows платформах, потому методику можно назвать мультиплатформенной.

Читайте также:  Source python extensions linux

Подготовка

  • Установка по ГОСТу шифрованного туннеля до серверов ГИС ЖКХ.
  • Формирование и отправка подписанного XML запроса.
  • Получение и проверка ответа.
# wget https://www.openssl.org/source/openssl-1.0.2g.tar.gz # tar -xvf openssl-1.0.2g.tar.gz # cd openssl-1.0.2g/ # yum groupinstall "Development Tools" # yum install zlib zlib-devel # ./config shared zlib enable-rfc3779 # make && make install # echo "/usr/local/ssl/lib/" > /etc/ld.so.conf.d/openssl.conf # ldconfig # /usr/local/ssl/bin/openssl ciphers | tr ":" "\n" | grep -i gost GOST2001-GOST89-GOST89 GOST94-GOST89-GOST89 # cat /usr/local/ssl/openssl.cnf ………… openssl_conf = openssl_def [openssl_def] engines = engine_section [engine_section] gost = gost_section [gost_section] engine_id = gost default_algorithms = ALL ………… 

Думаю, ничего сложного быть не должно и всё уже сотни раз описано. А в более свежих дистрибутивах модуль gost есть из коробки.

OpenSSL используется двояко: с ним собран stunnel, что-бы работал по ГОСТу; и утилита openssl вызывается из кода python-а для формирования и проверки подписей. Вызов openssl обусловлен тем, что не удалось из кода python-на задавать используемый крипто-модуль. Всё необходимое ПО есть как на Linux, так и на Windows платформах, потому методику можно назвать мультиплатформенной.

Для python-а сервера CentOS 6 нужно будет обновить библиотеку lxml, а для этого поставить несколько дополнительных пакетов:

# yum install libxml2 libxml2-devel libxslt libxslt-devel python-devel # pip install lxml --upgrade 

Так же нам потребуются файлы сертификата и закрытого ключа в формате PKCS12 (.pem). Получить их из eToken-а можно с помощью утилит вроде P12FromGostCSP или вручную. Если сделать это по каким-либо причинам не получается, то есть вариант работы с ключом «Рутокен ЭЦП» напрямую. На сайте есть подробные инструкции, как обучить этому OpenSSL и stunnel. Таким образом, задача сводится к предыдущей. У меня под рукой такого ключа не оказалось, потому проверить не удалось.

Криптотуннель по ГОСТу

Туннель поднимается с помощью Stunnel, который работает в режиме прокси. Нужно только научить его использовать модуль gost. Но тут есть момент — чтобы модуль инициализировался правильно, нужно слегка исправить исходники. Проблема, как я понял, связана с порядком инициализации модуля и методов. Итак:

# wget https://www.stunnel.org/downloads/stunnel-5.31.tar.gz # tar -xvf stunnel-5.31.tar.gz # cd stunnel-5.31 

Правим файл src/options.c и в конце функции » NOEXPORT char *engine_init(void) » добавляем вызов SSL_library_init();.

NOEXPORT char *engine_init(void) < if(engine_initialized) /* either first or already initialized */ return NULL; /* OK */ s_log(LOG_DEBUG, "Initializing engine #%d (%s)", current_engine+1, ENGINE_get_id(engines[current_engine])); if(!ENGINE_init(engines[current_engine])) < if(ERR_peek_last_error()) /* really an error */ sslerror("ENGINE_init"); else s_log(LOG_ERR, "Engine #%d (%s) not initialized", current_engine+1, ENGINE_get_id(engines[current_engine])); return "Engine initialization failed"; >#if 0 /* it is a bad idea to set the engine as default for all sections */ /* the "engine=auto" or "engineDefault" options should be used instead */ if(!ENGINE_set_default(engines[current_engine], ENGINE_METHOD_ALL)) < sslerror("ENGINE_set_default"); return "Selecting default engine failed"; >#endif s_log(LOG_INFO, "Engine #%d (%s) initialized", current_engine+1, ENGINE_get_id(engines[current_engine])); SSL_library_init(); engine_initialized=1; return NULL; /* OK */ > 
# ./configure --with-ssl=/usr/local/ssl --disable-libwrap # make && make install 

Файл конфигурации /etc/stunnel.conf:

client=yes # сертификат ГИС ЖКХ (тестовый). CAFile=/etc/crypto/CA-SIT.pem engine=gost sslVersion=TLSv1 engineDefault = ALL output=/var/log/stunnel.log DEBUG=4 # извлечённые с eToken-а. cert=/etc/crypto/public.pem key=/etc/crypto/private.key [pseudo-https] # адрес и порт сервера, который будет принимать запросы. accept = 10.1.5.133:8080 # адрес сервера ГИС ЖКХ, куда прокладываем туннель (тестовый). connect = 54.76.42.99:60045 ciphers = GOST2001-GOST89-GOST89 

Файлы сертификатов кладём в директорию /etc/crypto/. В общем случае, stunnel может работать под любым пользователем, но у нас пусть будет root.

#! /bin/bash # # stunnel Start/Stop Stunnel # # chkconfig: 2345 90 60 # description: launches Stunnel # processname: stunnel # config: /etc/stunnel.conf # Source function library. . /etc/init.d/functions # See how we were called. prog="Stunnel CryptoTunnel" RNG=PROGRAM export RNG start() < echo -n $"Starting $prog: " /usr/local/bin/stunnel /etc/stunnel.conf RETVAL=$? [ $RETVAL -eq 0 ] && success [ $RETVAL -ne 0 ] && failure echo return $RETVAL >stop() < echo -n $"Stopping $prog: " /usr/bin/killall /usr/local/bin/stunnel >/dev/null 2>&1 RETVAL=$? [ $RETVAL -eq 0 ] && success [ $RETVAL -ne 0 ] && failure echo return $RETVAL > restart() < stop start >case "$1" in start) start ;; stop) stop ;; restart) restart ;; *) echo $"Usage: $0 " exit 1 esac 
# curl http://10.1.5.133:8080/ext-bus-nsi-service/services/Nsi?wsdl       ……… 

Если вывод совсем не похож, то внимательно смотрим в лог файл /var/log/stunnel.log.

Формирование XMLDSig

Когда туннель до сервера ГИС ЖКХ настроен и работает, можно слать туда всякие запросы и получать нужные ответы. Запрос отправляется в виде XMLDSig, в котором содержится сам запрос, хеш этого запроса, хеш сертификата, сам сертификат, подпись хеша запроса с хешем сертификата и куча полей, всё это описывающих. Самое сложное как раз было раскрутить всю цепочку и получить XML, который успешно проходит проверку со стороны ГИС ЖКХ. Все подписываемые блоки берутся в каноническом виде, а получаемые подписи и хеш-суммы кодируются в BASE64.

Алгоритм формирования XMLDSig можно реализовать используя любой удобный язык программирования. Мы использовали python 2.7.11, демонстрационный код прилагается. Как пример, буду так же приводить консольный аналог.

0. Из сертификата достаются серийный номер и данные о выпустившем, генерируются необходимые id и запоминается текущее время.
1. С помощью любого soap клиента (например, suds на Python) формируется SOAP-запрос к серверу ГИС ЖКХ.

    2016-04-11T14:28:28 29f93de1-25b6-21e5-24ae-2c6f65dfe2b2 4eb0a7d6-6317-45cf-8974-10e75cbb0cbc    51   

Где SenderID — идентификатор управляющей компании, от лица которой делается запрос. MessageGUID — уникальный ID, генерируемый как пожелается. Тело — сам запрос с дополнительными полями. Id=»signed-element» — ID запроса, который указываем, как хотим и на который ориентируемся, подписывая запрос.

2. Берётся содержимое тега (точнее часть с Id и без первого и последнего символа перевода строки), канонизируется алгоритмом C14N (exclusive=True), считается от неё хеш-сумма по ГОСТу и выводится в виде BASE64. Получаем digest1 . Консольный аналог:

# cat in.xml ; echo 51 # cat in.xml | openssl dgst -engine gost -md_gost94 -binary | base64 

* openssl с поддержкой ГОСТ. Engine указан явно, но, настроив openssl.cnf, можно этого и не делать.

3. Берётся сертификат в x509, декодируется из BASE64, считается от него хеш-сумма и вывод кодируется в BASE64. Получаем digest2 .

4. Используя полученные данные, формируется содержимое тега (см. Шаблон), канонизируется алгоритмом C14N (exclusive=False) и от содержимого считается digest3 (BASE64).

5. Формируется блок , канонизируется алгоритмом C14N (exclusive=False), подписывается и кодируется в BASE64. Получается значение блока . Консольный аналог:

cat SignedInfo.xml | openssl dgst -sign private.key -engine gost -md_gost94 -binary | base64 

где SignedInfo.xml – уже канонизированный блок, без последнего перевода строки.

6. Все полученные значения вносятся в

    ">    -signedprops">       

Этот шаблон удалось сформировать расковыряв и проанализировав комплекс, который рекомендует использовать ГИС ЖКХ. Сам он находится в свободном доступе, но для работы требует СКЗИ КриптоПро CSP и СКЗИ Trusted Java 2.0.

7. Для того, чтобы проверить сформированную таким образом подпись, необходимо проделать все действия в обратном порядке. Консольный вариант проверки подписи:

# cat SignedInfo.xml | openssl dgst -engine gost -md_gost94 -verify <(openssl x509 -engine gost -in public.pem -pubkey -noout) -signature signature.sig 

где signature.sig – раскодированная из BASE64 подпись, а SignedInfo.xml проверяемый блок . целиком. Значения хеш-сумм просто сравниваются.

Демонстрационный код на python-е можно взять и использовать (на свой страх и риск) отсюда. Автор кода — Вячеслав (@slavam, RO). Подобный алгоритм можно реализовать средствами любого удобного языка, без необходимости покупки каких-либо дополнительных средств и компонентов. Вызов утилит OpenSSL из кода хоть и выглядит топорным, зато работает как на Linux так и на Windows платформе и позволяет отказаться от использования КриптоПро и дополнительных компонентов.
Система взаимодействия с ГИС ЖКХ у нас ещё на стадии создания, но получаемый XMLDSig проходит необходимые проверки.
Надеемся, эта статья облегчит кому-нибудь задачу по реализации подобного велосипеда.

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

UPD2
Чтобы завести OpenSSL под windows с поддержкой ГОСТ нужно:
1. Поставить OpenSSL от сюда, он уже с поддержкой GOST, в папке lib есть соответствующая библиотека: gost.lib .

2. В файле конфигурации явно указать его использование:

openssl_conf = openssl_def [openssl_def] engines = engine_section [engine_section] gost = gost_section [gost_section] engine_id = gost dynamic_path = ./gost.dll default_algorithms = ALL 
set OPENSSL_CONF=C:\OpenSSL-Win32\openssl.cnf 
C:\OpenSSL-Win32\bin>openssl.exe ciphers -v | find /I "gost" GOST2001-GOST89-GOST89 SSLv3 Kx=GOST Au=GOST01 Enc=GOST89(256) Mac=GOST89 GOST94-GOST89-GOST89 SSLv3 Kx=GOST Au=GOST94 Enc=GOST89(256) Mac=GOST89 

Cсылки

Источник

Оцените статью