- Openssl gost engine windows
- OpenSSL и ГОСТ
- Содержание
- Применимость
- Установка и настройка
- Формирование запроса на сертификат с поддержкой алгоритма ГОСТ (пример)
- Получение контрольной суммы используя алгоритмы ГОСТ
- OpenSSL with GOST engine
- 1 Answer 1
- Docker-образы с поддержкой ГОСТ-сертификатов в openssl, curl, php, nginx
- Причины
- Сборка OpenSSL, GOST-engine, cURL
- Примеры использования OpenSSL + GOST-engine
- Использование образа в работе с языками программирования
- Поддержка ГОСТ-алгоритмов в PHP
- Поддержка ГОСТ-сертификатов в nginx
- Заключение
Openssl gost engine windows
На текущий момент существует 2 варианта реализации ГОСТ алгоритмов, которые может использовать OpenSSL:
- Open source библиотека, которая раньше поставлялась вместе с OpenSSL, но начиная с версии OpenSSL 1.1, она была исключена из его состава, и оформилась в виде отдельного продукта https://github.com/gost-engine/engine .
Поддержка алгоритмов ГОСТ 2001 имеется во всех версиях библиотеки gost.dll. Однако поддержка алгоритмов ГОСТ 2012 реализована только в версиях, совместимых с OpenSSL >= 1.1.0.
Библиотека gost.dll должна использоваться только с соответствующей ей версией OpenSSL:
- для OpenSSL = 1.1.0: собирается самостоятельно из исходников (https://github.com/gost-engine/engine), поддерживает ГОСТ 2012
В релизах сервиса до сентября 2020 включительно, использовались библиотеки OpenSSL 1.0.2. Поэтому возможно использовать библиотеку gost.dll из самого интялятора OpenSSL, либо можно скачать соответствующую библиотеку с нашего сайта:
В штатной поставке текущего сервиса поставляются библиотеки OpenSSL версии 1.1.1. Поэтому необходимо самостоятельная сборка библиотеки gost.dll, либо можно воспользоваться версией собранной нами:
Необходимо использовать библиотеку соответствующую разрядности используемого приложения, которое будет использовать данную библиотеку. Например, если настраивается серверная сторона Сервиса, то выбирается в соответствии с его разрядностью, если настраивается клиентская сторона (приложение для удаленного доступа), то в соответствии с его разрядностью (на текущий момент только Win32).
КриптоПро библиотека для OpenSSL (gost_capi или gostengy для OpenSSL >= 1.1.0), работающая только при установленном КриптоПро CSP.
Аналогично, как и с библиотекой gost.dll, версия библиотеки зависит от используемой версии OpenSSL:
- для OpenSSL = 1.1.0: необходимо использовать библиотеку gostengy, поддерживает ГОСТ 2012
Скачать необходимые версии библиотеки можно на сайте КриптоПро .
Более подробное описание можно найти у них на форуме .
- Расположить необходимую библиотеку (нужной разрядности) поддержки алгоритмов ГОСТ рядом с исполняемыми файлами, которые будут ее использовать.
Создать файл конфигурации OpenSSL.
Пример для библиотеки gost.dll:
Пример для библиотеки gost_capi/gostengy от КриптоПро:
В указанных примерах файла конфигураций предполагается, что библиотека поддержки алгоритмов ГОСТ находится рядом с исполняемыми файлами. Но файл конфигурации может быть расположен в ином месте. В таком случае необходимо указать полный, а не относительный путь к библиотеке.
В случае использования существующего файла конфигурации, например поставляемого с самим OpenSSL, необходимо 1-ю строчку (openssl_conf = openssl_def) вставить в начало этого файла, а остальные строки в самый конец файла.
Указанный файл конфигурации является примером, и может быть изменен пользователем в зависимости от требуемых настроек.
Подобным образом возможно подключить любые другие расширения (engine) для OpenSSL.
Например, в случае если приватный ключ сертификата хранится на аппаратном носителе (USB токен, смарт карт) который не допускает их экспортирования в файл, но при этом предосталяет возможность их использования через свой интерфейс. Обычно в таких случаях криптопровайдер распространяет расширения для интеграции с OpenSSL.
В таких случаях, в процессе конфигурирования вместо указания пути к файлу (Параметры сетевых настроек, поле Закрытый ключ) необходимо указать через какое расширение можно обращаться к закрытому ключу:
OpenSSL и ГОСТ
Содержание
Применимость
- Приведённая ниже инструкция актуальна для RED X3|X4 и FRESH R8.1|R11. Реализация OpenSSL в этих дистрибутивах включает поддержку алгоритмов ГОСТ
- Наличие в ОС реализации алгоритма ГОСТ не означает автоматического наличия сертификата регулятора на эту реализацию. Проверка контроля встраивания не производилась, сертификат регулятора (ФСБ РФ) на эту реализацию отсутствует. Таким образом, применять эту реализацию можно только в целях осуществления проверок функционирования, либо в соответствии со статьей 1, пункт 2, подпункт 1 152-ФЗ
Установка и настройка
По-умолчанию поддержка ГОСТ отключена. Активизируем поддержку алгоритма в конфигурационном файле:
- Редактируем файл /etc/pki/tls/openssl.cnf Вначале файла, прямо первой строкой определим дополнительную секцию openssl_conf=openssl_def, например:
- Затем в конец этого же файла вносим описание алгоритма в конфигурационный файл, с учетом верного пути к библиотеке, например:
- Удостоверимся, что библиотека openssl корректно опознала добавленный алгоритм ГОСТ. Для этого выполним:
Ответ системы будет такой:
Формирование запроса на сертификат с поддержкой алгоритма ГОСТ (пример)
Получение контрольной суммы используя алгоритмы ГОСТ
Для получения хэш-функции согласно ГОСТ Р 34.11-2012.
OpenSSL with GOST engine
I want to use OpenSSL to generate private/public/(Certificate Signing Request) and to sign some data later. But I want to use OpenSSL GOST engine.
I downloaded OpenSSL 1.0.0 and modified openssl.cfg file:
I can generate private key and CSR (single line command string):
I know that I can do (prints an (unencrypted) text representation of private and public keys):
I use GOST instead RSA that is why I cannot just do:
My question is : how can I generate/get public key (mabye from private key or from csr) using gost?
- Windows 7 professional x64;
- OpenSSL 1.0.0;
- Gost engine.
Thanks for any help.
1 Answer 1
I resolved my problem.
Step by step guide for everyone who wants an alternative to КРИПТО-ПРО
Certificate Signing Request(CSR) + private key
./openssl req -newkey gost2001 -pkeyopt paramset:A -passout pass:aofvlgzm -subj «/C=RU/ST=Moscow/L=Moscow/O=foo_bar/OU=foo_bar/CN=developer/emailAddress=vany.egorov@gmail.com» -keyout private.key.pem -out csr.csr
Sign CSR (csr.csr) with private.key.pem (. ADMIN COMMAND PROMT ONLY . )
if not admin: «unable to write ‘random state'»
./openssl x509 -req -days 365 -in csr.csr -signkey private.key.pem -out crt.crt
Get public key
./openssl x509 -inform pem -in crt.crt -pubkey -noout > public.key.pem
Get GOST2001-md_gost94 hex
./openssl.exe dgst -hex -sign private.key.pem message.xml
Get MIME application/x-pkcs7-signature
Docker-образы с поддержкой ГОСТ-сертификатов в openssl, curl, php, nginx
В этой статье я расскажу о том, как я решал задачу об интеграции в тестовом режиме с сервисами, которые работают с использованием алгоритмов, определенных ГОСТ Р 34.10-2001 (устарел) и ГОСТ Р 34.10-2012. Приведу примеры некоторых проблем, с которыми столкнулся при решении задачи, дам ссылки на готовое решение и покажу несколько примеров их использования.
Причины
Для начала стоит сказать, что для продакшн-окружения существуют сертифицированные средства от компаний «Криптоком», «Крипто-Про», «Сигнал-КОМ» и других. Мне же нужно было реализовать взаимодействие в тестовом (девелоперском) окружении на Linux, покупать для этого лицензии не очень-то удобно, но что хуже, в открытом доступе отсутствуют документации по этому вопросу. По запросу «https гост» не так много решений. Среди них упоминается использование OpenSSL + Крипто CSP, я не помню деталей, но эта связка у меня не завелась с поддержкой ГОСТ Р 34.10-2012. Другим результатом, который часто встречался, было предложение использовать OpenSSL 1.0, в котором GOST-engine встроен внутрь, но такое решение тоже не содержало в себе поддержку GOST2012-GOST8912-GOST8912 .
Рабочим решением оказалась сборка OpenSSL 1.1.0g + вынесенный в отдельно подключаемый динамический движок GOST-engine. В интернете часто встречается упоминание, что некая российская компания приложила усилия по его разработке, но в самом репозитории нет сведений об авторах продукта. Пользуясь случаем, выражаю авторам благодарность за движок в open source. На этой странице сказано, что до OpenSSL 1.1.0 использовался встроенный движок GOST, сейчас для GOST используется сторонний от OpenSSL продукт. Судя по конфигурации, скорее всего, это одна и та же библиотека.
Сборка OpenSSL, GOST-engine, cURL
Сборка стороннего продукта для тех, кто делает это редко, может быть нетривиальной задачей. Для сборки OpenSSL, GOST-engine и cURL пришлось разобраться с кучей опций и перепробовать несколько комбинаций версий. Если в Dockerfile вы заметите странное, то, скорее всего, это осталось от таких экспериментов.
Я зафиксировал все версии проектов для сборки, чтобы исключить ситуацию, что из-за обновления что-то перестанет работать. Например, я собирал OpenSSL 1.1.0h + GOST-engine и команда openssl ciphers не содержала GOST-алгоритмов, хотя openssl engine показывала GOST-engine в списке. Указав предыдущую версию OpenSSL 1.1.0g, все работало, как ожидалось. Это было очень странно, я повторил это еще раз, потом пытался выяснить причины, но в итоге решил остаться на 1.1.0g.
Собирая сам GOST-engine, я не сразу обратил внимание на наличие файла INSTALL.md в master-ветке, потому что собирал из ветки openssl_1_1_0 по неизвестно откуда взятой документации. Та версия собиралась с кастомной сборкой OpenSSL командой
Но master-ветка так собираться перестала, появились ошибки об отсутствии DOPENSSL_ROOT_DIR и подобное. В итоге решение было найдено и зафиксировано.
Для сборки cURL с кастомной сборкой OpenSSL гораздо больше документации, тем не менее, документация успевала устаревать, и с опциями пришлось много экспериментировать.
Результат работы выложен здесь.
Образ запушен в Docker Hub.
Примеры использования OpenSSL + GOST-engine
Не буду сильно вдаваться в подробности работы с докер-образами, лишь приведу одну команду для начала работы внутри образа:
Для начала можно убедиться, что алгоритмы GOST2012-GOST8912-GOST8912 и GOST2001-GOST89-GOST89 есть в списке поддерживаемых:
Если вам известен хост, который работает по HTTPS на основе ГОСТ-алгоритмов, то посмотреть его сертификат и попробовать подключиться можно командой:
Создать закрытый ключ и сертификат по ГОСТ Р 34.10-2012:
Подписать файл ранее созданными сертификатами:
Извлечь содержимое подписанного файла, сертификатом, который был подписан самим собой:
С подписями самих сертификатов все немного сложнее. Пока мне не попался сервис, у которого сертификат выдан доверенным центром сертификации. Обычно, требуется дополнительно указывать сертификат удостоверяющего центра при работе с выданными им сертификатами. Это можно сделать глобально для системы (в образе), либо явно указывать в каждой команде.
Программа cURL в использовании не изменилась, просто поддерживает хосты с ГОСТ-сертификатами.
Использование образа в работе с языками программирования
Если язык программирования позволяет исполнять установленные в системе программы, то задача использования ГОСТ-алгоритмов проще всего решается копированием бинарников собранных openssl и curl в конце Dockerfile языка программирования с использованием multi-stage build. Например:
Даже необязательно копировать в /usr/bin , это можно сделать в любой каталог, а затем вызывать из вашей программы, передав полный путь и все аргументы.
Поддержка ГОСТ-алгоритмов в PHP
PHP, конечно, позволяет делать вызовы системных команд, используя, например, exec . Но, глядя на то, как собирается PHP-FPM в Dockerfile, мне показалось, что можно легко собрать PHP с кастомными сборками OpenSSL и cURL. Как оказалось дальше, я ошибся, что это легко. Всё равно собрал.
По какой-то причине, я начал с PHP-FPM 7.1. Идея была в том, чтобы использовать multi-stage build. Для этого надо заменить в их Dockerfile инструкцию FROM на мою FROM rnix/openssl-gost AS openssl-gost , затем прописать копирования собранных openssl и curl до начала сборки самого php и, наконец, указать в опции сборки путь до этих библиотек —with-openssl-dir=/usr/local/ssl и —with-curl=/usr/local/curl заменив оригинальные.
Сюрпризы ждали отовсюду. Одним из значительных было то, что при сборки php 7.1 используется pkg-config, а явная установка libcurl4-openssl-dev, libssl-dev прописывали в pkg-config версии из пакетов. В результате собиралось не то, что нужно. Если убрать их установку, то /configure php падал, ссылаясь на отсутствие openssl в pkg-config. Пришлось дополнительно копировать из кастомных сборок openssl и curl их lib/pkgconfig /* . После десятков таких сюрпризов сборка начала проходить. Дальше выяснилось, что зависимости устанавливали openssl, тем самым перезатирая ранее скопированный бинарник моей кастомной сборки. Пришлось дополнительно копировать его в самом конце. Но это не всё.
В собранном php появились алгоритмы хешей openssl_get_md_methods() : GOST R 34.11-2012 with 256 bit hash , GOST R 34.11-2012 with 512 bit hash , GOST R 34.11-94 . Это значило, что php подключил GOST-engine. А вот использование расширения curl в php почему-то говорило, что таких алгоритмов не знает, соединяясь с хостом по GOST-HTTPS. Я потратил несколько часов, пытаясь найти причину этого. Я смотрел исходники, как устроено расширение curl в php, как устроен сам curl, как они связываются с openssl. Я искал место, где могут определяться поддерживаемые алгоритмы или подключатся движки. Я искал по master-веткам, много гуглил, но ничего, что решило бы сразу проблему, не нашел. Тогда я вспомнил, что я собираю не последнюю версию PHP.
Я попробовал собрать PHP-FPM 7.2. Пришлось внести некоторые правки в мой скрипт корректировки оригинального Dockerfile PHP-FPM, но сборка начала проходить без большого количества сюрпризов. Главной новостью стало то, что теперь расширение curl внутри php умело общаться по ГОСТ-алгоритмам с хостами, но была одна неприятность. Каждый вызов php писал в stdout GOST engine already loaded . Очень неприятно. Я не сразу понял, кто это делает, но такую строчку нашел в исходниках GOST-engine. Я до сих пор не знаю, в какой части системы случилась ошибка: php, php-curl, curl, openssl. Но, видимо, в php 7.1 php-curl не подключал движок совсем, теперь в php 7.2 начал подключать его дважды. Так как все работало корректно, только был вывод, я решил его убрать правкой исходника инструкцией в Dockerfile:
Там строчкой ниже уже есть goto end; , поэтому ничего серьезного я не сделал. Зато, пересобрав весь зоопарк, все начало работать, как и хотелось.
Образ с PHP-FPM + OpenSSL + GOST + cURL запушен в Docker Hub.
Поддержка ГОСТ-сертификатов в nginx
Возможность работать из языков программирования это уже много, но хотелось еще две возможности:
- Легко поднимать свой веб-сервер с ГОСТ-сертификатом по HTTPS (TLS).
- Легко проксировать все запросы на хост с ГОСТ-сертификатом
Легко – это означает докер-образ. Его нужно создать. Для этого нужно в Dockerfile собрать nginx с кастомным OpenSSL и GOST-engine. Открыв документацию сборки nginx, я увидел одну опцию о ssl — —with-http_ssl_module , которая просто булева. Но nginx популярный продукт, инструкций по сборке с openssl много, поэтому я нашел еще опцию —with-openssl=[DIR] . Как показала практика, nginx хочет, чтобы здесь были исходники openssl, а сборкой скрипты nginx займутся сами. Это не совсем то, что я хотел бы (я хотел использовать multi-stage build). Я ознакомился с help-выводом сборщика nginx, но ничего, что мне там помогло бы, я не нашел.
Пришлось дублировать инструкции выкачивания исходников OpenSSL, распаковки, сборки GOST-engine, включения GOST-engine в конфиги. Всё это начало собираться, но поддержки ГОСТ-алгоритмов в nginx все ещё не было. Это я проверял указанием в конфиге ssl_ciphers GOST2001-GOST89-GOST89:HIGH:MEDIUM; . Выполнение nginx -t говорило, что не знает этого алгоритма.
Как оказалось, openssl, собранный nginx, не поддерживал динамические движки, т.е. ./Configure выводил no-dynamic-engine [forced] . Здесь пришлось внимательно почитать документацию сборки OpenSSL, чтобы выяснить, что проставило forced . Причина нашлась в аргументах сборки openssl, которые вызывал nginx, а именно no-shared . Если это указано, то нет никаких флагов, чтобы включить поддержку загрузки движков. Пришлось править инструкцию сборки:
Всё это собралось, но nginx начал ругаться, что не может найти gost.so по пути /usr/lib/x86_64-linux-gnu/ , это довольно странно, потому что тот же собранный openssl ищет и находит движки совсем в другом месте, а именно там, где и собирался ./lib/engines-1.1 . Добавил инструкцию копирования собранных движков в /usr/lib/x86_64-linux-gnu/ , чтобы угодить nginx. Заработало.
Рядом с основным Dockerfile в репозитории я положил демонстрационный Dockerfile, который при сборке создает себе ГОСТ-сертификаты и использует их, обрабатывая соединения на https://gost.example.com. Придется поработать с DNS или docker network, чтобы из одного контейнера попробовать подключится к этому демонстрационному, но все это я описал в документации.
Демонстрационный хост использует ключи по gost2001 , другие варианты это gost2012_256 , gost2012_512 . А вместо GOST2001-GOST89-GOST89 — GOST2012-GOST8912-GOST8912 .
Образ с nginx + GOST запушен в Docker Hub: https://hub.docker.com/r/rnix/nginx-gost/
Заключение
Мной изучена проблема работы с ГОСТ-алгоритмами в системах Linux, предоставлено решение в виде docker-образов, все это сопровождено документацией и примерами. Решение оформлено в виде репозитория на GitHub.
Стоит сказать о безопасности использования такого решения. Главное, не стоит доверять образам на Docker Hub, даже если там написано Automated Build . Я все равно могу собрать образ с любыми правками всех используемых библиотек и систем и запушить его в свой Docker Hub под любым тегом. Поэтому рекомендую форкать репозиторий на гитхабе, пулить его себе и уже самостоятельно собирать, проверив инструкции в Dockerfile на наличие того, что используются только официальные ресурсы без подозрительных модификацией по ходу сборки.
Собирая образ самостоятельно, вы можете убедиться, что в код не попали злонамеренные правки, потому что сборка происходит только из открытого кода, который доступен для просмотра всем желающим. Тем не менее, это не гарантирует, что в нем нет ошибок и уязвимостей. Использование проприетарных сертифицированных средств так же не гарантирует отсутствие ошибок и уязвимостей, но к тому же их код от вас закрыт.