Как создать цепочку сертификатов ssl
Перейти к содержимому

Как создать цепочку сертификатов ssl

  • автор:

Круг интересов

Full-stack development: Python, PostgreSQL, JavaScript, Linux, Git e t.c.

Создание валидной цепочки SSL сертификатов

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

Чтобы не писать кучу команд всякий раз, напишем bash-скрипт. Для начала, зададим несколько настроечных констант:

CSR_FILE="csrfile.csr" KEY_BITS=2048 CONF_DIR="conf" CHAIN_CRT="ca_chain.crt"

Затем пара функций для подготовки и последующей подчистки каталога с настройками:

function clean  find conf -not -name '*.cnf' -type f -delete rm -f $CSR_FILE $CHAIN_CRT > function prepare  clean echo 1000 > "$CONF_DIR/root_serial" cp /dev/null "$CONF_DIR/root_index.txt" echo 2000 > "$CONF_DIR/im_serial" cp /dev/null "$CONF_DIR/im_index.txt" > prepare

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

ROOT_URL="mycorp.com" ROOT_ORG="MYCORP" ROOT_CNF="$CONF_DIR/root_openssl.cnf" ROOT_CRT="root.crt" ROOT_KEY="root.key" ROOT_EXP=5000 ROOT_SUB="/C=RU/ST=Moscow/L=Moscow/O=$ROOT_ORG/CN=$ROOT_URL" # Generate root key openssl genrsa -out $ROOT_KEY $KEY_BITS # Generate root certificate openssl req -config $ROOT_CNF -new -x509 -sha256 -extensions v3_ca \ -key $ROOT_KEY -out $ROOT_CRT -days $ROOT_EXP -subj $ROOT_SUB # Verify root certificate openssl x509 -noout -text -in $ROOT_CRT

Хорошо, теперь создадим промежуточный сертификат с ключом:

IM_CRT="intermediate.crt" IM_KEY="intermediate.key" IM_CNF="$CONF_DIR/im_openssl.cnf" IM_EXP=4000 IM_SUB="/C=RU/ST=Moscow/L=Moscow/O=$ROOT_ORG>/CN=department.$ROOT_URL>" # Generate intermediate key openssl genrsa -out $IM_KEY $KEY_BITS # Generate intermediate request openssl req -config $IM_CNF -new -key $IM_KEY -out $CSR_FILE -subj $IM_SUB # Generate intermediate certificate openssl ca \ -config $ROOT_CNF -batch \ -extensions v3_intermediate_ca -notext -md sha256 \ -days $IM_EXP -in $CSR_FILE -out $IM_CRT # Verify intermediate certificate openssl x509 -noout -text -in $IM_CRT openssl verify -CAfile $ROOT_CRT $IM_CRT

Обратите внимание, что команда на создание промежуточного сертификата берет конфигурацию корневого ( $ROOT_CNF ), т.е. подписывать будем им. Также важно, чтобы срок подписываемого был меньше срока подписывающего.

Ну а теперь, собственно, итог:

SERVER_CRT="server.crt" SERVER_KEY="server.key" SERVER_EXP=365 SERVER_SUB="/C=RU/ST=Moscow/L=Moscow/O=MYSERVER/CN=myserver.com" # Generate key openssl genrsa -out $SERVER_KEY $KEY_BITS # Generate request openssl req \ -config $IM_CNF -key $SERVER_KEY -new -sha256 \ -out $CSR_FILE -subj $SERVER_SUB # Generate certificate openssl ca \ -batch \ -config $IM_CNF -days $SERVER_EXP \ -extensions server_cert \ -notext -md sha256 \ -in $CSR_FILE -out $SERVER_CRT # Verify certificate cat $IM_CRT $ROOT_CRT > $CHAIN_CRT openssl verify -CAfile $CHAIN_CRT $SERVER_CRT

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

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

[ CA_default ] dir = conf certs = $dir crl_dir = $dir new_certs_dir = $dir
database = $dir/root_index.txt serial = $dir/root_serial private_key = $dir/../root.key certificate = $dir/../root.crt
database = $dir/im_index.txt serial = $dir/im_serial private_key = $dir/../intermediate.key certificate = $dir/../intermediate.crt

Строго говоря, проверка корректности уже была произведена в процессе создания. Но так как мне нужно было делать это в Python, я использовал библиотеку pyOpenSSL, а именно модуль crypto. Для примера покажу, как это можно сделать без затей:

from OpenSSL import crypto # Prepare X509 objects root_cert = crypto.load_certificate( crypto.FILETYPE_PEM, open('root.crt').read() ) intermediate_cert = crypto.load_certificate( crypto.FILETYPE_PEM, open('intermediate.crt').read() ) server_cert = crypto.load_certificate( crypto.FILETYPE_PEM, open('server.crt').read() ) # Prepare X509 store store = crypto.X509Store() store.add_cert(root_cert) store.add_cert(intermediate_cert) # Verify crypto.X509StoreContext(store, server_cert).verify_certificate()

Для X509Store можно добавить флаги проверок, которые все сломают. К примеру, если добавить вот такой флаг, то получим исключение OpenSSL.crypto.X509StoreContextError :

store.set_flags(crypto.X509StoreFlags.CRL_CHECK)

А все потому, что будет предпринята попытка скачать CRL-файл, указанный в дополнениях сертификата, и эта попытка провалится. Как с этим бороться, как добавить Issuer URL и т.п. — это совсем другая история, которая в принципе вся решается через конфигурацию openssl .

Весь пример доступен на github

Как создать файл цепочки SSL сертификатов

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

Пример:
● сертификат для домена — domain.crt
● сертификат посредника 3 — Intermediate3.crt
● сертификат посредника 2 — Intermediate2.crt
● сертификат посредника 1 — Intermediate1.crt
● корневой сертификат — CARoot.crt
Обратите внимание, что в саму цепочку помещать сертификат домена не следует.

Обычно центр сертификации прилагает к SSL-сертификату уже сформированную цепочку — domain.ca-bundle. Если в архиве с сертификатом её нет, необходимо сформировать цепочку самостоятельно. Это можно сделать двумя способами:

1. С помощью текстового редактора:
a. откройте файлы
b. создайте новый документ
c. скопируйте в новый документ содержание каждого из файлов в последовательности: сертификат посредника 3, сертификат посредника 2, сертификат посредника 1, корневой сертификат
d. сохраните файл как domain.ca-boundle

2. С помощью командной строки:
a. В операционной системе семейства UNIX: cat “сертификат посредника 3” “сертификат посредника 2” “сертификат посредника 1” “корневой сертификат” > domain.ca-bundle
b. В Windows/DOS: copy “сертификат посредника 3” + “сертификат посредника 2” + “сертификат посредника 1” + “корневой сертификат” domain.ca-bundle

Другие вопросы из категории

Как создать цепочку сертификатов?

Товарищи, столкнулся с проблемой при добавлении сертификатов в хранилище для авторизации на сервере, куда посылается http запрос. Суть такая есть 3 сертификата, от клиентского до корневого сервера, куда будет посылаться запрос. Для авторизации требуется подставить сразу все эти сертификаты. Java приложение в момент запроса авторизации ищет по java kestore подходящий по запрос сертификат. Получается нужно как-то создать цепочку сертификатов, которые выглядели как иерархия от клиентского до серверного.
Я могу лишь средствами keytool добавить сертификат в хранилище:
keytool -import -trustcacerts -alias ca1 -file ca1.crt -keystore server.jks

Вопрос только один как выстроить цепочку.

  • Вопрос задан более трёх лет назад
  • 4665 просмотров

Комментировать
Решения вопроса 1

oleg_sidorenkov

oleg_sidorenkov @oleg_sidorenkov Автор вопроса

Видел это решением на других пабликах, но пошел по другому пути:
1. С помощью текстового редактора:
a. откройте файлы
b. создайте новый документ
c. скопируйте в новый документ содержание каждого из файлов в последовательности: сертификат посредника 1, сертификат посредника 2, сертификат посредника 3, корневой сертификат
d. сохраните файл

Должно получиться что-то вроде:
——BEGIN CERTIFICATE——
MIICBzCCAXACCQDBBdYCGkYdkDANBgkqhkiG9w0BAQUFADBIMS owKAYJKoZIhvcN
AQkBFht3ZWJtYXN0ZXJAYmlsbG1ncnNlcnZlci5jb20xGjAYBg NVBAMTEWJpbGxt
Z3JzZXJ2ZXIuY29tMB4XDTEzMDQxNDE2MzgyNloXDTIzMDQxMj E2MzgyNlowSDEq
MCgGCSqGSIb3DQEJARYbd2VibWFzdGVyQGJpbGxtZ3JzZXJ2ZX IuY29tMRowGAYD
VQQDExFiaWxsbWdyc2VydmVyLmNvbTCBnzANBgkqhkiG9w0BAQ EFAAOBjQAwgYkC
gYEA00K2OIK5rsHToFmv2lqAPsmQs3BYKhADm7sC69FqIUWQtf EzGNa24Wts/SAp
7tjPWb7couX0+6pekekc6lfJitUd27M2yhblzpF3eYIhAT5o7F X/K54S3B4vT7Ky
WXC7I1LXC9xAHnErhpIc97wPS7R0IKQ8J5rWdsaOdYx79s0CAw EAATANBgkqhkiG
9w0BAQUFAAOBgQArdad2hqOORfYeV0xcbFSyLkVHVgeuF9ulBo E7qsd777ylBySi
0Pg1WGnkaByBGmhphzwfj7cWE75o0p955z4VPNv+4fHNli9Hz4 vTQjQIbQ+iCGBK
XLIvfWmbzOW8orPhk2cULY1uQboQK+TUTm0Fj/2/DR/cSbFUSo2Wn66WPg==
——END CERTIFICATE——
——BEGIN CERTIFICATE——
MIICBzCCAXACCQDBBdYCGkYdkDANBgkqhkiG9w0BAQUFADBIMS owKAYJKoZIhvcN
AQkBFht3ZWJtYXN0ZXJAYmlsbG1ncnNlcnZlci5jb20xGjAYBg NVBAMTEWJpbGxt
Z3JzZXJ2ZXIuY29tMB4XDTEzMDQxNDE2MzgyNloXDTIzMDQxMj E2MzgyNlowSDEq
MCgGCSqGSIb3DQEJARYbd2VibWFzdGVyQGJpbGxtZ3JzZXJ2ZX IuY29tMRowGAYD
VQQDExFiaWxsbWdyc2VydmVyLmNvbTCBnzANBgkqhkiG9w0BAQ EFAAOBjQAwgYkC
gYEA00K2OIK5rsHToFmv2lqAPsmQs3BYKhADm7sC69FqIUWQtf EzGNa24Wts/SAp
7tjPWb7couX0+6pekekc6lfJitUd27M2yhblzpF3eYIhAT5o7F X/K54S3B4vT7Ky
WXC7I1LXC9xAHnErhpIc97wPS7R0IKQ8J5rWdsaOdYx79s0CAw EAATANBgkqhkiG
9w0BAQUFAAOBgQArdad2hqOORfYeV0xcbFSyLkVHVgeuF9ulBo E7qsd777ylBySi
0Pg1WGnkaByBGmhphzwfj7cWE75o0p955z4VPNv+4fHNli9Hz4 vTQjQIbQ+iCGBK
XLIvfWmbzOW8orPhk2cULY1uQboQK+TUTm0Fj/2/DR/cSbFUSo2Wn66WPg==
——END CERTIFICATE——

Затем засунул это сертификат в контейнер, и получилось то что нужно

Сшиваем SSL-сертификаты правильно на bash

Ускорение и защита сайта

Использование SSL-шифрование на сайтах приобретает уже почти обязательный характер: Google с этого года начал агрессивно предупреждать о небезопасном соединении с сайтами, ряд платежных шлюзов требуют безопасное подключение на сайтах (например, Яндекс.Касса). Установка SSL-сертификата на сайт требует достаточно сложной технической настройки веб-сервера (nginx, например). Одним из аспектов этой настройки является использование «сшивания» (stapling) SSL-сертификатов вплоть до корневого для ускорения установления безопасного соединения из браузеров к сайтам.

SSL stapling позволяет сэкономить для нового посетителя сайта 0,1-1 секунду (за счет экономии 1-2 запросов за промежуточными сертификатами с учетом DNS-запросов, установления соединения и получения данных, каждый из запросов может выполняться до 500 мс в случае 95 перцентиля пользователей). По умолчанию, SSL stapling выполняется для всех сертификатов, загруженных в Айри.

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

SSL-сертификат сайта — Промежуточный SSL-сертификат [- Промежуточный SSL-сертификат 2] — Корневой SSL-сертификат

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

Openssl

Основным рабочим инструментом будет библиотека openssl: она позволяет реализовать преобразование сертификатов и извлечение необходимой информации в текстовом формате (в сертификате информация закодирована либо в бинарном формате (DER), либо в base64 (PEM)).

Если на сервере вы подключаете SSL-шифрование для сайта, то сама библиотека, скорее всего, у вас уже установлена. Проверить, например, для какого домена (Canonical name) выпущен сертификат (если он в PEM формате, обычно в таком формате сертификаты выпускаются и передаются для установки на сервер) можно так:

openssl x509 -in ФАЙЛ_СЕРТИФИКАТА -subject -noout

Здесь x509 — входящий формат сертификата, in — ключ для входного файла, subject — указание вывести CN сертификата, а noout — запрет на вывод самого сертификата (в PEM формате).

Получаем «родительский» сертификат

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

openssl x509 -in "ФАЙЛ_СЕРТИФИКАТА" -text -noout

После этого нам нужно лишь выделить поле Issuers и получить из него URL. Это можно сделать, например, так:

openssl x509 -in "ФАЙЛ_СЕРТИФИКАТА" -text -noout | grep Issuers | awk ''

Получив URL сертификата, скачиваем его любым удобным образом. Например, через curl:

curl --user-agent "Mozilla/5.0 (compatible; Airee-Speedup/1.0; +http://airee.ru/robots)" $issuer -o /tmp/stapling.crt 2>/dev/null

Запускаем рекурсию

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

Для проверки формата сертификата воспользуемся verify от openssl:

openssl verify /tmp/stapling.crt 2>&1 | grep "unable to load")

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

openssl x509 -inform der -in /tmp/stapling.crt -out /tmp/stapling.crt
openssl pkcs7 -inform der -print_certs -in /tmp/stapling.crt -out /tmp/stapling.crt

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

Правильный порядок сертификатов в цепочке

В финале должен получиться файл с цепочкой сертификатов следующего содержания:

-----BEGIN CERTIFICATE----- сертификат сайта в формате base64 -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- промежуточный сертификат в формате base64 -----END CERTIFICATE----- [-----BEGIN CERTIFICATE----- возможно, еще один промежуточный сертификат -----END CERTIFICATE-----] -----BEGIN CERTIFICATE----- корневой сертификат в формате base64 -----END CERTIFICATE-----

Браузерам сам корневой сертификат в цепочке не требуется: он у них уже есть. Но он требуется для верификации цепочки самому nginx с включенной настройкой ssl_stapling .

Итог

Для составления цепочки сертификатов из данного требуются следующие действия:

1. Скопировать данный сертификат в начало цепочки (cat).
2. Получить URL «родительского» сертификата (openssl + awk / sed).
3. Загрузить «родительский» сертификат (curl / wget).
4. Переформатировать «родительский» сертификат (openssl).
5. Скопировать «родительский» сертификат в цепочку (cat).
6. Повторить шаги 2-5 или завершить.

Айри — облако для ускорения и защиты сайта, работает на уровне DNS, повышает конверсию сайта и улучшает поисковое ранжирование. Подключение за 2 минуты. Стоимость от 7950 в месяц.

Свежие записи

  • Отчеты по скорости сайта
  • Зачем быстрый сайт интернет-магазину
  • Глубокая аналитика скорости сайта: перезапуск
  • Server Push и preload для всех клиентов
  • Защищенные видео-трансляции через Айри CDN

Рубрики

  • Аналитика
  • Защита сайта
  • Интервью
  • Исследования
  • Мобильный сайт
  • Новости Айри
  • Поисковое продвижение
  • Руководства
  • Технические работы
  • Ускорение сайта
  • Хранение данных
  • Экосистема ускорения

Айри.рф

  • Ускорение сайта
  • Защита сайта
  • Доступность сайта
  • CDN по России
  • Личный кабинет
  • Добавить сайт

Если доступность сайта снизится — мы вернем вам деньги!

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

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