Openssl гост 2012 windows

Openssl гост 2012 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.

Шифрование TLS-трафика по алгоритмам ГОСТ-2012 c Stunnel

В этой статье я хочу показать, как настроить Stunnel на использование российских криптографических алгоритмов в протоколе TLS. В качестве бонуса покажу, как шифровать TLS-канал, используя алгоритмы ГОСТ, реализованные в криптоядре Рутокен ЭЦП 2.0.

Но для начала давайте вообще разберёмся для чего нужен Stunnel. В двух словах — это программа, на которую можно переложить всю логику шифрования трафика между сервером и клиентом. Делается это следующем образом: допустим у вас есть клиент и сервер, которые общаются между собой без использования шифрования, аутентификации и проверки целостности. Вы могли бы переписать клиент и сервер так, чтобы все исходящие и входящие сообщения передавались между собой с учётом всех этих моментов, но для чего такие сложности, если можно это просто переложить на плечи другому приложения? Для решения такой задачи как раз подойдёт Stunnel.

Читайте также:  Как удалить высокоскоростное подключение windows 10

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

Стоит заметить, что на сервере не обязательно должен стоять именно Stunnel, для работы с криптографическими алгоритмами. Здорово, что есть готовые демонстрационные стенды, которые поддерживают российскую криптографию, список которых есть в презентации с РусКрипто’2019.

Нам нужны стабильно работающие серверы, осуществляющие двухстороннюю аутентификацию.
Мы выбрали серверы КриптоПро как наиболее надёжные с полной реализацией стандарта ГОСТ TLS. Спасибо им за это 🙂

Звучит достаточно просто, давайте попробуем организовать этот процесс.

Подготовительный шаг

  1. OpenSSL
  2. Stunnel
  3. rtengine
  4. Доступ к тестовым серверам КриптоПро, для проверки соединения по TLS

OpenSSL для Windows можно взять отсюда, а для пользователей линукса — из репозиториев или собрать самому, скачав свежую версию отсюда. Также его можно взять из Rutoken SDK, из директории openssl\openssl-tool-1.1, этот архив нам будет полезен и дальше, т.к. в нём находится интересующий нас rtengine. Stunnel можно найти здесь. Для работы необходима версия >= 5.56.

Скачать rtengine можно из Rutoken SDK, он лежит в директории openssl\rtengine\bin. Закинуть его нужно туда, где хранятся все движки openssl. Узнать путь до них можно с помощью

Но просто переместить движок в нужную папку — мало, нужно ещё сконфигурировать сам openssl для работы с ним. Узнаём где лежит файл с конфигурацией openssl.cnf с помощью той же команды, что указана выше (под виндой stunnel идёт с собственной версией openssl, поэтому файл с конфигурацией лежит в path\to\stunnel\config\openssl.cnf

Давайте проверим, что rtengine подключился, для этого подключим токен и выведем список всех алгоритмов шифрования:

Напомню, что в Windows нужно проверять на openssl, который лежит рядом с stunnel
Если среди них будут присутствовать наши ГОСТы, значит всё настроено верно.

Настало время самого интересного: проверка установки соединения по ГОСТу с тестовыми серверами КриптоПро. Список данных серверов описан здесь (https://www.cryptopro.ru/products/csp/tc26tls). Каждый из этих серверов работает со своими алгоритмами для аутентификации и шифрования. Более того на портах 443, 1443, 2443,… запущены сервисы, которые воспринимают только определённые парамсеты. Так, например, по адресу http://tlsgost-256auth.cryptopro.ru происходит шифрование с аутентификацией с использованием алгоритмов GOST2012-GOST8912-GOST8912 и 256-битным ключом. Так же на порту 443 используется XchA-ParamSet, на порту 1443 — XchB-ParamSet, на порту 2443 — A-ParamSet и т.д.

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

Простой способ (работает под Windows и Linux)

Через командную строку

Для того, чтобы получить корневой сертификат, зайдём на сайт тестового УЦ ООО «КРИПТО-ПРО». И нажмём на кнопку для получения сертификата. Отобразится новая вкладка, в которой нужно будет выбрать метод шифрования Base64 и нажать на кнопку «Загрузка сертификата ЦС». Полученный файл certnew.cer сохраняем.

Теперь генерируем ключи.

Стоит заметить, что сгенерированные на токене ключи не могут быть скопированы с токена. В этом состоит одно из основных преимуществ их использования.

Создадим запрос на сертификат:

Опять открываем сайт тестового УЦ, но на этот раз нажимаем на кнопку «Отправить готовый запрос PKCS#10 или PKCS#7 в кодировке Base64». Вставляем в поле содержимое нашего запроса, нажимаем на кнопку Выдать и загружаем сертификат user.crt в формате Base64. Полученный файл сохраняем

Остался последний вопрос: Для чего всё это. Зачем мы получали все эти сертификаты, ключи и запросы?

Дело в том, что они нужны протоколу TLS для двусторонней аутентификации. Работает это очень просто.

У нас есть сертификат сервера, и мы считаем его доверенным.

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

Мы отправили этот запрос и сервер подписал её своей ЭЦП. Теперь мы можем каждый раз предъявлять этот сертификат, подписанный корневым УЦ, тем самым подтверждая, что мы — это мы.

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

Осталось только правильно настроить наш туннель. Для этого создадим файл stunnel.conf с настройками Stunnel по умолчанию и напишем туда следующее:

Теперь, если всё сделано правильно, можно запустить Stunnel с нашей конфигурацией и подключиться к серверу:

Откроем браузер и зайдём по адресу localhost:8080. Если всё верно, то отобразится следующее:

Если же нет, то смотрим логи и используем отладчик, чтобы понять в чём же всё-таки проблема.

Если у вас остались какие-то вопросы, то милости просим в комментарии 🙂

Docker-образы с поддержкой ГОСТ-сертификатов в openssl, curl, php, nginx

В этой статье я расскажу о том, как я решал задачу об интеграции в тестовом режиме с сервисами, которые работают с использованием алгоритмов, определенных ГОСТ Р 34.10-2001 (устарел) и ГОСТ Р 34.10-2012. Приведу примеры некоторых проблем, с которыми столкнулся при решении задачи, дам ссылки на готовое решение и покажу несколько примеров их использования.

Читайте также:  Ftp from unix to windows server

Причины

Для начала стоит сказать, что для продакшн-окружения существуют сертифицированные средства от компаний «Криптоком», «Крипто-Про», «Сигнал-КОМ» и других. Мне же нужно было реализовать взаимодействие в тестовом (девелоперском) окружении на 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, тем самым перезатирая ранее скопированный бинарник моей кастомной сборки. Пришлось дополнительно копировать его в самом конце. Но это не всё.

Читайте также:  Настроить сетевой доступ windows 10

В собранном 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

Возможность работать из языков программирования это уже много, но хотелось еще две возможности:

  1. Легко поднимать свой веб-сервер с ГОСТ-сертификатом по HTTPS (TLS).
  2. Легко проксировать все запросы на хост с ГОСТ-сертификатом

Легко – это означает докер-образ. Его нужно создать. Для этого нужно в 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 на наличие того, что используются только официальные ресурсы без подозрительных модификацией по ходу сборки.

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

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