Как создать свой корневой сертификат
Перейти к содержимому

Как создать свой корневой сертификат

  • автор:

Как создать сертификаты SSL (TLS)

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

Генерация приватного ключа RSA используя параметры по умолчанию (ключ будет сохранён в файл с именем rootCA.key):

Опция -out указывает на имя файла для сохранения, без этой опции файл будет выведен в стандартный вывод (на экран). Имя выходного файла не должно совпадать с именем входного файла.

Для безопасности ключа его следует защитить паролем. Генерация приватного ключа RSA используя 128-битное AES шифрование (-aes-128-cbc) и парольную фразу "hello" (-pass pass:hello):

Конечно, опцию -pass pass:hello можно не указывать, тогда вам будет предложено ввести пароль во время генерации ключа.

Список поддерживаемых симметричных алгоритмов шифрования приватного ключа можно узнать в документации (раздел SUPPORTED CIPHERS):

Если для генерируемого ключа не указано количество бит, то по умолчанию используется 2048, вы можете указать другое количество бит с помощью команды вида (будет создан 4096-битный ключ):

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

Здесь мы использовали наш корневой ключ для создания корневого сертификата (файл rootCA.crt), который должен распространяться на всех компьютерах, которые нам доверяют. А приватный ключ (файл rootCA.key) должен быть секретным, поскольку он будет использоваться для подписи сертификатов серверов.

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

Создание приватного ключа сертификата

Обратите внимание, что это та же самая команда, которой мы создавали пару приватный-публичный ключ Центра Сертификации (изменено только имя файла с ключами).

Создание файла с запросом на подпись сертификата (csr)

Получив закрытый ключ, вы можете приступить к созданию запроса на подпись сертификата — Certificate Signing Request (CSR). Это официальный запрос к CA о подписании сертификата, который содержит открытый ключ объекта, запрашивающего сертификат, и некоторую информацию об объекте. Все эти данные будут частью сертификата. CSR всегда подписывается закрытым ключом, соответствующим открытому ключу, который он несёт.

Создание CSR обычно представляет собой интерактивный процесс, в ходе которого вы будете предоставлять элементы отличительного имени сертификата (вводить информацию о стране, городе, организации, email и т.д.). Внимательно прочитайте инструкции, предоставленные инструментом openssl; если вы хотите, чтобы поле было пустым, вы должны ввести одну точку (.) в строке, а не просто нажать «Enter». Если вы сделаете последнее, OpenSSL заполнит соответствующее поле CSR значением по умолчанию. (Такое поведение не имеет никакого смысла при использовании с конфигурацией OpenSSL по умолчанию, что и делают практически все. Это имеет смысл, когда вы осознаете, что можете изменить значения по умолчанию, либо изменив конфигурацию OpenSSL, либо предоставив свои собственные конфигурации в файлах).

В запросе на подпись сертификата вы указываете информацию для сертификата, который хотите сгенерировать. Этот запрос будет обработан владельцем корневого ключа (в данном случае вы его создали ранее) для генерации сертификата.

Важно: имейте в виду, что при создании запроса на подпись важно указать Common Name, предоставляющее IP-адрес или доменное имя для службы, в противном случае сертификат не может быть проверен.

Я опишу здесь два способа:

  • Метод А (интерактивный)

Если вы создадите CSR таким способом, openssl задаст вам вопросы о сертификате, который необходимо сгенерировать, например, сведения об организации и Common Name (CN), которое является веб-адресом, для которого вы создаёте сертификат, например, mydomain.com.

Метод Б (в одну команду без запросов)

Этот метод генерирует тот же результат, что и метод A, но он подходит для использования в вашей автоматизации.

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

Проверка содержимого CSR

После создания CSR используйте его, чтобы подписать собственный сертификат и/или отправить его в общедоступный центр сертификации и попросить его подписать сертификат. Оба подхода описаны в следующих разделах. Но прежде чем сделать это, неплохо бы ещё раз проверить правильность CSR. Это делается так:

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

Создайте сертификат, используя csr для mydomain.com, корневые ключ и сертификат CA.

Если вы устанавливаете сервер TLS для своего собственного использования, вы, вероятно, не хотите идти в ЦС для покупки публично доверенного сертификата. Намного проще использовать сертификат, подписанный вашим собственным CA. Если вы являетесь пользователем Firefox, при первом посещении веб-сайта вы можете создать исключение для сертификата, после которого сайт будет защищён так, как если бы он был защищён общедоступным сертификатом.

Если у вас уже есть CSR, создайте сертификат, используя следующую команду:

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

  • rootCA.key — приватный ключ Центра Сертификации, должен храниться в секрете в CA
  • rootCA.crt — публичный корневой сертификат Центра Сертификации — должен быть установлен на всех пользовательских устройствах
  • mydomain.com.key — приватный ключ веб-сайта, должен храниться в секрете на сервере. Указывает в конфигурации виртуального хоста при настройке веб-сервера
  • mydomain.com.csr — запрос на подпись сертификата, после создания сертификата этот файл не нужен, его можно удалить
  • mydomain.com.crt — сертификат сайта. Указывает в конфигурации виртуального хоста при настройке веб-сервера, не является секретным.

Для глубокого понимания OpenSSL смотрите также полное руководство: «OpenSSL: принципы работы, создание сертификатов, аудит».

Создание сертификата OpenSSL

В наши дни очень часто для повышения безопасности сетевых соединений или просто для аутентификации используются SSL сертификаты. Одна из самых популярных свободных программ для создания сертификатов — это OpenSSL. Это утилита командной строки, которая позволяет создавать различные виды сертификатов, например, PKI или HTTPS.

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

Что такое сертификаты?

Думаю нужно начать с самого начала. Сертификаты в первую очередь позволяют идентифицировать человека или сервис, подтвердить что вы тот, за кого себя выдаете. А работает это так — есть два ключа — закрытый и открытый. Зашифровать сообщение можно с помощью открытого ключа, но чтобы его расшифровать нужен только закрытый ключ. Если у вас нет закрытого ключа, то вы попросту не сможете расшифровать зашифрованное сообщение. Фактически зашифровать сообщение может каждый, но расшифровать его способен только владелец закрытого (секретного ключа).

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

В этой инструкции мы будем иметь дело с такими видами ключей:

  • .pem, .crt, .cer — готовый, подписанный центром сертификации сертификат, расширения разные, но означают одно и то же. Если совсем просто, то сертификат, это подписанный открытый ключ, плюс немного информации о вашей компании;
  • .key — закрытый или открытый ключ;
  • .csr — запрос на подпись сертификата, в этом файле хранится ваш открытый ключ плюс информация, о компании и домене, которую вы указали.

А теперь рассмотрим как создать сертификат openssl, как его подписать и что для этого нужно сделать. Генерация ключей openssl — это довольно простая задача, если во всем разобраться.

Создание закрытого ключа

В этой статье я буду использовать папку

/certs для создания сертификатов. Вы можете создать эту папку и сразу перейти в неё с помощью команды:

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

openssl genrsa -out domain.key 2048

Ей необходимо передать имя файла ключа с помощью опции -out. Вы можете выбрать любое имя, оно не имеет значения. Также можно указать размер ключа, например 2048. Если этого не сделать, то будет создан ключ размером 512 бит. Все ключи размером меньше 512 бит считаются небезопасными. После выполнения команды в текущей папке появится файл ключа:

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

Создание запроса на подпись

При создании запроса на подпись нужно указать необходимую информацию. Обязательное поле здесь только одно. Это CN. Здесь должно быть указанно ваше доменное имя, для которого вы собираетесь использовать сертификат, также можно указать дополнительную информацию о вашей компании, адресе и организации, но это уже необязательно. Для создания запроса на подпись для ранее созданного ключа используйте такую команду:

openssl req -key domain.key -new -out domain.csr

Во время создания запроса большинство параметров можно оставить по умолчанию. Обязательно заполнять только Common Name (e.g. server FQDN or YOUR name). Если вы хотите создать сертификат для сайта, то в этом поле нужно указать домен этого сайта. В этом примере будет создан сертификат для localhost:

Вы также можете создать закрытый ключ и запрос на подпись открытого ключа одной командой:

openssl req -newkey rsa:2048 -nodes -keyout domain.key -out domain.csr

Опция -newkey указывает, что нужно создать новую пару ключей, а в параметрах мы сообщаем тип rsa и сложность 2048 байт. Опция -nodes указывает, что шифровать ключ не нужно, опция -new указывает что нужно создать запрос csr.

Кроме того, можно создать csr запрос из уже существующего сертификата и закрытого ключа, тогда вам не придется вводить информацию, она будет получена из сертификата:

openssl x509 -in domain.crt -signkey domain.key -x509toreq -out domain.csr

Параметр —x509toreq указывает, что нужно использовать сертификат для X509 для получения CSR. X509, это сертификаты, подписанные сами собой. Обычно сертификат подписывается другим сертификатом, а этот был подписан сам собой. Если вы получили сертификат от CA, то этот параметр не нужен.

Подпись сертификатов OpenSSL

Допустим, у вас есть приватный ключ и запрос на подпись, фактически, открытый ключ. Теперь вам нужно его подписать чтобы получить сертификат, который можно использовать. Тут есть несколько вариантов. Можно отправить csr файл на подпись какому-либо центру сертификации, например, LetsEncrypt. Можно подписать сертификат тем же ключом, с помощью которого он был создан, и третий вариант — создать свой центр сертификации.

Первый способ я рассматривать не буду. Здесь все просто. Либо используете утилиту сервиса, либо заполняете веб форму и получаете готовый сертификат. Второй вариант гораздо интереснее.

Подпись сертификата самим собой

Мы подпишем наш сертификат сами, ключом, на основе которого он был создан:

openssl x509 -signkey domain.key -in domain.csr -req -days 365 -out domain.crt

С помощью параметра -days мы указываем что сертификат будет действительным в течение 365 дней, то есть в течение года. Обратите внимание, что во время подписи проверяется CN, поэтому если вы не зададите этот параметр на этапе создания запроса на подпись, то ничего не заработает.

Вы можете объединить все в одну команду и сразу создать закрытый ключ, csr и подписанный сертификат:

openssl req -newkey rsa:2048 -nodes -keyout domain.key -x509 -days 365 -out domain.crt

Или создать самоподписанный сертификат openssl из существующего закрытого ключа без csr:

openssl req -key domain.key -new -x509 -days 365 -out domain.crt

Опция -new говорит, что нужно запросить информацию о csr у пользователя. Чтобы браузер доверял ключу нужно этот же сертификат импортировать в список доверенных.

Подпись сертификатов с помощью OpenSSL

А теперь рассмотрим третий способ выполнить создание сертификата OpenSSL — подписать его с помощью собственного CA, центра сертификации.

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

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

Дальше нужно создать самоподписанный сертификат openssl для нашего CA.

openssl req -newkey rsa:2048 -nodes -keyout ca.key -x509 -days 3654 -out ca.crt

С помощью параметра -days мы устанавливаем долгий строк действия — десять лет. Программа запросит стандартные данные, которые используются при создании сертификатов. Эти данные будут выводится в браузере при просмотре информации о центре сертификации если вы будете использовать подписанные сертификаты для HTTPS. В поле Common Name можно указать имя вашей организации:

Осталось подписать наш сертификат, созданный ранее:

openssl x509 -req -in

/certs/domain.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out domain.crt -days 365

Готово, теперь наш сертификат подписан. Но теперь, чтобы браузеры ему доверяли нужно добавить сертификат CA в список доверенных сертификатов браузера.

Подпись сертификатов с помощью EasyRSA

Создание центра сертификации можно немного упростить. Существует набор скриптов под названием EasyRSA, который позволяет инициализировать центр сертификации, а также подписывать и отзывать сертификаты. Сначала установите пакет easy-rsa из официальных репозиториев:

sudo apt install easy-rsa

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

После этого скопируйте файлы из /usr/share/easy-rsa/ в эту папку:

cp -R /usr/share/easy-rsa/*

Дальше перейдите в неё и инициализируйте центр сертификации:

Прежде чем вы сможете создать сертификат, необходимо создать файл vars и в нём прописать информацию о центре сертификации. Например:

set_var EASYRSA_REQ_COUNTRY «US» set_var EASYRSA_REQ_PROVINCE «California» set_var EASYRSA_REQ_CITY «California» set_var EASYRSA_REQ_ORG «Losst» set_var EASYRSA_REQ_EMAIL «support@losst.pro» set_var EASYRSA_REQ_OU «Losst» set_var EASYRSA_ALGO «rsa» set_var EASYRSA_DIGEST «sha512»

Первые 7 параметров аналогичны тем, что заполняются при создании запроса на подписание сертификата. Параметр EASYRSA_ALGO позволяет настроить алгоритм шифрования, можно использовать стандартный RSA или алгоритм на основе эллиптических кривых ES. Последний параметр — это формат подписи сертификатов. После этого можно создать сертификат CA:

Для корневого сертификата необходимо задать пароль. Если этого не сделать, сертификат не будет создан:

А в Common Name можно указать название центра сертификации, которое будет отображаться в браузере в информации о том кем подписан сертификат:

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

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

После этого вы можете подписать этот запрос используя имя, заданное при импорте:

./easyrsa sign-req server domain-server

Команде необходимо передать два параметра тип сертификата и имя запроса. Тип сертификата может быть server или client. Программа попросит подтвердить данные сертификата, наберите yes и нажмите Enter:

А затем нужно будет ввести пароль от корневого сертификата. После этого будет создан новый сертификат в папке pki/issued с расширением .crt.

Просмотр сертификатов

Сертификаты сохраняются в формате PEM, а это значит, что вы не сможете их открыть как текстовый файл и нужно использовать специальные команды для просмотра информации о них. Сначала смотрим содержимое CSR:

openssl req -text -noout -verify -in domain.csr

Смотрим содержимое сертификата в режиме обычного текста:

openssl x509 -text -noout -in domain.crt

Проверяем действительно ли сертификат подписан нужным CA:

openssl verify -verbose -CAfile

Просмотр закрытого ключа:

openssl rsa -check -in domain.key

Чтобы проверить связаны ли между собой закрытый ключ, сертификат и открытый ключ (запрос на подпись) можно подсчитать сумы md5 для этих ключей, если значения совпадут, то есть вероятность что это ключи из одной пары:

openssl rsa -noout -modulus -in

/certs/domain.key | openssl md5 openssl x509 -noout -modulus -in

/certs/domain.crt | openssl md5 openssl req -noout -modulus -in

/certs/domain.csr | openssl md5

Как использовать сертификат

Не зависимо от того какой способ создания сертификата OpenSSL вы выбрали у вас будет два файла. Это файл закрытого ключа с расширением .key и файл сертификата с расширение .crt. В данном примере это:

  • domain.key
  • domain-server.crt

Также вам может понадобится сертификат fullchain. Обычно этот файл содержит сам подписанный сертификат и сертификаты промежуточных центров сертификации. Но в случае если вы подписываете сертификат своим центром сертификации, промежуточных сертификатов у вас нет, а значит в качестве fullchain можно использовать сам подписанный сертификат.

Если вы хотите подключить ваши сертификаты к Apache, используйте такие директивы в файле виртуального хоста:

SSLEngine on SSLCertificateFile /путь/к/сертификату/domain-server.crt SSLCertificateKeyFile /путь/к/файлу/domain.key SSLCertificateChainFile /путь/к/файлу/domain-server.crt

Для Nginx директивы подключения сертификатов выглядят похожим образом:

ssl_certificate /путь/к/файлу/domain-server.crt ssl_certificate_key /путь/к/файлу/domain.key

Их нужно добавить внутри блока server для сайта на котором вы хотите настроить HTTPS.

Выводы

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

Как создавать надежные SSL-сертификаты для локальной разработки

Случалось ли так, что вы понимали — необходимо добавить HTTPS в приложение, запущенное на локальном хостинге или каком-нибудь еще местном домене вроде local.my-app.com ?

Есть некоторые различия в том, как браузеры работают с HTTP и HTTPS. Например, любые попытки загрузить JavaScript на HTTPS-странице по HTTP-ссылке будут заблокированы. Это значит, что если локальная разработка идет на HTTP, то добавленный тэг скрипта прекрасно будет работать на вашей машине, но сломается, как только вы развернете приложение на промежуточном или продакшен-окружении, где всё работает под HTTPS. Не очень вдохновляющая перспектива.

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

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

В этой статье мы разберем процесс создания локального корневого сертификата (также известного, как источник сертификатов). Это позволит вам создавать сколько угодно сертификатов для доменных имен, но доверять только одному сертификату — корневому.

Важно отметить вот что: с 1 сентября 2020 года SSL-сертификаты не выдаются дольше, чем на тринадцать месяцев (397 дней). Поэтому для сертификатов, создаваемых в этой статье, мы ограничимся двенадцатью месяцами.

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

Источник сертификата (Certificate Authority)

1. Создайте закрытый ключ и самоподписанный сертификат

Опционально: если необходимо, можно заменить MY-CA в CN на что-нибудь другое.

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

2. Создайте файл сертификата с расширением .crt :

Сертификат доменного имени

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

1. Создайте файл расширения x509 v3:

Следуя этому шаблону, можно добавить сколько угодно доменных имен.

Примечание: пожалуйста, обновите DNS.4, DNS.5 и DNS.6 или удалите их, если у вас не настроены никакие локальные доменные имена.

2. Создайте закрытый ключ и запрос на подпись сертификата:

Опционально: страну, штат, город и организацию можно изменять.

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

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

Приложениям, обслуживающим ваш контент, понадобится доступ к файлам сертификата и закрытого ключа. Это может быть локальный веб-сервер (Apache или NGINX), локальный сервис или какой-то другой локальный инструмент, допустим, сборщик модулей DevServer.

Вот несколько примеров:

Apache

NGINX

webpack DevServer

Express.js

Как только вы настроите обслуживающий ваше приложение инструмент на работу с вашим сертификатом, ваше приложение будет доступно по URL’у с HTTPS.

Следуя приведенному выше примеру с Express, вы можете открыть вкладку браузера по адресу https://localhost:8000 и увидеть ваш контент:

Погодите секунду! Где же сообщение «это защищенный сервер»?

Вы рассчитывали увидеть кое-что другое, но именно этого и следовало ожидать — потому что источник сертификата еще не входит в число доверенных.

Доверие к сертификатам

Чтобы получить обозначение безопасного доступа, ваш новый источник сертификата должен считаться доверенным на вашей машине. Процесс присваивания этого статуса различается в зависимости от операционной системы и удовлетворит большинство браузеров. Если вы используете Firefox, процесс имеет некоторые отличия.

macOS — Chrome и Safari

1. Дважды кликните на корневом сертификате ( ca.crt ).

2. Выберите нужную связку ключей [keychain] ( login , если вы хотите, чтобы сертификат считался доверенным только в вашем аккаунте, или System , если сертификат должен считаться доверенным во всей системе).

3. Добавьте сертификат.

4. Откройте «Keychain Access» (если еще не открыт).

5. Выделите keychain, который выбрали раньше.

6. Вы должны увидеть сертификат MY-CA (это будет имя, которое вы, как CN, дали вашему источнику сертификата).

7. Дважды кликните по сертификату.

8. Разверните «Доверять» и выберите опцию «Доверять всегда» в пункте «При использовании этого сертификата».

9. Закройте окно сертификата и введите свой пользовательский пароль (если требуется).

Windows 10 — Chrome, IE11 и Edge

1. Дважды кликните на сертификате ( ca.crt ).

2. Кликните на кнопку «Установить сертификат».

3. Выберите, хотите ли вы хранить его на уровне пользователя или на уровне машины.

4. Кликните «Дальше».

5. Выберите «Разместить все сертификаты в следующем хранилище».

6. Кликните «Обзор».

7. Выберите «Доверенные корневые источники сертификатов».

9. Кликните «Дальше».

10. Кликните «Завершить».

11. Если появится подсказка, кликните «Да».

Firefox

Даже после того, как вы установите доверенный источник сертификата в хранилище, Firefox все равно будет выдавать предупреждения. Этого может не случиться в Windows 10, но почти наверняка случится в macOS. Справиться с этим достаточно просто. Firefox демонстрирует вот такой экран:

Чтобы добавить разрешения сертификату, кликните «Дополнительно…». Сразу же после этого кликните на «Принять риск и продолжить», чтобы дать понять, что вы знаете о риске.

Это нужно сделать всего один раз, но для каждого локального домена.

Заключение

Теперь, когда сертификат создан и доверие к нему обеспечено, вы без проблем можете посещать свой локальный домен! Обслуживание приложений стало безопасным, и вы можете спокойно продолжать разработку. Возвращаясь к примеру с Express, результат на экране будет таким:

Сайт полностью загружен, и рядом с URL в Chrome теперь отображается символ безопасного соединения.

Сам себе PKI: Практика на примере OpenSSL и CA Smallstep. (Статья 2)

В предыдущей статье «Сам себе PKI: Теория на примере Let’s Encrypt» мы рассмотрели теорию и разобрали пример, как происходит установка HTTPS соединения между браузером и веб-сайтом при использовании сертификатов Let’s Encrypt. В этой статье перейдем к практике и самостоятельно реализуем ту же самую схему:

Сначала вручную (с помощью OpenSSL) пройдем цепочку генерации и использования самоподписанных сертификатов в HTTPS сервере.

Далее развернем собственный удостоверяющий центр Smallstep и будем получать сертификаты, подписанные им.

Схема PKI остаётся той же, только изменяются компоненты:

В качестве CA вместо Let’s Encrypt, будет использоваться OpenSSL и CA Smallstep.

В роли Web-сервера вместо Интернет веб-сайта, будет выступать простой HTTPS сервер, запущенный на Node.js.

Практика Self-signed certificate

OpenSSL

Начнем с классики криптографии OpenSSL. Сейчас широко используется версия 1.1.1, но ее поддержка заканчивается в 2023. Следующая версия 3.0 будет поддерживаться до 2026 года. Проверка установленной версии:

OpenSSL 1.1.1k FIPS 25 Mar 2021

Если OpenSSL не установлен, то его можно установить на всех востребованных платформах.

Реализация TLS

Для нашего CA генерируем приватный ключ 2048-бит RSA. Администратор CA должен хранить его в секрете от всех:

openssl genrsa -out root_ca.key 2048

Далее для нашего CA генерируем X.509 сертификат на 365 дней (root_ca.crt) и подписываем его приватным ключом (root_ca.key). Получается самоподписанный сертификат, его можно и нужно будет скопировать на все компьютеры, между которыми необходимо организовать TLS соединение. При ответах на вопросы, которые будет задавать OpenSSL, можно указывать произвольные данные, CA я назвал «My CN»:

openssl req -x509 -new -key root_ca.key -days 365 -out root_ca.crt

Смотрим получившийся сертификат, убеждаемся, что данные в нем корректные:

openssl x509 -text -in root_ca.crt

Генерируем приватный ключ для HTTPS сервера, его нужно будет скопировать только на компьютер, на котором он будет работать и никуда больше:

openssl genrsa -out server.key 2048

Генерируем запрос на сертификат CSR. В этом запросе нужно передать конкретные значения в параметре «subj». Это должны быть один или несколько параметров CN (Common Name), которые будут прописаны в атрибутах сертификата «Subject» и «Subject Alternative Name». Фактически CN-ы — это IP адреса и имена хостов, по которым будет осуществляться доступ к серверу. Имена хостов могут быть как в формате доменного имени, так и FQDN:

openssl req -new -key server.key -subj «/CN=xx.xx.xx.xx/CN=server/CN=server.example.com» -out server.csr

Можно посмотреть получившийся запрос на сертификат и убедиться в его корректности:

openssl req -text -in server.csr

Теперь генерируем сертификат X.509 (server.crt) на 365 дней для HTTPS сервера и подписываем его приватным ключом CA (root_ca.key):

openssl x509 -req -in server.csr -CA root_ca.crt -CAkey root_ca.key -CAcreateserial -out server.crt -days 365 -extensions SAN -extfile openssl.cnf

Файл openssl.cnf должен содержать список SAN (Subject Alternative Name) идентичный тому, что был в CSR запросе на сертификат:

Можно посмотреть на получившийся сертификат и убедиться в его корректности:

openssl x509 -text -in root_ca.crt

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

Пишем простейший HTTPS сервер, на JS:

Запускать данный скрипт будем с помощью Node.js. Если Node.js не установлен, то устанавливаем:

sudo yum groupinstall ‘Development Tools’

sudo yum install nodejs

Проверяем, что Node и Npm установились успешно:

Проверяем сервер curl-ом:

При первом запросе возникнет ошибка:

curl: (60) SSL certificate problem: self signed certificate in certificate chain

Это значит, что самоподписанный корневой сертификат нашего CA (root_ca.crt) не находится в хранилище доверительных сертификатов. Процесс загрузки сертификатов в это хранилище специфичен для операционной системы. Приведу алгоритм для RH Linux:

Если сертификат не в PEM (текстовом) формате, то его надо сконвертировать в текстовой формат:

openssl x509 -in root_ca.crt -out root_ca.pem -outform PEM

Копируем сертификат в определенный каталог на сервере. ДляRH 7 и выше это каталог:

Выполняем команду обновления хранилища сертификатов:

Теперь curl проходит

на Windows есть специфика — в curl необходимо добавлять параметр «ssl-no-revoke», чтобы не проверялся список отозванных сертификатов:

curl —ssl-no-revoke https://server.example.com:9443

При этом сервер выведет в консоль строку:

Это значит, что мы установили TLS соединение только с проверкой сертификата сервера, а не клиента. Переходим к mTLS.

Реализация mTLS

В коде сервера включаем mTLS, а именно выставляем в true параметр requestCert, чтобы HTTPS сервер запрашивал клиентский сертификат и параметр rejectUnauthorized, чтобы сервер отклонял запросы клиентов, которые не прошли авторизацию:

Алгоритм генерации клиентских сертификатов аналогичен серверным.

Генерируем приватный ключ для клиента:

openssl genrsa -out client.key 2048

Генерируем запрос на сертификат CSR со списком CN:

openssl req -new -key client.key -subj «/CN=xx.xx.xx.xx/CN=client/CN=client.example.com» -out client.csr

Генерируем сертификат для клиента и подписываем его приватным ключом CA:

openssl x509 -req -in client.csr -CA root_ca.crt -CAkey root_ca.key -CAcreateserial -out client.crt -days 365 -extensions SAN -extfile openssl.cnf

Файл openssl.cnf — такой же как и для сервера, только вместо «server» пишем «client».

Копируем следующие файлы на компьютер, на котором будет работать клиент:

Теперь если просто вызвать curl:

То произойдет ошибка авторизации

curl: (35) error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure

Поэтому вызываем curl с дополнительными параметрами, в которых указываем ключ клиента и сертификаты клиента и СА:

curl —cert ./client.crt —key client.key —cacert root_ca.crt https://server.example.com:9443

Теперь запрос проходит, при этом сервер выведет в консоль следующую строку и далее содержимое полученного от клиента сертификата:

Это значит, что мы установили mTLS соединение с проверкой сертификата как сервера, так и клиента. Теперь установим mTLS из браузера.

Реализация mTLS в браузере

Если просто запустить наш запрос к серверу (https://server.example.com:9443) из браузера, то выдается ошибка клиентского сертификата ERR_BAD_SSL_CLIENT_AUTH_CERT. Рабочие адреса закрасил желтым:

Для загрузки в браузер клиентский сертификат и приватный ключ надо сконвертировать в формат p12. Этот формат определяется стандартом PKCS #12 и является архивом для хранения нескольких объектов. В нашем случае файл будет хранить клиентский сертификат и его приватный ключ. Понятно, что приватный ключ — это чувствительная к разглашению информация и ее владелец не должен выкладывать p12 сертификат в открытый доступ. Для конвертации тоже используем OpenSSL:

openssl pkcs12 -inkey client.key -in client.crt -export -out client.p12

Импортируем client.p12 в браузер. Для этого, например в Chrome, идем в меню: Settings / Privacy and security / Manage certificates, в открывшемся окне нажимаем Import, выбираем наш файл client.p12 и место хранения «Personal». Видим, что клиентский сертификат, выданный нашим удостоверяющим центром «My CN», появился в хранилище персональных сертификатов:

Вызываем запрос заново, уже лучше, но браузер все равно пишет, что соединение не безопасно. Это из-за того, что клиентский сертификат выдан удостоверяющим центром «My CN», которого нет в списке доверительных CA (Trusted Root Certification Authorities).

Добавляем корневой сертификат нашего CA (root_ca.crt) в Trusted Root Certification Authorities. Делается с помощью того же вызова Import, что и для клиентского сертификата, но хранилище указываем Trusted Root Certification Authorities. Проверяем, что наш CA «My CN» появился в хранилище:

Повторяем наш запрос (https://server.example.com:9443). При первом запросе браузер находит подходящий клиентский сертификат и просит явно подтвердить его использование:

Дальнейшие вызовы проходят без запросов на подтверждение клиентского сертификата:

Если щелкнуть на замочке а адресной строке, то можно посмотреть сертификат сервера и убедиться, что мы взаимодействуем с правильным сервером (Issued to: server.example.com), сертификат которому выдан нашим удостоверяющим центром (Issued by: My CN) и время действия сертификата еще не прошло (Valid to: 31.05.2023):

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

Дополнительные возможности OpenSSL

Конвертация форматов сертификатов

Конвертируем сертификат в der (бинарный формат):

openssl x509 -outform der -in client.crt -out client.der

Конвертируем сертификат в PEM (текстовой формат)

openssl x509 -inform der -in client.cer -out client.pem

Отладка с помощью OpenSSL

Проверка, что сертификат подписан определенным (root_ca.pem) удостоверяющим центром:

openssl verify -verbose -x509_strict -CAfile root_ca.pem server.crt

Запускаем OpenSSL server

openssl s_server -accept 9443 -cert server.crt -key server.key

Запускаем OpenSSL client

openssl s_client -connect xx.xx.xx.xx:9443 -prexit -showcerts -state -status -tlsextdebug -verify 10

При вызове curl параметр:

-k — позволяет подсоединяться к серверу без проверки цепочки сертификатов (certificate path validation).

—ssl-no-revoke — предотвращает проверку отозванных сертификатов

Практика CA Smallstep

Установка Smallstep и CLI step

CA Smallstep — это open source CA, который можно развернуть локально для автоматического получения X.509 сертификатов. На официальном сайте есть ряд инструкций по его установке и настройке. Для экспериментов я использовал вариант с docker:

Краткая выжимка из инструкции по установке на RH Linux. Сначала устанавливаем docker:

sudo yum -y update

sudo yum install -y yum-utils

sudo yum-config-manager —add-repo https://download.docker.com/linux/centos/docker-ce.repo

sudo yum -y install docker-ce

sudo systemctl start docker

Проверяем корректность установки docker:

sudo docker run hello-world

sudo docker pull smallstep/step-ca

Инициализируем наш CA:

docker run -it -v step:/home/step smallstep/step-ca step ca init

При инициализации по умолчанию будет ряд ограничений, например, будут одинаковые пароли для корневого и промежуточного приватного ключа. Для разворота в промышленную среду необходимо внимательно изучить рекомендации Production considerations when running a certificate authority server.

При создании CA в консоль будет выведен fingerprint корневого сертификата в виде шестнадцатеричной строки (например: 55de8dc05cd. 8a70f725a56). Ее надо сохранить для последующей инициализации утилиты CLI step, которая используется для взаимодействия с CA Smallstep. Проверяем, что CA Smallstep запущен корректно. xx.xx.xx.xx:9000 — это IP и порт, на котором запущен Smallstep CA:

должна вернуться строка:

На этом же или другом компьютере по инструкции устанавливаем утилиту CLI step. Краткая выжимка:

tar -xf step_linux_0.19.0_386.tar.gz

Копируем утилиту step в /usr/bin

Регистрируем CLI step для использования с нашим CA. Этот процесс называется «bootstrap». Значение параметра «ca-url» — это IP и порт, на котором запущен Smallstep CA, «fingerprint » — это сохраненное значение при инициализации CA:

step ca bootstrap —ca-url https://xx.xx.xx.xx:9000 —fingerprint 55de8dc05cd. 8a70f725a56 —install

Проверка связи с CA:

должна вернуться строка:

Все готово для генерации ключей и сертификатов.

Генерация ключей и сертификатов

Также как и в случае с OpenSSL, сначала генерируем ключ и сертификат для сервера и установки TLS соединения, потом для клиента и установки mTLS.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *