Универсальный c использованием ГОСТ сертификата / Хабр

Содержание
  1. Введение
  2. Небольшое введение в механизм engine openssl и подключение engine gost
  3. Build form sh script
  4. Certification authority (ca)
  5. Examples
  6. How to build
  7. Internet explorer
  8. License
  9. Mozilla firefox
  10. Usage in other dockerfiles
  11. Библиотека openssl
  12. Добавление алгоритма цифровой подписи
  13. Добавление алгоритмов хеширования и симметричного шифрования
  14. Добавление нового алгоритма цифровой подписи
  15. Инфраструктура открытых ключей: удостоверяющий центр на базе утилиты openssl и sqlite3 (посткриптум)
  16. Как добавить поддержку шифрования по гост р 34.10-2021 в openssl 1.1.1d на debian 9 stretch | it-блог жаконды
  17. Компиляция файлов
  18. Конфигурирование nginx
  19. Корневой сертификат сбербанка
  20. Настройка openssl для работы с токенами (на примере рутокен)
  21. Обновление библиотеки openssl
  22. Пишем тестовую программу
  23. Правка и перекомпиляция php
  24. Преобразуем выданный ключ и сертификат в формат, понятный openssl
  25. Провайдер xyz provider
  26. Реализация алгоритма хеширования
  27. Реализация алгоритма шифрования
  28. Регистрация криптопровайдера xyzcsp.dll
  29. Результаты работы
  30. Сертификаты для тестирования
  31. Собираем nginx
  32. Создание приватного ключа и сертификата для принципала, kdc и уц
  33. Создание универсального патча

Введение

Протокол Kerberos 5 сейчас активно используется для аутентификации. Особенностью данного протокола является то, что он осуществляет аутентификацию, базируясь на четырех китах:

  1. Симметричное шифрование;
  2. Хеширование;
  3. ЭЦП;
  4. Третья доверенная сторона.

Начиная с пятой версии появилась возможность использовать еще асимметричное шифрование (для электронной подписи). Более подробно на работе протокола Kerberos останавливаться не имеет смысла, ибо описание алгоритма можно посмотреть тут.

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

легко и просто

собственные алгоритмы в

. Добавлять же мы будем наши отечественные алгоритмы: ГОСТ 28147-89 (aka Магма), ГОСТ Р 34.11-2021 (aka Стрибог) и ГОСТ Р 34.10-2021 (хотелось бы тоже иметь для него aka, но я не знаю:(). Готовое решение для данных алгоритмов можно его найти в

. На стороне клиента мы будем использовать аппаратные реализации алгоритмов ГОСТ в Рутокене ЭЦП 2.0 и их программные реализации в engine GOST для openssl. Но самый безопасный вариант хранения ключей – когда они генерируются непосредственно на Рутокене и никогда не покидают его память во время криптографических операций. Для такого варианта работы потребуется rtengine.

Перед тем, как приступить к внедрению алгоритмов, опишем основные места, где будут производится изменения. Внутри директории src/lib/crypto/ находятся реализации всех алгоритмов, отвечающих за симметричную криптографию и хеширование. В ней имеются 2 реализации этих криптографических алгоритмов: встроенная(builtin) и openssl.

Дабы сэкономить время и место, мы, естественно, будем добавлять реализации алгоритмов с помощью openssl, в котором они уже есть (ну или почти есть, но об этом чуть позже). Для добавления же асимметричных алгоритмов, нужно будет подправить плагин src/plugins/preauth/pkinit

Небольшое введение в механизм engine openssl и подключение engine gost

Engine в openssl – это небольшая динамическая библиотека, которую openssl подгружает в runtime по требованию. Каждая такая библиотека, должна содержать в себе определенные символы (функции) для загрузки необходимых алгоритмов. В данной работе мы воспользуемся engine gost, который содержит в себе все необходимые отечественные криптографические алгоритмы.

Установка дичайше проста, например, и происходит следующим образом:

  1. Выкачиваете из репозитория реализацию данного энджина.

  2. собираете библиотеку с ним (mkdir build && cd build && cmake… && make):

    mkdir build
    cd build
    cmake ..
    make

  3. В директории bin (КОТОРАЯ ПОЯВИТСЯ В КОРНЕВОМ КАТАЛОГЕ ПРОЕКТА!!!) будет лежать динамическая библиотека gost.so – это и есть наш энджин. Его нужно будет перенести в директорию, где хранятся энджины openssl. Узнать месторасположение данной директории можно с помощью:

    openssl version -a | grep ENGINESDIR

  4. Дело за последним – нужно сказать openssl, где находится данный энджин и как он называется. Сделать можно это с помощью изменения файла конфигурации openssl.cnf. Месторасположение которого можно узнать с помощью:

    openssl version -a | grep OPENSSLDIR

    В конец данного файла нужно будет внести следующее содержимое:

    # в начало файла написать
    openssl_conf = openssl_def
    
    ...
    
    # в конец файла
    # OpenSSL default section
    [openssl_def]
    engines = engine_section
    
    # Engine section
    [engine_section]
    gost = gost_section
    
    # Engine gost section
    [gost_section]
    engine_id = gost
    dynamic_path = /path/to/engines/dir/with/gost.so
    default_algorithms = ALL
    init = 0

После этого данный энджин должен появится в openssl. Проверить его работоспособность можно заставив, например, сгенерировать приватный ключ в файле по ГОСТ Р 34.10-2021:

openssl genpkey -engine gost -algorithm gost2021_512 -pkeyopt paramset:A -out client_key.pem

Флаг -engine как раз говорит о том, какой engine нужно подгрузить перед началом работы для того, чтобы стал виден алгоритм генерации ключей для ГОСТ Р 34.10-2021.

Build form sh script

chmod  x build-openssl-gost.sh
sh build-openssl-gost.sh

Certification authority (ca)

In Russia, it is common to issue GOST-certificates signed by CA which are not worldwide trusted.
In this case you get error. For example, curl: (60) SSL certificate problem: unable to get local issuer certificate.
To solve this problem you have two options: 1) do not verify CA (not recommended), 2) find and use CA.

Examples

To show certificate of host with GOST

To send a file to host with POST and save the response into new file

To generate new key and certificate with Signature Algorithm: GOST R 34.11-94 with GOST R 34.10-2001

openssl req -x509 -newkey gost2001 -pkeyopt paramset:A -nodes -keyout key.pem -out cert.pem

To sign file with electronic signature by GOST using public certificate (-signer cert.pem),
private key (-inkey key.pem), with opaque signing (-nodetach),
DER as output format without including certificate and attributes (-nocerts -noattr):

openssl cms -sign -signer cert.pem -inkey key.pem -binary -in file.txt -nodetach -outform DER -nocerts -noattr -out signed.sgn

To extract data (verify) from signed file (DER-format) using public certificate (-certfile cert.pem)
issued by CA (-CAfile cert.pem) (the same because cert.pem is self-signed):

openssl cms -verify -in signed.sgn -certfile cert.pem -CAfile cert.pem -inform der -out data.txt

How to build

You can pull my docker container: docker pull gosha20777/openssl-gost:dev. if you want to build a docker image yourself or build it into your host mashine, see the instructions below.

Internet explorer

Универсальный  c использованием ГОСТ сертификата / Хабр

License

MIT License.

Mozilla firefox

Универсальный  c использованием ГОСТ сертификата / Хабр

Usage in other dockerfiles

Compiled libraries can be used in other Dockerfiles with multi-stage approach. Basic template is in any-gost directory.
Working example with PHP is in php-fpm-gost directory.

There some notices:

  • OpenSSL and cURL are build in custom directory /usr/local/ssl and usr/local/curl
    which contain bin, include, lib.
  • Before compiling the main Dockerfile folders /usr/local/ssl and usr/local/curl should be copied into new image.
  • During building packages openssl and curl can be installed and overwrite new /usr/bin/openssl and /usr/bin/curl.
  • Specify paths of libraries in configuring scripts to new locations.

Библиотека openssl

Сборку OpenSSL из исходников оставим за кадром, заметим только, что это несложно, требуется наличие установленного

и MS Visual Studio, для компиляции нужно следовать инструкциям в файле Install.W32, после этого получим в директории C:xyzcspopenssl-1.0.0etmp32dll множество объектных файлов, которые я для простоты собрал в один файл openssl.lib, который и использовал в своем проекте.

Файл flist.txt:

Добавление алгоритма цифровой подписи

Ура! Мы приступаем к финальному разделу данной статьи и попробуем добавить собственный алгоритм электронной подписи. Не стоит пугаться, его добавить проще чем что-либо еще, так что давайте поскорее приступим… Хотя нет, подождите, для начала небольшая ремарка.

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

Ребята, не стоит вскрывать эту тему. Вы молодые, шутливые, вам все легко. Это не то. Это не Чикатило и даже не архивы спецслужб. Сюда лучше не лезть. Серьезно, любой из вас будет жалеть. Лучше закройте тему и забудьте, что тут писалось. Я вполне понимаю, что данным сообщением вызову дополнительный интерес, но хочу сразу предостеречь пытливых — стоп. Остальные просто не найдут.

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

Добавление алгоритмов хеширования и симметричного шифрования

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

Добавление нового алгоритма цифровой подписи

Алгоритмы ЭЦП добавить куда проще чем те, что рассматривались ранее – придется заменить всего-то 2 файли! src/plugins/preauth/pkinit/pkcs11.h и src/plugins/preauth/pkinit/pkinit_crypto_openssl.c

Инфраструктура открытых ключей: удостоверяющий центр на базе утилиты openssl и sqlite3 (посткриптум)

Универсальный  c использованием ГОСТ сертификата / Хабр

В одном из комментариев, присланным участником

garex

, в ответ на

заявление

:

Но сегодня в стандартной версии openssl отсутствует поддержка как ГОСТ Р 34.11-2021, так и ГОСТ Р 34.10-2021. Более того в версии 1.1 поддержка криптографии ГОСТ исключена из стандартной поставки («The GOST engine was out of date and therefore it has been removed.»)

было сказано:

Чем не устраивает вот эта, которую «убрали?» github.com/gost-engine/engine
Пример билда: github.com/rnixik/docker-openssl-gost/blob/master/Dockerfile

Выло решено протестировать эту версию openssl в составе УЦ

CAFL63

. Используя указанный пример билда, сам openssl и ГОСТ-ый engine собрались и установились без всяких проблем (все тестировалось в среде Linux и устанавливалось в каталог /usr/local/ssl). Естественно, для работы с ГОСТ-ой криптографией (речь идет о ГОСТ Р 34.10-2021, ГОСТ Р 34.11-2021) надо прописать подключение engine-а gost.so в конфигурационной файле openssl.cnf:

 . .
# OpenSSL default section
[openssl_def]
engines = engine_section
# Engine scetion
[engine_section]
gost = gost_section
# Engine gost section
[gost_section]
engine_id = gost
dynamic_path = /usr/local/ssl/lib/engines-1.1/gost.so
default_algorithms = ALL
CRYPT_PARAMS = id-Gost28147-89-CryptoPro-A-ParamSet
. . . 

Проверить подключение гостового engine-а можно выполнив команду:

bash-4.3$ /usr/local/ssl/bin/openssl  ciphers
. . . 
GOST2021-GOST8912-GOST8912:GOST2001-GOST89-GOST89
. . .
bash-4.3$

Для просмотра поддерживаемых ГОСТ-вых алгоритмов хэширования достаточно выполнить следующую команду:

bash-4.3$ /usr/local/ssl/bin/openssl  list –digest-algorithms| grep md_gost 
md_gost12_256 
md_gost12_512 
md_gost94 
bash-4.3$

Как видно, с поддержкой российской криптографии в этой версии openssl с подключенным engine-ом все хорошо.

Если подключить утилиту openssl (Средства->Настройки->Системные) в ранее созданном УЦ, то на первый взгляд все заработает. Можно будет просмотреть и запросы и сертификаты. При этом все поля, входящие в DN (отличительное имя) (ИНН, ОГРН, СНИЛС) отображаются верно. Но вот расширения, типа issuerSignTool, subjectSignTool и другие, openssl отказывается поминать:

image

Следует отметить, указанные расширения являются неотъемлемой частью СКПЭП (квалифицированный сертификат ключа проверки электронной подписи), требования к которому утверждены приказом ФСБ от 27 декабря 2021 г. N 795.

Анализ утилиты openssl показал, что она не поддерживает расширения isserSignTool, objectSignTools и другие, введенные ТК-26 для СКПЭП:


Error Loading request extension section v3_req
139974322407168:error:22097081:X509 V3 routines:do_ext_nconf:unknown extension:crypto/x509v3/v3_conf.c:82:
139974322407168:error:22098080:X509 V3 routines:X509V3_EXT_nconf:error in extension:crypto/x509v3/v3_conf.c:47:name=subjectSignTool, value=Наименование СКЗИ пользователя

Error Loading request extension section v3_req
140154981721856:error:22097081:X509 V3 routines:do_ext_nconf:unknown extension:crypto/x509v3/v3_conf.c:82:
140154981721856:error:22098080:X509 V3 routines:X509V3_EXT_nconf:error in extension:crypto/x509v3/v3_conf.c:47:name=subjectSignTool, value=Наименование СКЗИ пользователя

Error Loading extension section cert_ext
140320065406720:error:0D06407A:asn1 encoding routines:a2d_ASN1_OBJECT:first num too large:crypto/asn1/a_object.c:61:
140320065406720:error:2208206E:X509 V3 routines:r2i_certpol:invalid object identifier:crypto/x509v3/v3_cpols.c:135:section:,name:KC1ClassSignTool,value:
140320065406720:error:22098080:X509 V3 routines:X509V3_EXT_nconf:error in extension:crypto/x509v3/v3_conf.c:47:name=certificatePolicies, value=KC1ClassSignTool, KC2ClassSignTool
..

В связи с этим, УЦ CAFL63 также отказывался создавать запросы и выпускать сертификаты на openssl, так как он строго следил за соблюдением требований к СКПЭПЭ:

Универсальный  c использованием ГОСТ сертификата / Хабр

Вместе с тем, порой эти требования бывают излишними, например, при использовании сертификатов в учебном процессе, для внутрикорпоративного документооборота (подписание, шифрование документов), для доступа по https к корпоративным системам (сайты, порталы и т.д, так называемые, SSL-сертификаты).
Исходя их этого была проведена доработка CAFL63. Теперь стало возможным не заполнять поля расширений (Средства->Настройки->Системные):

Универсальный  c использованием ГОСТ сертификата / Хабр

Утилита CAFL63 позволяет просматривать сторонние запросы (Сертификаты->Просмотреть сторонний сертификат или кновка «Просмотр внешнего X509» на вкладке «Сертификаты»), но с тем же недостатком:

Универсальный  c использованием ГОСТ сертификата / Хабр

Эта доработка позволяет уже сегодня использовать УЦ CAFL63 в учебных целях, для организации корпоративного документооборота и т.п.

Это все, что хотелось сказать в постскриптуме.

Как добавить поддержку шифрования по гост р 34.10-2021 в openssl 1.1.1d на debian 9 stretch | it-блог жаконды

В работе имеется веб-сайт на котором реализована авторизация посредством ЕСИА (Единая система идентификации и аутентификации). До недавнего времени можно было использовать самоподписной RSA сертификат, но с 1 апреля 2020 года, для взаимодействия с ЕСИА необходимо использовать сертификат с алгоритмом шифрования по ГОСТ Р 34.10-2021.

В связи с этим мне необходимо было реализовать возможность работы с алгоритмом ГОСТ Р 34.11-2021 в OpenSSL на Debian 9 Stretch.

Путем перелопачивания множества информации по этому вопросу и проб использования движка GOST-Engine с различными версиями OpenSSL, для себя определил рабочую связку OpenSSL 1.1.1d  GOST-Engine.

В качестве памятки опишу действия для реализации связки OpenSSL 1.1.1d  GOST-Engine на Debian 9 Stretch.

Устанавливаем необходимые пакеты:

Выполняем сборку OpenSSL 1.1.1d, выполняем команды:

Выполняем сборку GOST Engine, выполняем команды:

Выполняем настройку OpenSSL для работы с GOST Engine. В файле конфигурации (/usr/ssl/openssl.cnf) добавляем следующие параметры (обращаем внимание на #комментарии):

Для проверки готовности OpenSSL к работе с GOST Engine, выполним команды (подсвеченные):

Для проверки сгенерируем сертификат по алгоритму GOST2021, для удобства просмотра переведем его в формат *.crt и скачиваем любым удобным способом на Windows машину:

В полученном сертификате смотрим алгоритм подписи, если он 1.2.643.7.1.1.3.2, то сертификат сгенерирован по ГОСТ Р 34.10-2021. Если на ПК установлен КриптоПро, то в Алгоритме подписи будет отображаться ГОСТ Р 34.11-2021/34.10-2021 256 бит.

ПОНРАВИЛАСЬ ИЛИ ОКАЗАЛАСЬ ПОЛЕЗНОЙ СТАТЬЯ, ПОБЛАГОДАРИ АВТОРА

Компиляция файлов

Файл компиляции провайдера comp_xyzcsp.bat:

Конфигурирование nginx


Ниже приведен мой конфигурационный файл Web-сервера Nginx. Следует обратить внимание на дублирующиеся директивы

ssl_certificatessl_certificate_key

Корневой сертификат сбербанка

С сертификатом Сбербанка подобное проделать не получается:

Универсальный  c использованием ГОСТ сертификата / Хабр

Это связано с тем, что в Сбербанке используется константа B из RFC 4357, а именно GostR3410_2001_CryptoPro_B_ParamSet.

Меняем тогда в нашем файле xyzcsp.c в функции CPVerifySignature константу A на B, то есть при вызове my_verify_gost будем использовать следующий параметр: NID_id_GostR3410_2001_CryptoPro_B_ParamSet.

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

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

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

Настройка openssl для работы с токенами (на примере рутокен)

Для работы с Рутокенами, аппаратно поддерживающими ГОСТ-криптографию, для openssl существует rtengine. Его установка достаточно проста и не сильно отличается от GOST, нужно только знать, что и где брать.

Обновление библиотеки openssl

Метод собирать «из исходников» и засорять систему — не наш метод. Поэтому лучший вариант — найти готовый пакет, и я его нашел в репозитории axivo:

Пишем тестовую программу

Зачем нужна отдельная тестовая программа? Она, кроме запуска тестов, будет патчить систему, чтобы поменять функции SystemFunction035 в ADVAPI32.dll и I_CryptGetDefaultCryptProv в CRYPT32.dll на их «правильный» вариант. Данная программа будет успешно работать как в Windows XP так и в Windows 7.

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

Файл testcsp.cpp:

Правка и перекомпиляция php

Основная проблема заключается в том, что для того чтобы OpenSSL использовала файл конфигурации по умолчанию (именно там у нас прописаны настройки для алгоритмов ГОСТ) перед ее использованием необходимо вызвать функцию OPENSSL_config(NULL). В расширении PHP OpenSSL этого не сделано, поэтому модуль PHP-SOAP при использовании SSL-соединения не видит алгоритмов ГОСТ. Кстати, тоже самое касается и других библиотек, например curl. Ее тоже нужно патчить если вы собираетесь с ней работать.

Итак приступим. Для того чтобы нам поправить OpenSSL необходимо перекомпилировать весь PHP, так как в CentOS расширение OpenSSL сделано не модулем.


Подготавливаем среду для сборки пакетов:

# yum install rpm-build redhat-rpm-config
# mkdir /root/rpmbuild
# cd /root/rpmbuild
# mkdir BUILD RPMS SOURCES SPECS SRPMS
# mkdir RPMS/{i386,i486,i586,i686,noarch,athlon}

Качаем исходники PHP и устанавливаем их:

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

Для этого нам понадобится Windows машина с установленным CryptoPRO CSP 3.6. Я его слил с сайта разработчика (там дается демонстрационный режим режим на 3 месяца).

Первое что делаем — экспортируем ключевой контейнер в реестр средствами КриптоПро. Для этого открываем КриптоПро из панели управления Windows. Вставляем наш ключевой носитель в компьютер. Для обычной флешки убеждаемся, что у нас среди считывателей на вкладке «Оборудование» есть «Все съемные диски» и «Реестр».

Далее переходим на вкладку «Сервис» и нажимаем «Копировать», нажимаем «Обзор» и выбираем среди списка свой ключевой контейнер. Если его там вдруг не находим — то возвращаемся к предыдущему параграфу и все проверяем. Далее вводим осмысленное имя нового ключевого контейнера, нажимаем «Готово» и в качестве носителя в появившемся окне выбираем «Реестр».

Новый пароль на контейнер не ставим. Теперь нам нужно установить сертификат в новый контейнер. На вкладке «Сервис» в КриптоПро нажимаем кнопку «Установить личный Сертификат», указываем файл с нашим сертификатом, нажимаем «Далее», выбираем только что созданный нами контейнер и не забываем галочку «Установить сертификат в контейнер».

Для того чтобы экспортировать данный сертификат в формате PKSC#12 вместе с закрытым ключом — нам понадобится сторонняя утилита. Которую можно либо купить здесь либо найти на просторах интернета по имени p12fromgostcsp. Запускаем данную утилиту, выбираем наш сертификат, пароль оставляем пустым и сохраняем его в файл mycert.p12.

# openssl pkcs12 -in mycert.p12 -nodes

На запрос пароля просто нажимаем Enter. И смотрим наличие строк BEGIN CERTIFICATE и BEGIN PRIVATE KEY. Если строки есть то все в порядке. Преобразуем полученный сертификат в формат PEM:

# openssl pkcs12 -in mycert.p12 -out mycert.pem -nodes -clcerts

Если вам нужна не только авторизация по клиентскому сертификату, но и также проверка валидности самого сервера — вам понадобится корневой сертификат удостоверяющего центра. Его можно просто через Windows открыть и сохранить в формате DER в кодировке X.

# openssl x509 -inform DER -in cacert.cer -outform PEM -out cacert.pem

Где cacert.cer — имя исходного файла с корневым сертификатом. Проверить коннект с сервером с использованием сертификатов можно через OpenSSL командой:

Провайдер xyz provider

Теперь займемся, наконец, провайдером. Выберем ему имя: «XYZ Provider». Соответственно, основной файл будет называться xyzcsp.c, также нужны файлы xyzcsp.def и xyzcsp.rc

В исходном образце, который можно найти в CSPDK, в файле csp.c, нас интересуют только функции CPAcquireContext, CPHashData, CPGetHashParam, CPVerifySignature. Легко видеть, что это функции для создания хендла провайдера, функции хеширования и проверки ЭЦП. Заменим эти функции на приведенные ниже.

Кроме них, напишем одну замечательную функцию, xyz_ConvertPublicKeyInfo, которая будет заниматься конвертацией публичного ключа ЭЦП. Не забываем добавить xyz_ConvertPublicKeyInfo в файл xyzcsp.def, чтобы линкер экспортировал это имя. Конвертация будет заключаться в игнорировании первых двух байт в записи ASN1 нотации публичного ключа, тем самым получая ключ в чистом виде, две половинки по 32 байта.

Удалим функцию DllMain, а также старые CPAcquireContext, CPHashData, CPGetHashParam, CPVerifySignature из xyzcsp.c, уберем устаревшую команду DESCRIPTION и имена DllRegisterServer и DllUnregisterServer из xyzcsp.def

Добавим в конец файла xyzcsp.c:

BOOL WINAPI
CPAcquireContext(
    OUT HCRYPTPROV *phProv,
    IN  LPCSTR szContainer,
    IN  DWORD dwFlags,
    IN  PVTableProvStruc pVTable)
{
    *phProv = 123;
    return TRUE;
}

BOOL WINAPI
CPHashData(
    IN  HCRYPTPROV hProv,
    IN  HCRYPTHASH hHash,
    IN  CONST BYTE *pbData,
    IN  DWORD cbDataLen,
    IN  DWORD dwFlags)
{
    my_hash_gost(pbData, cbDataLen, hash_gost);
    SHA1(pbData, cbDataLen, hash_sha1);
    return TRUE;
}

BOOL WINAPI
CPGetHashParam(
    IN  HCRYPTPROV hProv,
    IN  HCRYPTHASH hHash,
    IN  DWORD dwParam,
    OUT LPBYTE pbData,
    IN OUT LPDWORD pcbDataLen,
    IN  DWORD dwFlags)
{
	switch(dwParam)
	{
		case HP_HASHVAL:
			if(*pcbDataLen == 20) // у нас просят отпечаток sha1
			{
				memcpy(pbData, hash_sha1, 20);
				break;
			}
		default:
			*pcbDataLen = 0;
			SetLastError(E_INVALIDARG);
			return FALSE;
	}
    return TRUE;
}

BOOL WINAPI
CPVerifySignature(
    IN  HCRYPTPROV hProv,
    IN  HCRYPTHASH hHash,
    IN  CONST BYTE *pbSignature,
    IN  DWORD cbSigLen,
    IN  HCRYPTKEY hPubKey,
    IN  LPCWSTR szDescription,
    IN  DWORD dwFlags)
{
#define NTE_IC_ERROR_PREDEF          0x89900000L
    INT err;
    err = my_verify_gost(hash_gost, pbSignature, public_key, public_key 32, 
            NID_id_GostR3410_2001_CryptoPro_A_ParamSet);
    if ( err ) 
    {
        SetLastError( NTE_IC_ERROR_PREDEF | err );
        return FALSE;
    }
    return TRUE;
}

BOOL WINAPI xyz_ConvertPublicKeyInfo(
  DWORD dwCertEncodingType,
  VOID *EncodedKeyInfo,
  DWORD dwAlg,
  DWORD dwFlags,
  BYTE** ppStructInfo,
  DWORD* StructLen
)
{
    memcpy(public_key, ((CERT_PUBLIC_KEY_INFO*)EncodedKeyInfo)->PublicKey.pbData   2, 64);
    return TRUE;
}

Подробно комментировать исходники криптопровайдера, думаю, излишне. Все понятно по тексту.

Реализация алгоритма хеширования

Начнем с самого простого – с реализации алгоритма Стрибог. Kerberos обладает жесткой связью алгоритма хеширования и шифрования, то есть вы не можете просто так взять и выбрать для шифрования один алгоритм, а для хеширования другой – вам нужно будет встроить связку алгоритма хеширования и шифрования. Причина этого мне не известна, но раз там бытуют такие правила – давайте попробуем создать связку алгоритма Стрибог и AES.

Реализация алгоритма шифрования

В этом разделе я покажу, как можно добавить свой алгоритм шифрования данных в Kerberos, и мы попробуем создать связку Магмы и Стрибога, добавленного в прошлом разделе. Тут я уже предполагаю, что небольшая библиотека gost_helper уже была добавлена в прошлом разделе. Ну что же, разминаем пальцы и приступаем:

Регистрация криптопровайдера xyzcsp.dll

Зарегистрируем криптопровайдер в реестре. Для этого выполним (с правами администратора) нижеприведенный файл командой «regedit xyzcsp.reg»

Файл xyzcsp.reg:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINESOFTWAREMicrosoftCryptographyDefaultsProviderXYZ Provider]
"Image Path"="xyzcsp.dll"
"Type"=dword:0000007B

[HKEY_LOCAL_MACHINESOFTWAREMicrosoftCryptographyDefaultsProvider TypesType 123]
"Name"="XYZ Provider"

[HKEY_LOCAL_MACHINESOFTWAREMicrosoftCryptographyOIDEncodingType 0CryptDllFindOIDInfo]

[HKEY_LOCAL_MACHINESOFTWAREMicrosoftCryptographyOIDEncodingType 0CryptDllFindOIDInfo1.2.643.2.2.19!1]
"Name"="GOST R 34.10-2001"
"Algid"=dword:00002036
"ExtraInfo"=hex:00,00,00,00

[HKEY_LOCAL_MACHINESOFTWAREMicrosoftCryptographyOIDEncodingType 0CryptDllFindOIDInfo1.2.643.2.2.3!2]
"Name"="GOST R 34.11/34.10-2001"
"Algid"=dword:00008037
"ExtraInfo"=hex:36,20,00,00,00,00,00,00

[HKEY_LOCAL_MACHINESOFTWAREMicrosoftCryptographyOIDEncodingType 1CryptDllConvertPublicKeyInfo]

[HKEY_LOCAL_MACHINESOFTWAREMicrosoftCryptographyOIDEncodingType 1CryptDllConvertPublicKeyInfo1.2.643.2.2.19]
"Dll"="xyzcsp.dll"
"FuncName"="xyz_ConvertPublicKeyInfo"

[HKEY_LOCAL_MACHINESOFTWAREMicrosoftCryptographyOIDEncodingType 1CryptDllConvertPublicKeyInfo1.2.643.2.2.98]
"Dll"="xyzcsp.dll"
"FuncName"="xyz_ConvertPublicKeyInfo"

Результаты работы

Запустим тестовую программу, получим результат:

Универсальный  c использованием ГОСТ сертификата / Хабр

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

После повторного запуска теста наблюдаем уже иную картину:
Универсальный  c использованием ГОСТ сертификата / Хабр

Что и требовалось получить.

Сертификаты для тестирования


Файл gnivc_2006.cer, в котором лежит корневой сертификат ФНС:

-----BEGIN CERTIFICATE-----
MIIDGjCCAsegAwIBAgIQPx2a1ZtKRIBLiHKukksltTAKBgYqhQMCAgMFADCBwDEe
MBwGCSqGSIb3DQEJARYPdWNpbmZvQGduaXZjLnJ1MQswCQYDVQQGEwJSVTEVMBMG
A1UEBwwM0JzQvtGB0LrQstCwMTAwLgYDVQQKDCfQpNCT0KPQnyDQk9Cd0JjQktCm
INCk0J3QoSDQoNC 0YHRgdC40LgxMDAuBgNVBAsMJ9Cj0LTQvtGB0YLQvtCy0LXR
gNGP0Y7RidC40Lkg0YbQtdC90YLRgDEWMBQGA1UEAxMNR05JVkMgRk5TIFJVUzAe
Fw0wNjA5MjcwOTI5NTdaFw0xMjA5MjcwOTM4MjdaMIHAMR4wHAYJKoZIhvcNAQkB
Fg91Y2luZm9AZ25pdmMucnUxCzAJBgNVBAYTAlJVMRUwEwYDVQQHDAzQnNC 0YHQ
utCy0LAxMDAuBgNVBAoMJ9Ck0JPQo9CfINCT0J3QmNCS0KYg0KTQndChINCg0L7R
gdGB0LjQuDEwMC4GA1UECwwn0KPQtNC 0YHRgtC 0LLQtdGA0Y/RjtGJ0LjQuSDR
htC10L3RgtGAMRYwFAYDVQQDEw1HTklWQyBGTlMgUlVTMGMwHAYGKoUDAgITMBIG
ByqFAwICIwEGByqFAwICHgEDQwAEQCzY8VGw9ged02ijaj2KWOMXJVvzY1FEcg7G
xedUtKx0wqyTVti0kmodEmm2cVfAbDkp0xAdBS9/mdDfeIrKXLajgZYwgZMwCwYD
VR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFBMQt5JPv eiD7j1
nYkVJssQ6/RfMBAGCSsGAQQBgjcVAQQDAgEAMEIGCCsGAQUFBwEBBDYwNDAyBggr
BgEFBQcwAoYmaHR0cDovL3d3dy5nbml2Yy5ydS91Yy9HTklWQ0ZOU1JVUy5jcnQw
CgYGKoUDAgIDBQADQQDgEyWPI fdXXiTYMLHdV76v8kVFIxCHCYtastcvZiM3cG1
wTFhio8fDx6sLgHHriOwQFg0zRUYHIs9nZEptLvM
-----END CERTIFICATE-----

Файл rootsber.cer, в котором лежит корневой сертификат Сбербанка:

-----BEGIN CERTIFICATE-----
MIIDKjCCAtmgAwIBAgIGMDBDQT0HMAgGBiqFAwICAzCBwTELMAkGA1UEBhMCUlUx
LTArBgNVBAoMJNCh0LHQtdGA0LHQsNC90Log0KDQvtGB0YHQuNC4INCe0JDQnjE4
MDYGA1UECwwv0JTQtdC/0LDRgNGC0LDQvNC10L3RgiDQsdC10LfQvtC/0LDRgdC9
0L7RgdGC0LgxJjAkBgNVBAMMHdCh0LHQtdGA0LHQsNC90Log0KDQvtGB0YHQuNC4
MSEwHwYJKoZIhvcNAQkBFhJjYXNicmZAc2JlcmJhbmsucnUwHhcNMDkwODA1MDAw
MDAwWhcNMTcwODA1MDAwMDAwWjCBwTELMAkGA1UEBhMCUlUxLTArBgNVBAoMJNCh
0LHQtdGA0LHQsNC90Log0KDQvtGB0YHQuNC4INCe0JDQnjE4MDYGA1UECwwv0JTQ
tdC/0LDRgNGC0LDQvNC10L3RgiDQsdC10LfQvtC/0LDRgdC90L7RgdGC0LgxJjAk
BgNVBAMMHdCh0LHQtdGA0LHQsNC90Log0KDQvtGB0YHQuNC4MSEwHwYJKoZIhvcN
AQkBFhJjYXNicmZAc2JlcmJhbmsucnUwYzAcBgYqhQMCAhMwEgYHKoUDAgIjAgYH
KoUDAgIeAQNDAARAaYzyi29YQ9NC5cb/kq//J1kKhOgcvGWqsQu50mldjADTGfrl
JUVXwu4fMUTHoF9TjY0O1kgrLYWT/kI4jABAWKOBsjCBrzAdBgNVHQ4EFgQUZmHo
Zo41vw/U74ZlC8k/bcQODuowDAYDVR0TBAUwAwEB/zAzBgNVHR8ELDAqMCigJqAk
hiJodHRwOi8vd3d3LnNicmYucnUvY2EvMDAwMHg1MDkuY3JsMAsGA1UdDwQEAwIC
hDA BgcqhQMDewMBBDMMMTAwQ0ExODUzetCa0L7RgNC90LXQstC 0Lkg0LrQu9GO
0Ycg0KPQpiDQodCRINCg0KQwCAYGKoUDAgIDA0EAD9Umnh/EZgjgQvpypdVwe0wa
GnTi dHhVwoNAX1tquxQNbAptbBs2OKzkRU7/mrBfDD4EdVV5xC1f2DTcH8NAg==
-----END CERTIFICATE-----

Собираем nginx

Я собирал nginx со статической библиотекой OpenSSL 1.0.2h

Создание приватного ключа и сертификата для принципала, kdc и уц

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

Создание универсального патча

В заключение несколько слов о создании универсального патча.

Для Windows XP SP3 достаточно подменить следующие файлы:c:windowssystem32advapi32.dllc:windowssystem32dllcacheadvapi32.dllc:windowssystem32crypt32.dllc:windowssystem32dllcachecrypt32.dll

Патчить нужно, загрузившись с другого диска, чтобы системный был свободным (можно с загрузочного диска Windows в режиме восстановления), далее заменяем эти два файла как в директории system32 так и в system32dllcache, где хранятся их копии. Патчить на работающей системе не получится, потому что файлы «залочены» и поменять их не удастся.

После этого не забудьте скопировать файл с криптопровайдером xyzcsp.dll в директорию c:windowssystem32, чтобы система его находила.

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

Заменить файлы нужно на их пропатченный вариант:

Сравнение файлов advapi32.dll и C:xyzcspPATCHADVAPI32.DLL
00017585: 8B B8
00017586: FF 01
00017587: 55 00
00017588: 8B 00
00017589: EC 00
0001758A: 81 C2
0001758B: EC 04
0001758C: 50 00

Сравнение файлов crypt32.dll и C:xyzcspPATCHCRYPT32.DLL
00008F66: 8B E9
00008F67: FF 47
00008F68: 55 09
00008F69: 8B 00
00008F6A: EC 00
000098B2: 90 55
000098B3: 90 8B
000098B4: 90 EC
000098B5: 90 8B
000098B6: 90 45
000098B7: 90 08
000098B8: 53 83
000098B9: 00 F8
000098BA: 6F 00
000098BB: 00 74
000098BC: 66 21
000098BD: 00 3D
000098BE: 74 36
000098BF: 00 20
000098C0: 77 00
000098C2: 61 74
000098C3: 00 1A
000098C4: 72 3D
000098C5: 00 35
000098C6: 65 66
000098C8: 5C 00
000098C9: 00 74
000098CA: 50 13
000098CB: 00 3D
000098CC: 6F 37
000098CD: 00 80
000098CE: 6C 00
000098D0: 69 74
000098D1: 00 0C
000098D2: 63 3D
000098D3: 00 38
000098D4: 69 AA
000098D6: 65 00
000098D7: 00 74
000098D8: 73 05
000098D9: 00 E9
000098DA: 5C 8D
000098DB: 00 F6
000098DC: 4D FF
000098DD: 00 FF
000098DE: 69 6A
000098E0: 63 68
000098E1: 00 7B
000098E2: 72 00
000098E4: 6F 00
000098E5: 00 6A
000098E6: 73 00
000098E7: 00 8D
000098E8: 6F 05
000098E9: 00 40
000098EA: 66 A5
000098EB: 00 A7
000098EC: 74 77
000098ED: 00 50
000098EE: 5C 8D
000098EF: 00 45
000098F0: 53 08
000098F1: 00 50
000098F2: 79 FF
000098F3: 00 15
000098F4: 73 00
000098F5: 00 10
000098F6: 74 A7
000098F7: 00 77
000098F8: 65 83
000098F9: 00 F8
000098FA: 6D 00
000098FB: 00 74
000098FC: 43 DC
000098FD: 00 8B
000098FE: 65 45
000098FF: 00 08
00009900: 72 C9
00009901: 00 C2
00009902: 74 04

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

В реальной системе, в которой установлен ГОСТ криптопровайдер, проблемы с патчем обычно решаются за счет установки специального драйвера PatchEngine, который наблюдает за загрузкой системных DLL и патчит их «на лету».

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