OpenSSL: принципы работы, создание сертификатов, аудит


Оглавление

1. OpenSSL: инструкция по использованию и аудит безопасности

2. Что такое OpenSSL и для чего используется

3. Как работают SSL сертификаты

4. Как генерировать сертификаты в OpenSSL

5. Какую команду использовать, genpkey или genrsa

6. Как пользоваться OpenSSL (команды OpenSSL)

7. Как создать сертификаты SSL (TLS) для сайтов

8. Рецепты и советы по генерации SSL сертификатов

8.1 Создание запроса на подпись (CSR) из существующих сертификатов

8.2 Автоматическая генерация CSR

8.3 Создание сертификатов, действительных для нескольких имён хостов

8.4 Самоподписанный сертификат

8.5 Как получить бесплатный валидный сертификат для сайта

9. Просмотр содержимого ключей и сертификатов

10. Форматы ключей и сертификатов

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

11.1 PEM и DER преобразование

11.2 Конвертация PKCS#12 (PFX)

11.3 Конвертация PKCS#7

12. Где хранятся корневые сертификаты Центров Сертификации (CA) в операционной системе


12.1 Корневые сертификаты Центров Сертификации (CA) в Linux

12.1.1 Общесистемные корневые CA сертификаты

12.1.2 Mozilla Network Security Services (NSS)

12.1.3 Google Chrome / Chromium

12.1.4 Firefox

12.1.5 Thunderbird

12.2 Корневые сертификаты Центров Сертификации (CA) в Windows

12.2.1 Общесистемные корневые CA сертификаты

12.2.2 Google Chrome

12.2.3 Opera

12.2.4 Firefox

13. Как добавить корневой сертификат в доверенные

13.1 Как добавить корневой сертификат в доверенные в Linux

13.1.1 Как добавить корневой сертификат в доверенные в Linux на уровне системы

13.1.2 Как добавить корневой сертификат в доверенные в Linux в веб браузеры


13.2 Как добавить корневой сертификат в доверенные в Windows

13.2.1 Как добавить корневой сертификат в доверенные в Windows на уровне системы

13.2.2 Как добавить корневой сертификат в доверенные в Windows в веб браузеры

14. Цепи сертификатов

15. Верификация (проверка) сертификатов

16. Проверка настройки HTTPS

17. Как создать Корневой Центр Сертификации (Root CA)

18. Шифрование файлов в OpenSSL

18.1 Симметричное шифрование файлов в OpenSSL

18.2 Как зашифровать строки в OpenSSL (симметричное шифрование)

18.3 Асимметричное шифрование файлов в OpenSSL

19. Пининг сертификатов (pinning)

20. Словарь основных терминов OpenSSL

21. Программы для проверки настроек SSL и сбора информации


OpenSSL: инструкция по использованию и аудит безопасности

Знаете ли вы, что один единственный корневой сертификат хакера, установленный в вашу систему, фактически лишает её защиты с помощью шифрования SSL (TLS)? Знаете ли вы, что на самом деле для передачи основных данных браузеры не используют ассиметричное шифрование (с помощью сертификатов), а используют симметричное (парольная фраза)? Задумывались ли вы, можете ли Удостоверяющий Центр, выдавший SSL сертификат, расшифровать при желании передаваемый на сайт трафик? Почему VNC сессия, защищённая самодельным сертификатом, считается надёжной, а подключение к сайту, использующего такой же сертификат, нет? Почему для сайтов не подходят самодельные сертификаты? Знаете ли вы, что в вашей системе уже установлены сотни корневых сертификатов различных Центров Сертификации которым безоговорочно доверяют веб браузеры и другие приложения?


В этой статье мы разберёмся, как работает SSL (TLS) шифрование, как пользоваться утилитами OpenSSL, как создавать свои собственные ключи и Центры Сертификации, как подписывать сертификаты для сайтов, как просмотреть детальную информацию о сертификате и ключе, как конвертировать сертификаты в различные форматы и как проверить различные аспекты безопасности SSL (TLS), как проверить, какие сертификаты установлены в качестве доверенных корневых, как добавить новый доверенный сертификат или удалить сертификат из доверенных..

Что такое OpenSSL и для чего используется

OpenSSL — это криптографический инструментарий, реализующий сетевые протоколы Secure Sockets Layer (SSL v2/v3) и Transport Layer Security (TLS v1) и соответствующие им стандарты криптографии.

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

  • Создание и управление закрытыми ключами, открытыми ключами и параметрами.
  • Криптографические операции с открытым ключом
  • Создание сертификатов X.509, CSR и CRL
  • Расчёт дайджестов сообщений
  • Шифрование и дешифрование с помощью шифров
  • Клиентские и серверные тесты SSL/TLS
  • Обработка подписанной или зашифрованной почты S/MIME
  • Запросы отметок времени, генерация и проверка

Как работают SSL сертификаты

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

  • приватный ключ
  • публичный ключ

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

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

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

Любой может сгенерировать пару ключей, поэтому возникает проблема идентификации — как проверить, что публичный ключ выпущен определённым лицом?

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

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

В результате процедура создания сертификата выглядит так:

  1. Владельцем сайта генерируется пара приватный и публичный ключ.
  2. Публичный ключ вместе с другой информацией для подписи (например, название доменного имени) упаковывается в файл в специальном формате. Он называется — Certificate Signing Request (CSR), то есть «запроса на подпись сертификата».
  3. Данный запрос на подпись (CSR) отправляется в Центр Сертификации (CA), который, используя свой приватный корневой ключ, создаёт подпись для этих данных и всё это упаковывается в другой специальный файл, называемый сертификат.

В результате получается сертификат со следующими свойствами:

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

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

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

Как генерировать сертификаты в OpenSSL

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

  1. Его приватный ключ используется для подписи сертификатов (поэтому он называется корневым, хотя в физическом смысле не отличается от приватного ключа сервера)
  2. Его публичный ключ (сертификат) добавлен на компьютеры всех пользователей в качестве доверенного
  3. Цифровая подпись в сертификате не предназначена для проверки третьей стороной, поскольку сертификат является самоподписанным. Единственное отличие самоподписанного сертификата из Центр Сертификации (CA) от того, который вы можете сгенерировать сами, в том, что он у вас размещён среди доверенных (в операционной системе или в браузере). Вы можете самостоятельно созданный самоподписанный сертификат разместить среди доверенных, и он будет иметь точно такую же силу как и корневой сертификат из Центр Сертификации (CA)

Вернёмся к процедуре подписи, а фактически создания сертификата сервера — создаваемый сертификат должен быть криптографически связан с приватным ключом сервера. Но приватный ключ должен быть известен исключительно его владельцу (серверу). Выходом из данной ситуации является использования уже упомянутого Certificate Signing Request (CSR), то есть «запроса на подпись сертификата». То есть Центру Сертификации передаеъётся публичный ключ и название домена, но приватный ключ остаётся в тайне. Именно в этом смысл существования CSR.

В учебных целях вы можете создать свои корневые ключи и даже свой «Центр Сертификации (CA)». Затем создадим пару приватный и публичный ключ сервера. Используя ключ сервера мы создадим запрос на подпись сертификата (CSR). Приватным ключом CA мы подпишем (создадим) сертификат для сервера.

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

Какую команду использовать, genpkey или genrsa

В пакете OpenSSL есть две команды, которые выполняют очень похожее действие — генерируют пару приватный-публичный ключ RSA:

openssl genpkey -algorithm RSA
openssl genrsa

На самом деле, форматы создаваемых этими программами RSA ключей немного различаются. Команда genpkey заменяет команду genpkey, а также ещё две команды: gendh и gendsa.

То есть использовать надо genpkey с которой нужно указать алгоритм ключа опцией -algorithm.

Как пользоваться OpenSSL (команды OpenSSL)

Команды OpenSSL не столько сложные, сколько запутанные.

Во-первых, их много (48 основных команд, 28 digest команд, 84 cipher команды, а также алгоритмы и методы), некоторые из них выполняют более чем одну функцию, некоторые имеют пересекающиеся функции и не всегда непонятно, какую команду выбрать.

Синтаксис использования команд OpenSSL:

openssl КОМАНДА ОПЦИИ

Ещё один пример как команды OpenSSL могут сбить с толку: у команды x509 есть опция -req, а у команды req есть опция -x509.

Если вы хотите получить справку по командам OpenSSL, то вам нужно знать, что это делается так:

man openssl-КОМАНДА
# ИЛИ
man КОМАНДА

Например:

man openssl-req
man openssl-x509
man openssl-genpkey
man openssl-enc
man openssl-rsa
# ИЛИ
man req
man x509
man genpkey
man enc
man rsa

При этом если по аналогии попытаться использовать в командной строке openssl-req или req, то такие команды будет не найдены (нужно использовать openssl req …).

Команды openssl могут быть громоздкими за счёт того, что через одну из опций команды передаются опции сертификата.

На самом деле, для типичных задач используется всего несколько команд и несколько опций. Поэтому если понимать суть, то всё довольно просто.

Перечень команд OpenSSL, которые мы будем использовать:

  • genpkey (заменяет genrsagendh и gendsa) — генерирует приватные ключи
  • req — утилита для создания запросов на подпись сертификата и для создания самоподписанных сертификатов PKCS#10
  • x509 — утилита для подписи сертификатов и для показа свойств сертификатов
  • rsa — утилита для работы с ключами RSA, например, для конвертации ключей в различные форматы
  • enc — различные действий с симметричными шифрами
  • pkcs12 — создаёт и парсит файлы PKCS#12
  • crl2pkcs7 — программа для конвертирования CRL в PKCS#7
  • pkcs7 — выполняет операции с файлами PKCS#7 в DER или PEM формате
  • verify — программа для проверки цепей сертификатов
  • s_client — команда реализует клиент SSL/TLS, который подключается к удалённому хосту с использованием SSL/TLS. Это очень полезный инструмент диагностики для серверов SSL
  • ca — является минимальным CA-приложением. Она может использоваться для подписи запросов на сертификаты в различных формах и генерировать списки отзыва сертификатов. Она также поддерживает текстовую базу данных выданных сертификатов и их статус
  • rand — эта команда генерирует указанное число случайных байтов, используя криптографически безопасный генератор псевдослучайных чисел (CSPRNG)
  • rsautl — команда может быть использована для подписи, проверки, шифрования и дешифрования данных с использованием алгоритма RSA
  • smime — команда обрабатывает S/MIME почту. Она может шифровать, расшифровывать, подписывать и проверять сообщения S/MIME

Чтобы увидеть полный список команд выполните:

openssl list -commands

Пример вывода:

asn1parse         ca                ciphers           cms               
crl               crl2pkcs7         dgst              dhparam           
dsa               dsaparam          ec                ecparam           
enc               engine            errstr            gendsa            
genpkey           genrsa            help              list              
nseq              ocsp              passwd            pkcs12            
pkcs7             pkcs8             pkey              pkeyparam         
pkeyutl           prime             rand              rehash            
req               rsa               rsautl            s_client          
s_server          s_time            sess_id           smime             
speed             spkac             srp               storeutl          
ts                verify            version           x509

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

Создайте корневой приватный ключ

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

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

openssl genpkey -algorithm RSA -out rootCA.key

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

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

openssl genpkey -algorithm RSA -out rootCA.key -aes-128-cbc -pass pass:hello

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

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

man enc

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

openssl genpkey -algorithm RSA -out rootCA.key -aes-128-cbc -pkeyopt rsa_keygen_bits:4096

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

openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.crt

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

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

Чтобы создать приватный ключ сертификата

openssl genpkey -algorithm RSA -out mydomain.com.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.

openssl req -new -key mydomain.com.key -out mydomain.com.csr

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

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

openssl req -new -sha256 -key mydomain.com.key -subj "/C=US/ST=CA/O=MyOrg, Inc./CN=mydomain.com" -out mydomain.com.csr

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

openssl req -new -sha256 -key mydomain.com.key -subj "/C=US/ST=CA/O=MyOrg, Inc./CN=mydomain.com" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:mydomain.com,DNS:www.mydomain.com")) -out mydomain.com.csr

Проверьте содержание CSR

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

openssl req -in mydomain.com.csr -noout -text

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

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

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

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

openssl x509 -req -in mydomain.com.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out mydomain.com.crt -days 500 -sha256

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

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

Рецепты и советы по генерации SSL сертификатов

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

Создание запроса на подпись (CSR) из существующих сертификатов

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

openssl x509 -x509toreq -in mydomain.com.crt -out mydomain.com.csr -signkey mydomain.com.key

Примечание: если вы не используете какую-либо форму закрепления открытого ключа (key pinning — об этом позже) и у вас нет необходимости продолжать использовать существующий приватный ключ, рекомендуется генерировать новый приватный ключ каждый раз, когда вы подаёте заявку на новый сертификат. Генерация ключей является быстрой и недорогой, но снижает ваши риски.

Автоматическая генерация CSR

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

Например, допустим, мы хотим автоматизировать создание CSR для hackware.ru Начнём с создания файла hackware.cnf со следующим содержимым:

[req]
prompt = no
distinguished_name = dn
req_extensions = ext
input_password = ЗДЕСЬ_ПАРОЛЬ

[dn]
CN = hackware.ru
emailAddress = webmaster@hackware.ru
O = Any Corp Ltd
L = London
C = GB

[ext]
subjectAltName = DNS:www.hackware.ru,DNS:hackware.ru

Теперь вы можете создать CSR прямо из командной строки без интерактивного режима:

openssl req -new -config hackware.cnf -key hackware.key -out hackware.csr

Создание сертификатов, действительных для нескольких имён хостов

По умолчанию сертификаты, созданные OpenSSL, имеют только одно Common Name и действительны только для одного имени хоста. Из-за этого, даже если у вас есть связанные веб-сайты (домены), вы вынуждены использовать отдельный сертификат для каждого сайта. В этой ситуации использование одного многодоменного сертификата имеет гораздо больше смысла. Кроме того, даже если вы используете один веб-сайт, вы должны убедиться, что сертификат действителен для всех возможных путей, по которым конечные пользователи могут его использовать. На практике это означает использование как минимум двух имён, одно с префиксом www, а другое без (например, www.hackware.ru и hackware.ru).

Существует два механизма поддержки нескольких имён хостов в сертификате. Первый — перечислить все желаемые имена хостов, используя расширение X.509, которое называется Subject Alternative Name (SAN). Второе — использовать подстановочные знаки. Вы также можете использовать комбинацию двух подходов, обычно это более удобно. На практике для большинства сайтов вы можете указать доменное имя и подстановочный знак для всех поддоменов (например, hackware.ru и *.hackware.ru).

Предупреждение: когда сертификат содержит Alternative Name, все Common Name игнорируются. Более новые сертификаты, произведённые центрами сертификации, могут даже не содержать Common Name. По этой причине включите все желаемые имена хостов в список альтернативных имён (Alternative Name).

Сначала поместите информацию о расширении в отдельный текстовый файл. Я собираюсь назвать это hackware.ext. В файле укажите имя расширения (subjectAltName) и перечислите нужные имена хостов, как в следующем примере:

subjectAltName = DNS:*.hackware.ru, DNS:hackware.ru

Затем, при использовании команды x509 для выдачи сертификата, обратитесь к файлу с помощью ключа -extfile:

openssl x509 -req -days 365 -in hackware.csr -signkey hackware.key -out hackware.crt -extfile hackware.ext

В остальном процесс ничем не отличается от предыдущего. Но когда впоследствии вы изучите сгенерированный сертификат, вы обнаружите, что он содержит расширение SAN (Subject Alternative Name):

 X509v3 extensions:
            X509v3 Subject Alternative Name:
                DNS:*.hackware.ru, DNS:hackware.ru

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

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

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

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

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

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

Если вы не хотите, чтобы вам задавали какие-либо вопросы, используйте ключ -subj, чтобы предоставить информацию о субъекте сертификата в командной строке:

openssl req -new -x509 -days 365 -key hackware.local.key -out hackware.local.crt -subj "/C=GB/L=London/O=Any Corp Ltd/CN=hackware.local"

Как получить бесплатный валидный сертификат для сайта

Смотрите «Бесплатное получение и настройка автоматического продления действительных сертификатов SSL».

Просмотр содержимого ключей и сертификатов

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

Наши тестовые файлы:

  • rootCA.key
  • rootCA.crt
  • mydomain.com.key
  • mydomain.com.csr
  • mydomain.com.crt

Обратите внимание на расширения файлов — они могут отличаться от тех, которые используются в других инструкциях. Например, вместо .key и .crt может использоваться расширение .pem. Расширение файла не имеет особого значения кроме как служить подсказкой пользователю, что именно находится в этом файле. Это же самое касается и имён файлов — вы можете выбирать любые имена.

Все эти файлы являются текстовыми:

cat rootCA.key

Там мы увидим примерно следующее:

-----BEGIN PRIVATE KEY-----
MIIJRAIBADANBgkqhkiG9w0BAQEFAASCCS4wggkqAgEAAoICAQDJBKkr6XzzAcXD
eyDQdvB0SWE2Fl3nqlX/c2RgqMgScXtgidEzOu9ms3Krju5UKLokkQJrZFPMtiIL
MuPJFdYjVyfkfnqlZiouBVgJ60s8NQBBI8KnyyAoJCIFdASoW4Kv5C5LT8pX9eRa
/huJaRJL5XsFUGnTOLvW2ZLN52iAux9CoZlmH6ZF4nuQpblwN0MHULAhze52VNFT
…………………………………………………..
…………………………………………………..
…………………………………………………..
…………………………………………………..
…………………………………………………..
…………………………………………………..
-----END PRIVATE KEY-----

Если вам эти строки кажутся знакомыми на кодировку Base64, то вы совершенно правы — это она и есть. (Смотрите также «Как быстро узнать и преобразовать кодировку»).

Этот формат, называемый форматом PEM, расшифровывается как Privacy Enhanced Mail.

PEM — это текстовое представление реального двоичного ключа или сертификата в формате DER. Представляет собой двоичного формата DER в кодировке base64 и с дополнительными строками «-----BEGIN PRIVATE KEY-----», «-----BEGIN CERTIFICATE-----» и другими в начале файла и строками «-----END PRIVATE KEY-----», «-----END CERTIFICATE-----» в конце файла.

Мы можем хранить двоичную версию файла только с кодировкой DER, но наиболее распространенным способом является версия PEM.

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

openssl rsa -text -in rootCA.key

Опция -in ИМЯ_ФАЙЛА указывает имя файла ввода для чтения ключа или стандартный ввод, если эта опция не указана. Если ключ зашифрован, будет запрошен пароль.

Опция -text печатает различные компоненты открытого или закрытого ключа в виде простого текста в дополнение к закодированной версии.

Пример вывода:

RSA Private-Key: (4096 bit, 2 primes)
modulus:
    00:c9:04:a9:2b:e9:7c:f3:01:c5:c3:7b:20:d0:76:
    [...]
publicExponent: 65537 (0x10001)
privateExponent:
    1f:86:71:99:87:66:a7:1d:b2:0c:34:35:33:3c:53:
    [...]
prime1:
    00:f0:af:82:a6:f1:40:85:ee:c0:77:cc:41:ce:11:
    [...]
prime2:
    00:d5:cf:03:c6:2a:01:79:9a:e3:1d:ec:1b:52:40:
    [...]
exponent1:
    00:d7:7e:ed:65:f7:9f:a3:cb:2e:bc:94:3f:5e:f8:
    [...]
exponent2:
    00:ae:a1:5e:db:c4:03:60:67:79:89:3f:07:31:ae:
    [...]
coefficient:
    00:e4:7d:de:4e:00:a0:8d:c4:5a:14:93:b6:7f:c9:
    [...]
writing RSA key
-----BEGIN RSA PRIVATE KEY-----
[...]
-----END RSA PRIVATE KEY-----

Любой формат ключа на самом деле является контейнером для набора длинных чисел. Все остальные данные можно считать «шумом».

Закрытый ключ содержит: модуль (modulus), частный показатель (privateExponent), открытый показатель (publicExponent), простое число 1 (prime1), простое число 2 (prime2), показатель степени 1 (exponent1), показатель степени 2 (exponent2) и коэффициент (coefficient).

Открытый ключ содержит только модуль (modulus) и открытый показатель (publicExponent).

Вы можете извлечь из файла ключей публичный ключ:

openssl rsa -in rootCA.key -pubout -out rootCA-public.key

По умолчанию выводится закрытый ключ: с опцией -pubout вместо него будет выведен открытый ключ. Эта опция устанавливается автоматически, если ввод является открытым ключом.

Следующая команда покажет информацию о публичном ключе:

openssl rsa -text -in rootCA-public.key -pubin

По умолчанию из входного файла считывается закрытый ключ. Используемая в предыдущей команде опция -pubin делает так, что вместо приватного ключа читается открытый ключ.

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

openssl rsa -text -in rootCA-public.key -pubin -noout

С такими же опциями, но уже используя команду req, можно изучить содержимое запроса на подпись сертификата:

openssl req -in mydomain.com.csr -noout -text

При создании SSL сертификата мы создали две пары ключей (корневые и для домена), то есть это файлы rootCA.key и mydomain.com.key, но по своей технической сути они идентичны.

Что касается сертификатов, которых у нас тоже два (rootCA.crt и mydomain.com.crt), то по своей природе они не являются одинаковыми: корневой сертификат является самоподписанным, а сертификат домена подписан приватным корневым ключом.

Информацию о содержимом сертификатов можно посмотреть командой x509 (остальные опции нам уже знакомы):

openssl x509 -in rootCA.crt -noout -text
openssl x509 -in mydomain.com.crt -text -noout

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

Сертификат (цепочку сертификатов) любого сайта вы можете получить следующей командой (замените w-e-b.site на интересующий вас сайт):

openssl s_client -showcerts -connect w-e-b.site:443 </dev/null

Вы увидите сертификаты (один или несколько), найдите по полю CN тот, который вас интересует, например, сертификат домена w-e-b.site:

0 s:CN = w-e-b.site

И скопируйте содержимое начиная с -----BEGIN CERTIFICATE----- и заканчивая -----END CERTIFICATE-----. Затем сохраните это в файл.

Вы также можете сохранить сертификат центра сертификации и изучить его:

К примеру, сертификат сайта w-e-b.site я сохранил в файл w-e-b.site.crt, для просмотра информации о нём:

openssl x509 -in w-e-b.site.crt -text -noout

Пример вывода:

Issuer указывает на организацию, которая выдала (подписала) сертификат:

        Issuer: C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3

Validity — срок действия сертификата:

        Validity
            Not Before: May 12 03:42:46 2020 GMT
            Not After : Aug 10 03:42:46 2020 GMT

Subject: CN — домен (IP адрес) для которого предназначен сертификат:

        Subject: CN = w-e-b.site

Поддомены в группе X509v3 extensions → X509v3 Subject Alternative Name (подробности чуть позже):

            X509v3 Subject Alternative Name: 
                DNS:w-e-b.site, DNS:www.w-e-b.site

Теперь бегло рассмотрим расширения X.509.

Расширение Basic Constraints используется для маркировки сертификатов как принадлежащих ЦС, давая им возможность подписывать другие сертификаты. В сертификатах, отличных от CA, это расширение будет либо пропущено, либо будет установлено значение CA, равное FALSE. Это расширение является критическим, что означает, что все программные сертификаты должны понимать его значение.

            X509v3 Basic Constraints: critical
                CA:FALSE

Расширения Key Usage (KU) и Extended Key Usage (EKU) ограничивают возможности использования сертификата. Если эти расширения присутствуют, то разрешены только перечисленные варианты использования. Если расширения отсутствуют, ограничений на использование нет. То, что вы видите в этом примере, типично для сертификата веб-сервера, который, например, не позволяет подписывать код:

            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage: 
                TLS Web Server Authentication, TLS Web Client Authentication

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

X509v3 CRL Distribution Points:
    Full Name:
      URI:http://crl.starfieldtech.com/sfs3-20.crl

Примечание: возможно, вы заметили, что местоположение CRL не использует защищённый сервер, и вам может быть интересно, является ли ссылка небезопасной. Не является. Поскольку каждый CRL подписан центром сертификации, который его выпустил, браузеры могут проверить его целостность. В том же случае, если бы CRL были доступны по TLS (адрес включал бы в себя протокол HTTPS), то браузеры могут столкнуться с проблемой «курицы и яйца», в которой они хотят проверить статус отзыва сертификата, используемого сервером, доставляющим сам CRL!

Расширение Certificate Policies используется для указания политики, в соответствии с которой был выпущен сертификат. Например, именно здесь можно найти индикаторы расширенной проверки (EV). Индикаторы представлены в форме уникальных идентификаторов объектов (OID) и являются уникальными для выдающего ЦС. Кроме того, это расширение часто содержит один или несколько пунктов CPS, которые обычно являются веб-страницами или документами PDF.

            X509v3 Certificate Policies: 
                Policy: 2.23.140.1.2.1
                Policy: 1.3.6.1.4.1.44947.1.1.1
                  CPS: http://cps.letsencrypt.org

Расширение Authority Information Access (AIA) обычно содержит две важные части информации. Во-первых, он перечисляет адрес ответчика CA OCSP, который можно использовать для проверки отзыва сертификатов в режиме реального времени. Расширение также может содержать ссылку, где находится сертификат эмитента (следующий сертификат в цепочке). В наши дни серверные сертификаты редко подписываются непосредственно доверенными корневыми сертификатами, а это означает, что пользователи должны включать в свою конфигурацию один или несколько промежуточных сертификатов. Ошибки легко сделать, и сертификаты будут признаны недействительными. Некоторые клиенты (например, Internet Explorer) будут использовать информацию, представленную в этом расширении для исправления неполной цепочки сертификатов, но многие клиенты этого не сделают.

            Authority Information Access: 
                OCSP - URI:http://ocsp.int-x3.letsencrypt.org
                CA Issuers - URI:http://cert.int-x3.letsencrypt.org

Расширения Subject Key Identifier и Authority Key Identifier устанавливают уникальные идентификаторы ключа субъекта и ключа авторизации соответственно. Значение, указанное в расширении Authority Key Identifier сертификата, должно соответствовать значению, указанному в расширении Subject Key Identifier в выдающем сертификате. Эта информация очень полезна в процессе построения пути сертификации, когда клиент пытается найти все возможные пути от конечного (серверного) сертификата до доверенного корня. Центры сертификации часто используют один закрытый ключ с несколькими сертификатами, и это поле позволяет программному обеспечению надёжно определять, какой сертификат может быть сопоставлен с каким ключом. В реальном мире многие цепочки сертификатов, предоставляемые серверами, недействительны, но этот факт часто остаётся незамеченным, поскольку браузеры могут находить альтернативные пути доверия.

            X509v3 Subject Key Identifier: 
                12:AF:9A:BC:DA:63:7D:5A:35:14:E6:8F:1D:B1:70:ED:83:E0:81:AC
            X509v3 Authority Key Identifier: 
                keyid:A8:4A:6A:63:04:7D:DD:BA:E6:D1:39:B7:A6:45:65:EF:F3:A8:EC:A1

Наконец, расширение Subject Alternative Name используется для перечисления всех имен хостов, для которых действителен сертификат. Это расширение раньше было необязательным; если его нет, клиенты возвращаются к использованию информации, представленной в Common Name (CN), которое является частью поля «Subject». Если расширение присутствует, то содержимое поля CN игнорируется во время проверки.

            X509v3 Subject Alternative Name: 
                DNS:w-e-b.site, DNS:www.w-e-b.site

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

Чтобы показать издателя сертификата используйте опцию -issuer:

openssl x509 -in w-e-b.site.crt -noout -issuer

Пример вывода:

issuer=C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3

Опция -fingerprint вычисляет и выводит дайджест DER-кодированной версии всего сертификата. Это обычно называют «отпечатком». Из-за характера дайджестов сообщений, отпечаток сертификата является уникальным для этого сертификата, и два сертификата с одинаковым отпечатком могут считаться одинаковыми. Для сертификатов обычно не нужно сверять сертификаты по отпечаткам, но это имеет смысл при использовании самоподписанных сертификатов (например, получении сертификата для VNC сессии, когда нет другого способа проверить, что сертификат не был подменён при пересылке). В этом случае можно сверить отпечаток сертификата, например, по телефону или электронной почте.

Для показа отпечатка сертификата:

openssl x509 -in w-e-b.site.crt -noout -fingerprint

Пример вывода:

SHA1 Fingerprint=43:4E:55:5B:27:09:33:00:3F:43:B0:B7:B2:5E:96:D5:10:42:3B:44

Чтобы вывести сертификат в виде строки символов в стиле C — char, используйте опцию -C:

openssl x509 -in w-e-b.site.crt -noout -C

Чтобы вывести расширения сертификата в текстовой форме, используйте опцию -ext. Несколько расширений можно перечислить через запятую, например "subjectAltName,subjectKeyIdentifier". Чтобы посмотреть весь список расширений:

man x509v3_config

Пример команды для вывода альтернативных имён в домене:

openssl x509 -in suip.biz.cert -noout -ext subjectAltName

Пример информации об альтернативных именах домена:

            X509v3 Subject Alternative Name: 
                DNS:suip.biz, DNS:www.suip.biz

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

openssl x509 -in w-e-b.site.crt -noout -email

Для вывода адресов респондентов OCSP, если они присутствуют в сертификате, укажите опцию -ocsp_uri:

openssl x509 -in w-e-b.site.crt -noout -ocsp_uri

Пример вывода:

http://ocsp.int-x3.letsencrypt.org

Для показа дат из сертификата имеются следующие опции:

  • -startdate: Распечатывает дату начала сертификата, то есть дату notBefore (не ранее).
  • -enddate: Распечатывает дату истечения срока действия сертификата, то есть дату notAfter (не позднее).
  • -dates: Распечатывает даты начала и окончания срока действия сертификата.

Для вывода имени subject укажите опцию -subject:

openssl x509 -in w-e-b.site.crt -noout -subject

Пример вывода:

subject=CN = w-e-b.site

Чтобы показать имя subject сертификата в форме RFC2253 используйте сочетание опций -subject -nameopt RFC2253:

openssl x509 -in w-e-b.site.crt -noout -subject -nameopt RFC2253

Пример вывода:

subject=CN=w-e-b.site

Пример вывода имени subject сертификата в форме схемы на терминале, поддерживающем UTF8:

openssl x509 -in w-e-b.site.crt -noout -subject -nameopt oneline,-esc_msb

Опция -serial выводит серийный номер:

openssl x509 -in w-e-b.site.crt -noout -serial

Пример вывода:

serial=03AD15E134F5A4D76FEF369D86A4C1ED5B27

Чтобы извлечь публичный ключ из сертификата используйте опцию -pubkey:

openssl x509 -in w-e-b.site.crt -noout -pubkey

Форматы ключей и сертификатов

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

Бинарный (DER) сертификат

Содержит сертификат X.509 в необработанном виде с использованием кодировки DER ASN.1.

ASCII (PEM) сертификат(ы)

Содержит сертификат DER в кодировке base64, в котором -----BEGIN CERTIFICATE----- используется в качестве заголовка, а -----END CERTIFICATE----- в качестве нижнего колонтитула. Обычно встречается только с одним сертификатом на файл, хотя некоторые программы допускают более одного сертификата в зависимости от контекста. Например, более старые версии веб-сервера Apache требуют, чтобы сертификат сервера был один в одном файле, а все промежуточные сертификаты — в другом.

Двоичный (DER) ключ

Содержит закрытый ключ в необработанном виде с использованием кодировки DER ASN.1. OpenSSL создаёт ключи в своём собственном традиционном (SSLeay) формате. Существует также альтернативный формат, называемый PKCS#8 (определённый в RFC 5208), но он не используется широко. OpenSSL может конвертировать в и из формата PKCS#8 с помощью команды pkcs8.

ASCII (PEM) ключ

Содержит ключ DER в кодировке base64, иногда с дополнительными метаданными (например, алгоритм, используемый для защиты паролем).

Сертификат PKCS#7

Сложный формат, предназначенный для транспортировки подписанных или зашифрованных данных, определённый в RFC 2315. Он обычно встречается с расширениями .p7b и .p7c и может при необходимости включать всю цепочку сертификатов. Этот формат поддерживается утилитой keytool Java.

PKCS#12 (PFX) ключ и сертификат(ы)

Сложный формат, который может хранить и защищать ключ сервера вместе со всей цепочкой сертификатов. Обычно встречается с расширениями .p12 и .pfx. Этот формат обычно используется в продуктах Microsoft, но также используется для клиентских сертификатов. В наши дни имя PFX используется как синоним для PKCS#12, хотя в прежние времена под PFX имелся ввиду другой формат (ранняя версия PKCS#12). Вряд ли вы встретите старую версию где-либо.

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

PEM и DER преобразование

Преобразование сертификата между форматами PEM и DER выполняется с помощью инструмента x509. Чтобы преобразовать сертификат из формата PEM в DER:

openssl x509 -inform PEM -in fd.pem -outform DER -out fd.der

Чтобы преобразовать сертификат из DER в формат PEM:

openssl x509 -inform DER -in fd.der -outform PEM -out fd.pem

Синтаксис идентичен, если вам нужно преобразовать закрытые ключи между форматами DER и PEM, но используются разные команды: rsa для ключей RSA и dsa для ключей DSA.

Конвертация PKCS#12 (PFX)

Одна команда — это все, что нужно для преобразования ключа и сертификатов в формате PEM в PKCS#12. В следующем примере ключ (fd.key), сертификат (fd.crt) и промежуточные сертификаты (fd-chain.crt) преобразуются в эквивалентный один файл PKCS#12:

openssl pkcs12 -export -name "My Certificate" -out fd.p12 -inkey fd.key -in fd.crt -certfile fd-chain.crt

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

openssl pkcs12 -in fd.p12 -out fd.pem -nodes

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

Bag Attributes
    localKeyID: E3 11 E4 F1 2C ED 11 66 41 1B B8 83 35 D2 DD 07 FC DE 28 76
subject=/1.3.6.1.4.1.311.60.2.1.3=GB/2.5.4.15=Private Organization/serialNumber=06694169/C=GB/ST=London/L=London/O=Feisty Duck Ltd/CN=www.feistyduck.com
issuer=/C=US/ST=Arizona/L=Scottsdale/O=Starfield Technologies, Inc./OU=http://certificates.starfieldtech.com/repository/CN=Starfield Secure Certification Authority
-----BEGIN CERTIFICATE-----
MIIF5zCCBM+gAwIBAgIHBG9JXlv9vTANBgkqhkiG9w0BAQUFADCB3DELMAkGA1UE
BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAj
[...]

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

Предупреждение: конечный результат преобразования не должен содержать ничего, кроме закодированного ключа и сертификатов. Хотя некоторые инструменты достаточно умны, чтобы игнорировать то, что не нужно, другие инструменты — нет. Оставление дополнительных данных в файлах PEM может привести к проблемам, которые трудно устранить.

Можно заставить OpenSSL разделить компоненты для вас, но для этого требуется несколько вызовов команды pkcs12 (включая каждый раз ввод пароля пакета):

openssl pkcs12 -in fd.p12 -nocerts -out fd.key -nodes
openssl pkcs12 -in fd.p12 -nokeys -clcerts -out fd.crt
openssl pkcs12 -in fd.p12 -nokeys -cacerts -out fd-chain.crt

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

Конвертация PKCS#7

Чтобы преобразовать PEM в PKCS#7, используйте команду crl2pkcs7:

openssl crl2pkcs7 -nocrl -out fd.p7b -certfile fd.crt -certfile fd-chain.crt

Чтобы преобразовать из PKCS#7 в PEM, используйте команду pkcs7 с ключом -print_certs:

openssl pkcs7 -in fd.p7b -print_certs -out fd.pem

Подобно преобразованию из PKCS#12, теперь вы должны отредактировать файл fd.pem, чтобы очистить его и разделить на нужные компоненты.

Где хранятся корневые сертификаты Центров Сертификации (CA) в операционной системе

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

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

Также нужно различать корневые сертификаты CA и сертификаты сайтов, которые вы добавили в доверенные — они также хранятся веб браузерами.

Корневые сертификаты Центров Сертификации (CA) в Linux

Общесистемные корневые CA сертификаты

Консолидированный файл, включающий в себя все корневые сертификаты CA операционной системы, находится в файле /etc/ssl/certs/ca-certificates.crt. Этот файл может быть символической ссылкой на фактическое расположение сертификатов в файлах /etc/ssl/cert.pem или /etc/ca-certificates/extracted/tls-ca-bundle.pem.

Корневые CA сертификаты в виде отдельных файлов расположены в директории /etc/ssl/certs, в этой директории могут быть ссылки на фактическое расположение сертификатов, например, в /etc/ca-certificates/extracted/cadir/.

Для просмотра Subject всех корневых CA сертификатов в системе:

awk -v cmd='openssl x509 -noout -subject' ' /BEGIN/{close(cmd)};{print | cmd}' < /etc/ssl/certs/ca-certificates.crt

Эти сертификаты используются утилитоми curl, wget и другими. Веб-браузеры Chromium и Firefox используют свои собственные хранилища корневых CA сертификатов.

Чтобы узнать, где веб браузеры хранять корневые CA сертификаты в Linux, нам нужно познакомиться с NSS.

Mozilla Network Security Services (NSS)

Network Security Services (NSS) это набор библиотек, разработанных для поддержки кросс-платформенной разработки защищенных клиентских и серверных приложений. Приложения построенные с использование NSS могут использовать SSL v2 и v3, TLS, PKCS#5, PKCS#7, PKCS#11, PKCS#12, S/MIME, сертификаты X.509 v3 и другие стандарты обеспечения безопасности.

В отличие от OpenSSL, NSS использует файлы базы данных в качестве хранилища сертификатов.

NSS начинается с жёстко закодированного списка доверенных сертификатов CA внутри файла libnssckbi.so. Этот список можно просмотреть из любого приложения, использующего NSS, способного отображать (и манипулировать) хранилищем доверенных сертификатов, например, Chrome-совместимые или Firefox-совместимые браузеры.

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

В вашем дистрибутиве скорее всего уже установлен пакет NSS, в некоторых дистрибутивах он называется libnss3 (Debian и производные) в некоторых — nss (Arch Linux, Gentoo и производные).

Если вы хотите просматривать и изменять хранилища сертификатов NSS, то понадобиться утилита certutil. В Arch Linux эта утилита входит в пакет nss и, следовательно, предустановлена в Arch Linux. А в Debian и производные установка делается так:

sudo apt install libnss3-tools

Google Chrome / Chromium

Как уже было сказано, при работе на Linux, Google Chrome использует библиотеку Mozilla Network Security Services (NSS) для выполнения верификации сертификатов.

Корневые CA сертификаты, которые добавил пользователь, хранятся в файле ~/.pki/nssdb/cert9.db, их можно просмотреть командой:

certutil -L -d ~/.pki/nssdb

Поскольку Chrome не может удалить сертификаты из хранилища NSS, то если вы отключите некоторые из них в настройках веб браузера (Privacy and security → Manage certificates → Authorities), то в том же файле, где хранятся добавленные пользователем корневые CA сертификаты, будут сохранены изменения о полномочиях отключённого сертификата:

Используемые в Google Chrome / Chromium корневые CA сертификаты в Linux можно посмотреть следующим причудливым способом:

1. Найдите расположение файла libnssckbi.so (как было сказано в предыдущем разделе, в нём NSS хранит доверенные корневые сертификаты):

locate libnssckbi.so

Примеры расположений этого файла:

  • /usr/lib/libnssckbi.so
  • /usr/lib/x86_64-linux-gnu/nss/libnssckbi.so

2. Теперь выполните команду вида:

ln -s /ПУТЬ/ДО/libnssckbi.so ~/.pki/nssdb

Например:

ln -s /usr/lib/x86_64-linux-gnu/nss/libnssckbi.so ~/.pki/nssdb

2. Затем запустите команду:

certutil -L -d sql:$HOME/.pki/nssdb/ -h 'Builtin Object Token'

Вы увидите доверенные корневые сертификаты, которые использует Google Chrome в Linux.

Также вы можете просмотреть корневые CA сертификаты в настройках браузера:

Конфиденциальность и безопасность (выбрать «Ещё») → Настроить сертификаты → Центры сертификации, на английском это Privacy and security → Manage certificates → Authorities.

Firefox

Поскольку Firefox принадлежит Mozilla, то этот веб браузер, конечно, также использует Mozilla Network Security Services (NSS).

Стандартными расположениями папок с базами данных NSS являются:

  • ~/.pki/nssdb (на уровне пользователей)
  • /etc/pki/nssdb (на общесистемном уровне, может отсутствовать)

Firefox НЕ использует ни одно из этих стандартных расположений, база данных хранится в профиле пользователя, который имеет общий вид ~/.mozilla/firefox/СЛУЧАЙНЫЕ-БУКВЫ-ЦИФРЫ.default/cert9.db, например, ~/.mozilla/firefox/3k0r4loh.default/cert9.db.

Посмотреть корневые сертификаты CA которые использует Firefox в Linux можно следующей командой:

certutil -L -d ~/.mozilla/firefox/*.default/

У Firefox-esr это папка:

certutil -L -d ~/.mozilla/firefox/*.default-esr/

Также вы можете просмотреть корневые CA сертификаты в настройках браузера:

Приватность и Защита → Сертификаты → Просмотр сертификатов → Центры сертификации:

Thunderbird

Чтобы просмотреть, каким CA доверяет Thunderbird:

certutil -L -d ~/.thunderbird/*.default/

Чтобы найти все файлы cert9.db выполните команду:

find ~/ -name "cert9.db"

Корневые сертификаты Центров Сертификации (CA) в Windows

Общесистемные корневые CA сертификаты

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

В Windows просмотр и управление доверенными корневыми сертификатами осуществляется в программе Менеджер Сертификатов.

Чтобы открыть Менеджер Сертификатов нажмите Win+r, введите в открывшееся поле и нажмите Enter:

certmgr.msc

Перейдите в раздел «Доверенные корневые центры сертификации» → «Сертификаты»:

Здесь для каждого сертификата вы можете просматривать свойства, экспортировать и удалять.

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

Чтобы просмотреть список сертификатов с помощью PowerShell:

Get-ChildItem cert:\LocalMachine\root | format-list

Чтобы найти определённый сертификат выполните команду вида (замените «HackWare» на часть искомого имени в поле Subject):

Get-ChildItem cert:\LocalMachine\root | Where {$_.Subject -Match "HackWare"} | format-list

Теперь рассмотрим, где физически храняться корневые CA сертификаты в Windows. Сертификаты хранятся в реестре Windows в следующих ветках:

Сертификаты уровня пользователей:

  • HKEY_CURRENT_USER\Software\Microsoft\SystemCertificates — содержит настройки сертификатов для текущего пользователя
  • HKEY_CURRENT_USER\Software\Policies\Microsoft\SystemCertificates — как и предыдущее расположение, но это соответствует сертификатам пользователей, развёрнутым объектом групповой политики (GPO (Group Policy))
  • HKEY_USERS\SID-User\Software\Microsoft\SystemCertificates — соответствует настройке определённых пользовательских сертификатов. У каждого пользователя есть своя ветка в реестре с SID (идентификатор безопасности).

Сертификаты уровня компьютера:

  • HKEY_LOCAL_MACHINE\Software\Microsoft\SystemCertificates — содержит настройки для всех пользователей компьютера
  • HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\SystemCertificates — как и предыдущее расположение, но это соответствует сертификатам компьютера, развёрнутым объектом групповой политики (GPO (Group Policy))

Сертификаты уровня служб:

  • HKEY_LOCAL_MACHINE\Software\Microsoft\Cryptography\Services\ServiceName\SystemCertificates — содержит настройки сертификатов для всех служб компьютера

Сертификаты уровня Active Directory:

  • HKEY_LOCAL_MACHINE\Software\Microsoft\EnterpriseCertificates — сертификаты, выданные на уровне Active Directory.

И есть несколько папок и файлов, соответствующих хранилищу сертификатов Windows. Папки скрыты, а открытый и закрытый ключи расположены в разных папках.

Пользовательские сертификаты (файлы):

  • %APPDATA%\Microsoft\SystemCertificates\My\Certificates
  • %USERPROFILE%\AppData\Roaming\Microsoft\Crypto\RSA\SID
  • %USERPROFILE%\AppData\Roaming\Microsoft\Credentials
  • %USERPROFILE%\AppData\Roaming\Microsoft\Protect\SID

Компьютерные сертификаты (файлы):

  • C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys

Рассмотрим теперь где хранятся корневые CA сертификаты веб-браузеров.

Google Chrome

Использует общесистемные доверенные корневые центры сертификации.

Чтобы перейти к списку сертификатов из веб браузера:

Настройки → Приватность и Защита → Безопасность → Управление сертификатами → Просмотр сертификатов → Центры сертификации → Доверенные корневые центры сертификации:


Opera

Чтобы перейти к списку сертификатов из веб браузера: Настройки → Перейти к настройкам браузера → Дополнительно → Безопасность → Ещё → Настроить сертификаты → Доверенные корневые центры сертификации:

Firefox

Использует NSS.

Приватность и Защита → Сертификаты → Просмотр сертификатов → Центры сертификации:

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

Как добавить корневой сертификат в доверенные в Linux

Как добавить корневой сертификат в доверенные в Linux на уровне системы

Сертификат с расширением .crt можно открыть двойным кликом и просмотреть его содержимое:


Если вы работаете в системе от обычного пользователя (не root), то кнопка «Импортировать» будет недоступна.

Чтобы разблокировать кнопку «Импортировать», выполните следующую команду:

sudo gcr-viewer /ПУТЬ/ДО/СЕРТИФИКАТА.crt

Например:

sudo gcr-viewer ./HackWareCA.crt

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

Суть метода очень проста:

  1. Добавить свой корневой CA сертификат в папку, предназначенную для таких сертификатов.
  2. Запустить программу для обновления общесистемного списка сертификатов.

Пути и команды в разных дистрибутивах Linux чуть различаются.

Просмотреть Subject всех корневых CA сертификатов можно уже знакомой командой:

awk -v cmd='openssl x509 -noout -subject' ' /BEGIN/{close(cmd)};{print | cmd}' < /etc/ssl/certs/ca-certificates.crt

Для демонстрации я добавлю сертификат с Common Name, включающим «HackWare», тогда для проверки, имеется ли сертификат с таким именем среди корневых CA, я могу использовать команду:

awk -v cmd='openssl x509 -noout -subject' ' /BEGIN/{close(cmd)};{print | cmd}' < /etc/ssl/certs/ca-certificates.crt | grep -i HackWare

Для добавления своего корневого CA в доверенные в Debian, Kali Linux, Linux Mint, Ubuntu и их производных:

1. Проверьте, существует ли директория /usr/local/share/ca-certificates:

ls -l /usr/local/share/ca-certificates

Если её ещё нет, то создайте:

sudo mkdir /usr/local/share/ca-certificates

Сертификат должен быть в формате PEM (обычно так и есть) и иметь расширение .crt — если расширение вашего сертификата .pem, то достаточно просто поменять на .crt.

2. Скопируйте ваш сертификат командой вида:

sudo cp СЕРТИФИКАТ.crt /usr/local/share/ca-certificates/

Например:

sudo cp ./HackWareCA.crt /usr/local/share/ca-certificates/

3. Запустите следующую команду для обновления общесистемного списка:

sudo update-ca-certificates

Пример вывода:

Updating certificates in /etc/ssl/certs...
1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...

Adding debian:HackWareCA.pem
done.
done.

Проверим наличие нашего CA сертификата среди доверенных:

awk -v cmd='openssl x509 -noout -subject' ' /BEGIN/{close(cmd)};{print | cmd}' < /etc/ssl/certs/ca-certificates.crt | grep -i HackWare

Сертификат успешно найден:

Чтобы его удалить:

sudo rm /usr/local/share/ca-certificates/СЕРТИФИКАТ.crt
sudo update-ca-certificates

Для добавления своего корневого CA в доверенные в Arch Linux, BlackArch и их производных:

1. Выполните команду вида:

sudo cp ./СЕРТИФИКАТ.crt /etc/ca-certificates/trust-source/anchors/

Например:

sudo cp ./HackWareCA.crt /etc/ca-certificates/trust-source/anchors/

2. Обновите общесистемный список доверенных CA:

sudo update-ca-trust

Чтобы удалить этот сертификат:

sudo rm /etc/ca-certificates/trust-source/anchors/СЕРТИФИКАТ.crt
sudo update-ca-trust

Добавление сертификатов в базу данных NSS

Некоторые приложения используют базу данных NSS, и у вас может быть необходимость добавить доверенные CA в неё.

Последующие изменения повлияют только на приложения, использующие базу данных NSS и учитывающие файл /etc/pki/nssdb.

1. Сначала создайте структуру каталогов для системных файлов базы данных NSS:

sudo mkdir -p /etc/pki/nssdb

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

sudo certutil -d sql:/etc/pki/nssdb -N

2. Убедитесь, что файлы базы данных доступны для чтения всем:

sudo chmod go+r /etc/pki/nssdb/*

Примечание: вышеприведённые инструкции применимы только в том случае, если пока не существует общесистемного набора файлов базы данных NSS. Если он уже существует, то важно знать пароль для этого набора баз данных (конечно, если он защищён паролем).

3. Теперь, когда доступны файлы базы данных NSS, добавьте сертификат в хранилище следующим образом:

sudo certutil -d sql:/etc/pki/nssdb -A -i ФАЙЛ-СЕРТИФИКАТА.crt -n "ИМЯ-СЕРТИФИКАТА" -t "C,,"

Например:

sudo certutil -d sql:/etc/pki/nssdb -A -i ./HackWareCA.crt -n "HackWare CA" -t "C,,"

Биты доверия, используемые в приведённом выше примере, помечают сертификат как надёжный для подписи сертификатов, используемых для связи SSL/TLS. Имя (указывается после опции -n), используемое в команде, можно выбрать любое, но убедитесь, что его легко отличить от других сертификатов в магазине.

Для проверки:

certutil -L -d /etc/pki/nssdb

Аналогичные инструкции можно использовать для включения сертификата только в базу данных NSS конкретного пользователя:

certutil -d sql:$HOME/.pki/nssdb -A -i ФАЙЛ-СЕРТИФИКАТА.crt -n "ИМЯ-СЕРТИФИКАТА" -t "C,,"

Удаление из файлов базы данных NSS

Чтобы удалить сертификат из любой базы данных NSS, используйте команду certutil следующим образом. В этом примере используется общесистемное расположение базы данных NSS, но его можно легко изменить на пользовательское ~/.pki/nssdb местоположение.

sudo certutil -d sql:/etc/pki/nssdb -D -n "certificateName"

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

Chrome, Chromium, Firefox и созданные на их основе веб браузеры доверяют корневым сертификатам, установленным на уровне системы. То есть вам достаточно добавить в доверенные CA сертификат как это показано в предыдущем разделе.

Причём эти браузеры хотя и используют NSS, они игнорируют общесистемные сертификаты NSS, которые можно добавить в файл /etc/pki/nssdb!

Тем не менее приложения, которые используют NSS (такие как Firefox, Thunderbird, Chromium, Chrome) хранят свои списки доверенных сертификатов в файлах cert9.db. Чтобы добавить свой сертификат в каждый из этих файлов можно использовать скрипт.

Сохранить следующий код в файл CAtoCert9.sh:

#!/bin/bash

certfile="root.cert.pem"
certname="My Root CA"

for certDB in $(find ~/ -name "cert9.db")
do
	certdir=$(dirname ${certDB});
	certutil -A -n "${certname}" -t "TCu,Cu,Tu" -i ${certfile} -d sql:${certdir}
done

В этом файле измените значение certfile на имя файла вашего сертификата и значение certname на имя вашего сертификата, сохраните и закройте файл.

Затем запустите его следующим образом:

bash ./CAtoCert9.sh

В результате в домашней папке пользователя будут найдены все файлы cert9.db и в каждый из них будет добавлен указанный CA сертификат.

Вы можете добавить CA сертификаты в графическом интерфейсе каждого браузера.

  • В настройках Chrome: Конфиденциальность и безопасность → Безопасность → Настроить сертификаты → Центры сертификации
  • В настройках Chromium: Конфиденциальность и безопасность (выбрать «Ещё») → Настроить сертификаты → Центры сертификации

Нажмите кнопку «Импорт»:

Выберите файл с сертификатом.

Укажите, какие полномочия вы даёте этому сертификату:

  • В настройках Firefox: Приватность и Защита → Сертификаты → Просмотр сертификатов → Центры сертификации:

Нажмите кнопку «Импортировать»:

Выберите файл с сертификатом.

Укажите, какие полномочия вы даёте этому сертификату:

Как добавить корневой сертификат в доверенные в Windows

Как добавить корневой сертификат в доверенные в Windows на уровне системы

1. Мастер импорта сертификатов

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

В открывшемся окне нажмите кнопку «Установить сертификат»:

Выберите один из вариантов:

  • «Текущий пользователь» - сертификат будет иметь эффект только для одного пользователя
  • «Локальный компьютер» - сертификат будет иметь эффект для всех пользователей данного компьютера

Выберите «Пометить все сертификаты в следующие хранилища»:

Нажмите кнопку «Обзор» и выберите «Доверенные корневые центры сертификации»:

Нажмите «Далее»:

Нажмите «Готово»:

Сообщение об успешном импорте:

Теперь сертификат будет доступен в Менеджере Сертификатов:

2. Добавление root CA сертификата в Менеджере Сертификатов

Чтобы открыть Менеджер Сертификатов нажмите Win+r, введите в открывшееся поле и нажмите Enter:

certmgr.msc

Кликните правой кнопкой мыши по пункту «Доверенные корневые центры сертификации», выберите пункт «Все задачи» → «Импорт»:

Нажмите «Далее»:

Укажите папку и имя файла:

Нажмите «Далее»:

Всё готово:

Подтвердите:

Теперь действительно всё готово:

Только что импортированный сертификат в Менеджере Сертификатов:

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

Chrome, Chromium, Opera и сделанные на их основе веб браузеры используют общесистемные корневые CA сертификаты. То есть для добавления новых доверенных CA достаточно добавить их в систему, как это показано выше.

Firefox использует исключительно своё хранилище. Для добавления корневых сертификатов CA в Firefox нужно сделать так:

  • В настройках Firefox: Приватность и Защита → Сертификаты → Просмотр сертификатов → Центры сертификации:

Нажмите кнопку «Импортировать»:

Выберите файл с сертификатом.

Укажите, какие полномочия вы даёте этому сертификату:

Цепи сертификатов

На практике, корневые Центры Сертификации (CA) сейчас уже практически не подписывают сертификаты для веб сайтов. Корневые CA делегируют свои полномочия для подписания сертификатов сайтов другим организациям — промежуточным CA. Именно к ним мы обращаемся, когда покупаем или получаем на 3 месяца бесплатный сертификат для сайта.

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

Поэтому описанная выше схема на практике является в настоящее время неактуальной:

  1. Получение сертификата от сайта
  2. Валидация сертификата сайта с помощью сертификата корневого CA
  3. Если сертификат сайта действительный, то выполнение других действий в соответствии с HTTPS протоколом

На самом деле всё происходит так:

  1. Получение сертификата от сайта
  2. Валидация сертификата сайта с помощью сертификата промежуточного CA
  3. Валидация сертификата промежуточного CA с помощью сертификата корневого CA
  4. Если сертификат промежуточного CA является действительным, то сертификат сайта также считается действительным. И в этом случае запускается выполнение других действий в соответствии с HTTPS протоколом

Главное практическое следствие из этого — при валидации сертификатов нужно получить и использовать промежуточные сертификаты.

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

Главное правило, когда сертификат и промежуточные сертификаты собраны в один файл: первым идёт сертификат сайта, затем сертификат подписавшего CA. Корневые сертификаты указывать НЕ нужно, поскольку они уже есть у пользователей.

Промежуточных CA может быть несколько, поэтому промежуточных сертификатов также может быть несколько.

Мы уже рассмотрели некоторые расширения X.509, одно из них Authority Information Access (AIA). Частью поля AIA является CA Issuers, в нём содержится информация об издатели сертификата. Она может быть полезной, когда веб сервер не предоставил цепочку доверенных сертификатов.

Пример:

            Authority Information Access: 
                OCSP - URI:http://ocsp.int-x3.letsencrypt.org
                CA Issuers - URI:http://cert.int-x3.letsencrypt.org/

Если перейти по ссылке http://cert.int-x3.letsencrypt.org/, то будет скачен сертификат промежуточного CA, подписавшего сертификат сайта. Этот сертификат в формате DER и он может быть конвертирован в формат PEM как это показано выше в разделе о конвертации форматов ключей и сертификатов.

Верификация (проверка) сертификатов

Для проверки действительности сертификата используется команда

openssl verify СЕРТИФИКАТ

В разделе «Как создать сертификаты SSL (TLS) для сайтов» мы создали сертификат mydomain.com.crt, попробуем проверить его:

openssl verify mydomain.com.crt

Вывод:

C = US, ST = CA, O = "MyOrg, Inc.", CN = mydomain.com
error 20 at 0 depth lookup: unable to get local issuer certificate
error mydomain.com.crt: verification failed

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

С помощью опции -CAfile можно указать сертификат доверенного Центра Сертификации:

openssl verify -CAfile rootCA.crt mydomain.com.crt

Как можно увидеть, проверка подлинности прошла успешно:

mydomain.com.crt: OK

Чтобы было поинтереснее, возьмём реальные сертификаты сайта и промежуточного центра сертификации:

openssl s_client -showcerts -connect w-e-b.site:443 </dev/null

Вы увидите сертификаты (один или несколько), найдите по полю CN сначала сертификат домена w-e-b.site:

0 s:CN = w-e-b.site

И скопируйте содержимое начиная с -----BEGIN CERTIFICATE----- и заканчивая -----END CERTIFICATE-----. Затем сохраните это в файл w-e-b.site.crt.

Затем найдите сертификат центра сертификации и сохраните его в файл x3.crt:

Итак, для наших экспериментов у нас появилось два новых файла: w-e-b.site.crt (сертификат сайта) и x3.crt (сертификат промежуточного Центра Сертификации).

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

openssl verify w-e-b.site.crt

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

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

openssl verify x3.crt

Как можно увидеть на скриншоте, с этим сертификатом всё в порядке.

Дело в том, что команда openssl verify сверяет подпись в сертификате с коревыми Центрами Сертификации, чьи сертификаты установлены в операционной системе как доверенные. Мы можем убедиться в этом. Следующая команда покажет организацию, подписавшую сертификат x3.crt:

openssl x509 -in x3.crt -noout -issuer

Вывод:

issuer=O = Digital Signature Trust Co., CN = DST Root CA X3

Имя издателя в поле CN (Common Name) DST Root CA X3.

Убедимся, что сертификат этого CA действительно есть в системе:

awk -v cmd='openssl x509 -noout -subject' ' /BEGIN/{close(cmd)};{print | cmd}' < /etc/ssl/certs/ca-certificates.crt | grep 'DST Root CA X3'

Если мы посмотрим, кто выдал сертификат сайта w-e-b.site:

openssl x509 -in w-e-b.site.crt -noout -issuer

То увидим, что это Let's Encrypt Authority X3.

Посмотрим имя организации в сертификате x3.crt:

openssl x509 -in x3.crt -noout -subject

Имя совпало — это также Let's Encrypt Authority X3.

То есть в целом цепочка понятна — сертификат w-e-b.site.crt выдан организацией Let's Encrypt Authority X3, а её полномочия по выдаче сертификатов заверяет DST Root CA X3, которая в операционной системе находится среди доверенных корневых Центрах Сертификации.

Чтобы автоматически выполнить проверку всей цепочки с помощью openssl verify, нам нужно указать промежуточный сертификат после опции -untrusted. Если промежуточных сертификатов несколько, то нужно указать их все — опцию -untrusted можно использовать несколько раз.

openssl verify -untrusted x3.crt w-e-b.site.crt

Опция -show_chain покажет информацию о цепочке сертификатов, которая была построена:

openssl verify -untrusted x3.crt -show_chain w-e-b.site.crt

Опции -verify_hostname ИМЯ-ХОСТА и -verify_ip IP позволяют проверить, действительно ли сертификат выдан для указанного хоста или IP адреса. Чтобы проверка прошла успешно, имя хоста должно быть в Subject Alternative Name или Common Name в subject сертификата. А IP адрес должен быть в Subject Alternative Name в subject сертификата. Пример:

openssl verify -untrusted x3.crt -verify_hostname w-e-b.site w-e-b.site.crt

Следующими тремя командами вы можете проверить, соответствует ли SSL сертификат приватному ключу:

Для SSL сертификата выполните команду вида:

openssl x509 -noout -modulus -in ФАЙЛ.crt | openssl md5

Для приватного ключа RSA выполните команду вида:

openssl rsa -noout -modulus -in ФАЙЛ.key | openssl md5

Для CSR:

openssl req -noout -modulus -in ФАЙЛ.csr | openssl md5

Замените ФАЙЛ на имя ваших файлов. Для всего перечисленного выше — SSL сертификата, приватного ключа и запроса на подпись — хеш должен быть одинаковым.

Проверка настройки HTTPS

Команда s_client выполняет функции SSL/TLS клиента для подключения к удалённому хосту с использованием SSL/TLS. Данная программа позволяет подключаться с различными настройками SSL/TLS — выбирать используемые шифры, версию рукопожатия, использовать определённые протоколы, тестировать повторное использование сессий. При этом программа показывает все переданные и полученные во время SSL/TLS подключения данные. Благодаря этому возможна доскональная проверка настроек сервера SSL/TLS, тестирование списка отзыва сертификатов и даже проверка на уязвимости.

Выполнив SSL/TLS подключение, s_client позволяет вводить данные, например, отправлять заголовки HTTP протокола, команды SMTP, FTP и т.д.

Для подключения к удалённому хосту укажите адрес домена и порт (обычно это 443) с опцией -connect:

openssl s_client -connect yandex.ru:443

Вы увидите:

1. верификацию и цепочку сертификатов

2. сертификат сайта

3. данные текущей сессии — SSL/TLS (ассиметричное шифрование) используются для обмена ключом для симметричного шифрования, поскольку ассиметричное слишком «затратное». И фактический шифрование данных будет выполняться «паролем» (ключами сессии, а не сертификатом). Эти ключи меняются при каждой новой сессии.

То есть, компрометация приватного ключа сервера ≠ расшифровка трафика. Поскольку необходимо знать все ключи сессии. Раньше, зная приватный ключ сервера, можно было расшифровать SSL трафик — сначала расшифровывались ключи сессии, а затем они использовались для расшифровки данных. Но теперь используется Perfect Forward Secrecy (которая применяет Diffie-Hellman key exchange (DH)), что привело к тому, что третья сторона, даже зная приватный ключ RSA (приватный ключ сервера), не сможет расшифровать TLS трафик.

Как видеть все сертификаты, которые отправляет HTTPS сервер

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

openssl s_client -showcerts -connect yandex.ru:443

Для yandex.ru будет выведено 3 сертификата: 1 сертификат сайта и 2 промежуточных.

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

openssl s_client -showcerts -connect yandex.ru:443 </dev/null

Чтобы сохранить сертификат сайта в файл используйте следующую команду (дважды замените w-e-b.site на интересующий вас домен):

echo | openssl s_client -connect w-e-b.site:443 2>&1 | sed --quiet '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > w-e-b.site.crt

Если вы хотите сохранить всю присылаемую цепочку сертификатов, то сделайте так (дважды замените w-e-b.site на интересующий вас домен):

echo | openssl s_client -showcerts -connect w-e-b.site:443 2>&1 | sed --quiet '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > w-e-b.site.ca-bundle

Проверка TLS/SSL веб-сайта с указанием Центра Сертификации

Если веб-сайт использует самостоятельно созданный сертификат, который не подписан Глобальными Центрами Сертификации, то с помощью опции -CAfile можно указать сертификат того CA, который вы использовали для подписи:

openssl s_client -connect w-e-b.site:443 -CAfile /etc/ssl/CA.crt

Это подходит, например, для тестирования сгенерированных сертификатов на локальном сервере без добавления самодельного CA в корневые Центры Сертификации ОС.

Тестирование протоколов, которые обновляются до SSL

При использовании с HTTP TLS оборачивает весь текстовый канал связи в HTTPS. Некоторые другие протоколы начинаются как открытый текст, но затем они переходят на шифрование. Если вы хотите протестировать такой протокол, вам нужно сообщить OpenSSL, какой это протокол, чтобы он мог обновляться от вашего имени. Укажите информацию о протоколе с помощью ключа -starttls. Например:

openssl s_client -connect gmail-smtp-in.l.google.com:25 -starttls smtp

Поддерживаются в частности следующие протоколы: smtp, pop3, imap, ftp и xmpp.

Отладка SSL/TLS к HTTPS

Во время установки соединения SSL/TLS «под капотом» выполняется много работы. Если у нас есть какие-то проблемы или нам нужна подробная информация об инициализации SSL/TLS, мы можем использовать опцию -tlsextdebug, как показано ниже.

openssl s_client -connect w-e-b.site:443 -tlsextdebug

Поддержка протокола тестирования

По умолчанию s_client будет пытаться использовать лучший протокол для связи с удаленным сервером и сообщать согласованную версию в выходных данных.

    Protocol  : TLSv1.3

Если вам нужно протестировать поддержку определённых версий протокола, у вас есть два варианта. Вы можете явно выбрать один протокол для тестирования, указав один из ключей --ssl3, -tls1, -tls1_1, -tls1_2 или -tls1_3. Кроме того, вы можете выбрать протоколы, которые вы не хотите тестировать, используя один или несколько из следующих параметров: -no_ssl3, -no_tls1, -no_tls1_1, -no_tls1_2 или -no_tls1_3.

Примечание: не все версии OpenSSL поддерживают все версии протокола. Например, более старые версии OpenSSL не будут поддерживать TLS 1.2 и TLS 1.3, а более новые версии могут не поддерживать более старые протоколы, такие как SSL 2 и SSL 3. К примеру, при попытке использовать опцию -ssl3 на современных версиях OpenSSL возникает ошибка:

s_client: Option unknown option -ssl3

Интерактивные запросы с s_client

Как вы можете увидеть, подключение с помощью s_client не прекращается до истечении таймаута — программа и сервер ожидают ввод данных.

К примеру, выполним подключение:

openssl s_client -connect w-e-b.site:443

И введём:

HEAD / HTTP/1.1
Host: w-e-b.site
User-Agent: fucking best browser ever

Вместо HTTP метода GET использовался HEAD — в результате показана не страница, а только HTTP заголовки.

Получение HTML кода страницы (пример использования метода GET с запросом адреса страницы):

GET /?act=my-user-agent HTTP/1.1
Host: w-e-b.site
User-Agent: fucking best browser ever

При использовании s_client всегда возникает ошибка «HTTP/1.1 400 Bad Request»

На некоторых серверах при использовании s_client и попытке ввести любые HTTP заголовки возникает ошибка «400 Bad Request».

Как можно понять из текста ошибки — сервер получил плохой запрос. Причины могут быть разными:

  • ошибки в синтаксисе HTTP заголовков
  • некоторые сервера требуют CR+LF вместо символа line feed, отправляемого при нажатии Enter

Например, подключимся к серверу:

openssl s_client -connect w-e-b.site:443

Попробуем ввести первый заголовок и нажмём Enter:

HEAD / HTTP/1.1

Сразу после этого возникнет ошибка — ваш браузер отправил запрос, который этот сервер не может понять:

HTTP/1.1 400 Bad Request
………………..
………………..
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>

В данном случае необходимо использовать опцию -crlf, она переводит line feed от терминала в CR+LF, как этого требуют некоторые серверы:

openssl s_client -connect w-e-b.site:443 -crlf

После этого сервер нормально пример HTTP заголовки.

Для того, чтобы s_client перестал ожидать ввод и отправил данные на сервер, нажмите Enter дважды.

Как создать Корневой Центр Сертификации (Root CA)

Источник: «OpenSSL Cookbook».

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

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

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

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

Проходя этот раздел, вы создадите два файла конфигурации: один для управления корневым центром сертификации (root-ca.conf), а другой — для управления подчиненным центром сертификации (sub-ca.conf). Несмотря на то, что вы сможете делать все с нуля, просто следуя моим инструкциям, вы также можете загрузить шаблоны файлов конфигурации из моей учётной записи GitHub. Последний вариант сэкономит вам некоторое время, но первый подход даст вам лучшее понимание в вовлечённую работа.

Особенности и ограничения

В оставшейся части этого раздела мы собираемся создать частный ЦС, который по своей структуре аналогичен общедоступным ЦС. Будет один корневой ЦС, из которого могут быть созданы другие подчинённые ЦС. Мы предоставим информацию об аннулировании через CRL и респондентов OCSP. Для поддержания корневого ЦС в автономном режиме ответчики OCSP будут иметь свои собственные идентификационные данные. Это не самый простой частный центр сертификации, который вы могли бы иметь, но он может быть надёжно защищён. В качестве бонуса подчинённый ЦС будет технически ограничен, что означает, что ему будет разрешено выдавать сертификаты только для разрешённых имён хостов.

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

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

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

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

Прежде чем мы сможем создать CA, нам нужно подготовить файл конфигурации (root-ca.conf), который сообщит OpenSSL, как именно мы хотим, чтобы все было настроено. Файлы конфигурации не требуются большую часть времени при обычном использовании, но они необходимы, когда речь идёт о сложных операциях, таких как создание корневого ЦС. Конфигурационные файлы OpenSSL являются мощными; прежде чем продолжить, предлагаю вам ознакомиться с их возможностями (man config в командной строке).

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

[default]
name                    = root-ca
domain_suffix           = example.com
aia_url                 = http://$name.$domain_suffix/$name.crt
crl_url                 = http://$name.$domain_suffix/$name.crl
ocsp_url                = http://ocsp.$name.$domain_suffix:9080
default_ca              = ca_default
name_opt                = utf8,esc_ctrl,multiline,lname,align

[ca_dn]
countryName             = "GB"
organizationName        = "Example"
commonName              = "Root CA"

Вторая часть напрямую контролирует работу ЦС. Для получения полной информации о каждом параметре обратитесь к документации по команде ca (man ca в командной строке). Большинство настроек говорят сами за себя; мы в основном сообщаем OpenSSL, где мы хотим хранить наши файлы. Поскольку этот корневой ЦС будет использоваться только для выдачи подчинённых ЦС, я решил, что сертификаты действительны в течение 10 лет. Для алгоритма подписи по умолчанию используется безопасный SHA256.

Политика по умолчанию (policy_c_o_match) настроена таким образом, чтобы все сертификаты, выпущенные из этого CA, имели поля countryName и organizationName, которые совпадают с полями CA. Это не может быть сделано общедоступным ЦС, но подходит для частного ЦС:

[ca_default]
home                    = .
database                = $home/db/index
serial                  = $home/db/serial
crlnumber               = $home/db/crlnumber
certificate             = $home/$name.crt
private_key             = $home/private/$name.key
RANDFILE                = $home/private/random
new_certs_dir           = $home/certs
unique_subject          = no
copy_extensions         = none
default_days            = 3650
default_crl_days        = 365
default_md              = sha256
policy                  = policy_c_o_match

[policy_c_o_match]
countryName             = match
stateOrProvinceName     = optional
organizationName        = match
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

Третья часть содержит конфигурацию команды req, которая будет использоваться только один раз при создании самозаверяющего (самоподписанного) корневого сертификата. Наиболее важные части находятся в расширениях: расширение basicConstraints указывает, что сертификат является CA, а keyUsage содержит соответствующие параметры для этого сценария:

[req]
default_bits            = 4096
encrypt_key             = yes
default_md              = sha256
utf8                    = yes
string_mask             = utf8only
prompt                  = no
distinguished_name      = ca_dn
req_extensions          = ca_ext

[ca_ext]
basicConstraints        = critical,CA:true
keyUsage                = critical,keyCertSign,cRLSign
subjectKeyIdentifier    = hash

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

Все подчинённые ЦС будут ограничены, что означает, что выданные ими сертификаты будут действительны только для подмножества доменных имён и ограниченного использования. Во-первых, расширение extendedKeyUsage указывает только clientAuth и serverAuth, которые являются TLS-аутентификацией клиента и сервера. Во-вторых, расширение nameConstraints ограничивает допустимые имена хостов только доменными именами example.com и example.org. Теоретически, эта настройка позволяет вам передавать контроль над подчинёнными ЦС кому-то ещё, но при этом быть уверенным, что они не могут выдавать сертификаты для произвольных имён хостов. Если вы хотите, вы можете ограничить каждый подчинённый ЦС небольшим пространством имён домена. Требование об исключении двух диапазонов IP-адресов исходит из базовых требований CA/Browser Forum, в которых содержится определение технически ограниченных подчинённых CA.

На практике ограничения имён не совсем практичны, потому что некоторые основные платформы в настоящее время не распознают расширение nameConstraints. Если вы отметите это расширение как критическое, такие платформы будут отклонять ваши сертификаты. У вас не возникнет таких проблем, если вы не отметите их как критические (как в примере), но некоторые другие платформы не будут применять их.

[sub_ca_ext]
authorityInfoAccess     = @issuer_info
authorityKeyIdentifier  = keyid:always
basicConstraints        = critical,CA:true,pathlen:0
crlDistributionPoints   = @crl_info
extendedKeyUsage        = clientAuth,serverAuth
keyUsage                = critical,keyCertSign,cRLSign
nameConstraints         = @name_constraints
subjectKeyIdentifier    = hash

[crl_info]
URI.0                   = $crl_url

[issuer_info]
caIssuers;URI.0         = $aia_url
OCSP;URI.0              = $ocsp_url

[name_constraints]
permitted;DNS.0=example.com
permitted;DNS.1=example.org
excluded;IP.0=0.0.0.0/0.0.0.0
excluded;IP.1=0:0:0:0:0:0:0:0/0:0:0:0:0:0:0:0

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

[ocsp_ext]
authorityKeyIdentifier  = keyid:always
basicConstraints        = critical,CA:false
extendedKeyUsage        = OCSPSigning
keyUsage                = critical,digitalSignature
subjectKeyIdentifier    = hash

Структура корневого ЦС

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

mkdir root-ca
cd root-ca
mkdir certs db private
chmod 700 private
touch db/index
openssl rand -hex 16  > db/serial
echo 1001 > db/crlnumber

Используются следующие подкаталоги:

certs/

Хранение сертификатов; новые сертификаты будут размещены здесь по мере их выпуска.

db/

Этот каталог используется для базы данных сертификатов (index) и файлов, которые содержат следующий сертификат и серийные номера CRL. OpenSSL создаст несколько дополнительных файлов по мере необходимости.

private/

В этом каталоге будут храниться закрытые ключи, один для ЦС, а другой для ответчика OCSP. Важно, чтобы ни один другой пользователь не имел к нему доступа. (На самом деле, если вы собираетесь серьёзно относиться к ЦС, на компьютере, на котором хранится корневой материал, должно быть только минимальное количество учётных записей пользователей.)

Примечание: при создании нового сертификата CA важно инициализировать серийные номера сертификатов с помощью генератора случайных чисел, как я делаю в этом разделе. Это очень полезно, если вам когда-нибудь придётся создавать и развёртывать несколько сертификатов CA с одним и тем же отличительным именем (обычно, если вы допустили ошибку и вам нужно начать заново); конфликтов не будет, потому что сертификаты будут иметь разные серийные номера.

Генераци Root CA

Мы делаем два шага, чтобы создать корневой CA. Сначала мы генерируем ключ и CSR. Вся необходимая информация будет взята из файла конфигурации при использовании ключа -config:

openssl req -new -config root-ca.conf -out root-ca.csr -keyout private/root-ca.key

На втором этапе мы создаем самозаверяющий сертификат. Ключ -extensions указывает на раздел ca_ext в файле конфигурации, который активирует расширения, подходящие для корневого ЦС:

openssl ca -selfsign -config root-ca.conf -in root-ca.csr -out root-ca.crt -extensions ca_ext

Структура файла базы данных

База данных в db/index представляет собой обычный текстовый файл, содержащий информацию о сертификате, по одному сертификату на строку. Сразу после создания корневого ЦС он должен содержать только одну строку:

V    240706115345Z        1001    unknown    /C=GB/O=Example/CN=Root CA

Каждая строка содержит шесть значений, разделённых символами табуляции:

  1. Флаг состояния (V для действительного, R для отозванного, E для истекшего)
  2. Срок годности (в формате ГГММДДЧЧММССЗ)
  3. Дата отзыва или пусто, если не отменён
  4. Серийный номер (шестнадцатеричный)
  5. Расположение файла или unknown, если не известно
  6. Отличительное имя

Операции корневого центра сертификации

Чтобы создать CRL из нового CA, используйте ключ -gencrl команды ca:

openssl ca -gencrl -config root-ca.conf -out root-ca.crl

Чтобы выдать сертификат, вызовите команду ca с нужными параметрами. Важно, чтобы переключатель -extensions указывал на правильный раздел в файле конфигурации (например, вы ведь не хотите создавать другой корневой ЦС).

openssl ca -config root-ca.conf -in sub-ca.csr -out sub-ca.crt -extensions sub_ca_ext

Чтобы отозвать сертификат, используйте ключ -revoke команды ca; Вам понадобится копия сертификата, который вы хотите отозвать. Поскольку все сертификаты хранятся в каталоге certs/, вам нужно знать только серийный номер. Если у вас есть отличительное имя, вы можете посмотреть серийный номер в базе данных.

Выберите правильную причину для значения в ключе -crl_reason. Значение может быть одним из следующих: unspecified, keyCompromise, CACompromise, affiliationChanged, superseded, cessationOfOperation, certificateHold и removeFromCRL.

openssl ca -config root-ca.conf -revoke certs/1002.pem -crl_reason keyCompromise

Создание сертификата для подписи OCSP

Сначала мы создаём ключ и CSR для респондента OCSP. Эти две операции выполняются так же, как и для любого сертификата не-CA, поэтому мы не указываем файл конфигурации:

openssl req -new -newkey rsa:2048 -subj "/C=GB/O=Example/CN=OCSP Root Responder" -keyout private/root-ocsp.key -out root-ocsp.csr

Во-вторых, используйте корневой центр сертификации для выдачи сертификата. Значение параметра -extensions указывает ocsp_ext, который обеспечивает установку расширений, подходящих для подписи OCSP. Срок действия нового сертификата уменьшен до 365 дней (по умолчанию 3650). Поскольку эти сертификаты OCSP не содержат информации об аннулировании, они не могут быть отозваны. По этой лучше, чтобы срок службы был как можно короче. Хороший выбор — 30 дней, при условии, что вы готовы часто создавать новый сертификат:

openssl ca -config root-ca.conf -in root-ocsp.csr -out root-ocsp.crt -extensions ocsp_ext -days 30

Теперь у вас есть все, что нужно для запуска респондента OCSP. Для тестирования вы можете сделать это с того же компьютера, на котором находится корневой ЦС. Однако для производства вы должны переместить ключ респондента OCSP и сертификат в другое место:

openssl ocsp -port 9080 -index db/index -rsigner root-ocsp.crt -rkey private/root-ocsp.key -CA root-ca.crt -text

Вы можете проверить работу ответчика OCSP с помощью следующей команды:

openssl ocsp -issuer root-ca.crt -CAfile root-ca.crt -cert root-ocsp.crt -url http://127.0.0.1:9080

В выходных данных проверка «OK» означает, что подписи были правильно проверены, а «good» означает, что сертификат не был отозван.

Response verify OK
root-ocsp.crt: good
        This Update: Jul  9 18:45:34 2014 GMT

Создание подчинённого ЦС

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

Конфигурация подчинённого ЦС

Чтобы создать файл конфигурации (sub-ca.conf) для подчинённого ЦС, начните с файла, который мы использовали для корневого ЦС, и внесите изменения, перечисленные в этом разделе. Мы изменим имя на sub-ca и будем использовать другое отличительное имя. Мы установим респондент OCSP на другой порт, но только потому, что команда ocsp не понимает виртуальные хосты. Если вы используете правильный веб-сервер для респондента OCSP, вы можете вообще не использовать специальные порты. Срок действия новых сертификатов по умолчанию составит 365 дней, и мы будем генерировать новый CRL один раз каждые 30 дней.

Изменение copy_extensions на copy означает, что расширения из CSR будут скопированы в сертификат, но только если они ещё не установлены в нашей конфигурации. С этим изменением тот, кто готовит CSR, может поместить в него необходимые альтернативные имена, и информация оттуда будет собрана и помещена в сертификат. Эта функция несколько опасна (вы позволяете кому-то другому иметь ограниченный прямой контроль над тем, что входит в сертификат), но я думаю, что это нормально для небольших сред:

[default]
name                    = sub-ca
ocsp_url                = http://ocsp.$name.$domain_suffix:9081

[ca_dn]
countryName             = "GB"
organizationName        = "Example"
commonName              = "Sub CA"

[ca_default]
default_days            = 365
default_crl_days        = 30
copy_extensions         = copy

В конце файла конфигурации мы добавим два новых профиля, по одному для сертификатов клиента и сервера. Единственная разница заключается в расширениях keyUsage и extendedKeyUsage. Обратите внимание, что мы указываем расширение basicConstraints, но устанавливаем его в false. Мы делаем это, потому что мы копируем расширения из CSR. Если бы мы оставили это расширение, мы могли бы в конечном итоге использовать одно из указанных в CSR:

[server_ext]
authorityInfoAccess     = @issuer_info
authorityKeyIdentifier  = keyid:always
basicConstraints        = critical,CA:false
crlDistributionPoints   = @crl_info
extendedKeyUsage        = clientAuth,serverAuth
keyUsage                = critical,digitalSignature,keyEncipherment
subjectKeyIdentifier    = hash

[client_ext]
authorityInfoAccess     = @issuer_info
authorityKeyIdentifier  = keyid:always
basicConstraints        = critical,CA:false
crlDistributionPoints   = @crl_info
extendedKeyUsage        = clientAuth
keyUsage                = critical,digitalSignature
subjectKeyIdentifier    = hash

После того, как вы довольны файлом конфигурации, создайте структуру каталогов, следуя тому же процессу, что и для корневого центра сертификации. Просто используйте другое имя каталога, например, sub-ca.

Генерация подчинённого ЦА

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

openssl req -new -config sub-ca.conf -out sub-ca.csr -keyout private/sub-ca.key

На втором этапе мы получаем корневой CA для выдачи сертификата. Ключ -extensions указывает на раздел sub_ca_ext в файле конфигурации, который активирует расширения, подходящие для подчинённого ЦС.

openssl ca -config root-ca.conf -in sub-ca.csr -out sub-ca.crt -extensions sub_ca_ext

Операции подчинённого ЦС

Чтобы выдать сертификат сервера, обработайте CSR, указав server_ext в ключе -extensions:

openssl ca -config sub-ca.conf -in server.csr -out server.crt -extensions server_ext

Чтобы выдать сертификат клиента, обработайте CSR, указав client_ext в ключе -extensions:

openssl ca  -config sub-ca.conf -in client.csr -out client.crt -extensions client_ext

Примечание: при запросе нового сертификата вся его информация будет представлена вам для проверки до завершения операции. Вы должны всегда следить за тем, чтобы все было в порядке, но особенно если вы работаете с CSR, подготовленным кем-то другим. Обратите особое внимание на отличительное имя сертификата, а также на базовые ограничения и расширения субъекта альтернативного имени.

Создание CRL и отзыв сертификата такие же, как для корневого CA. Единственное, что отличается от ответчика OCSP — это порт; подчинённый ЦС должен использовать 9081. Рекомендуется, чтобы респондент использовал свой собственный сертификат, чтобы избежать начилие подчинённого ЦС на общедоступном сервере.

Шифрование файлов в OpenSSL

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

Для шифрования файлов вместо OpenSSL рекомендуется использовать инструмент gpg. С этим инструментом вы можете познакомиться в статье «Как пользоваться gpg: шифрование, расшифровка файлов и сообщений, подпись файлов и проверка подписи, управление ключами».

Симметричное шифрование файлов в OpenSSL

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

Для шифрования используется команда следующего вида:

openssl enc -ШИФР -in ДЛЯ-ШИФРОВАНИЯ -out ЗАШИФРОВАНЫЕ-ДАННЫЕ

Для расшифровки похожая команда, но с опцией -d, также ЗАШИФРОВАНЫЕ-ДАННЫЕ теперь являются входными, а на выходе РАСШИФРОВАННЫЕ-ДАННЫЕ:

openssl enc -ШИФР -d -in ЗАШИФРОВАНЫЕ-ДАННЫЕ -out РАСШИФРОВАННЫЕ-ДАННЫЕ

В качестве ШИФРА рекомендуют aes-256-cbc, а полный список шифров вы можете посмотреть командой:

openssl enc -list

Ещё настоятельно рекомендуется использовать опцию -iter ЧИСЛО. Она использует указанное ЧИСЛО итераций для пароля при получении ключа шифрования. Высокие значения увеличивают время, необходимое для взлома пароля брут-форсом зашифрованного файла. Эта опция включает использование алгоритма PBKDF2 для получения ключа. Указывать можно высокие значения — десятки и сотни тысяч. В разделе «Как создать базу данных KeePass» при создании базы данных используется такой же алгоритм (первая версия), там для 1 секундной задержки я выставлял значение в 25 миллионов инераций.

Пример шифрования файла art.txt шифром aes-256-cbc, зашифрованные данные будут помещены в файл с именем art.txt.enc, при получении ключа шифрования используется десять миллионов итераций (на моём железе выполнение команды заняло несколько секунд):

openssl enc -aes-256-cbc -in art.txt -out art.txt.enc -iter 10000000

Введите, а затем подтвердите пароль для шифрования:

В результате будет создан зашифрованный файл art.txt.enc.

Для расшифровки файла art.txt.enc и сохранения данных в файл art-new.txt:

openssl enc -aes-256-cbc -d -in art.txt.enc -out art-new.txt -iter 10000000

Если файл успешно расшифрован, то не будет выведена никакая дополнительная информация.

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

bad decrypt
140381536523584:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:crypto/evp/evp_enc.c:583:

Возможные причины ошибки:

  • неверный пароль
  • неверный алгоритм для расшифровки
  • неправильно указано количество итераций с опцией -iter
  • неверно указан файл для расшифровки

Обратите внимание, что для расшифровки также нужно указать опцию -iter с тем же самым значением, которое было указано при шифровании. Конечно, можно не использовать опцию -iter при шифровании (а, следовательно, и при расшифровке), но в этом случае шифрование считается ненадёжным! Не рекомендуется пропускать опцию. Если у вас слабое железо ИЛИ если файл будет расшифровываться на слабом железе, то вам необязательно использовать такие большие значения -iter — укажите хотя бы десятки или сотни тысяч (например, полмиллиона).

Предыдущие команды для шифрования и расшифровки могут запускаться чуть иначе:

openssl ШИФР

Например:

openssl aes-256-cbc -in art.txt -out art.txt.enc -iter 10000000

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

Зашифрованный файл представляет собой бинарные данные, которые не получится передать, например, в текстовом сообщении (в чате). Используя опцию -a (или её псевдоним -base64), можно закодировать зашифрованные данные в кодировку Base64:

openssl enc -aes-256-cbc -in art.txt -out art.txt.b64 -iter 10000000 -a

Содержимое полученного файла art.txt.b64 можно открыть любым текстовым редактором и переслать в мессенджере или в чате.

Для расшифровки также нужно указать опцию -a:

openssl enc -aes-256-cbc -d -in art.txt.b64 -out art-new.txt -iter 10000000 -a

Чтобы просто закодировать бинарный файл в кодировку base64:

openssl enc -base64 -in file.bin -out file.b64

Чтобы раскодировать этот файл:

openssl enc -base64 -d -in file.b64 -out file.bin

Чтобы зашифровать файл используя указанный ПАРОЛЬ в команде (не интерактивный режим):

openssl enc -aes128 -pbkdf2 -d -in file.aes128 -out file.txt -pass pass:ПАРОЛЬ

Зашифровать файл, затем закодировать его с помощью base64 (например, его можно отправить по почте), используя AES-256 в режиме CTR и с получением производной ключа PBKDF2:

openssl enc -aes-256-ctr -pbkdf2 -a -in file.txt -out file.aes256

Декодировать файл из Base64 , затем расшифровывать его, используя пароль, указанный в файле:

openssl enc -aes-256-ctr -pbkdf2 -d -a -in file.aes256 -out file.txt -pass file:<ФАЙЛ-С-ПАРОЛЕМ>

Как зашифровать строки в OpenSSL (симметричное шифрование)

Следует помнить, что для шифрования используется весь набор символов ASCII, включая непечатаемые символы. Если вы хотите иметь возможность вырезать и вставлять зашифрованные данные из консоли или текстового файла, вам нужно преобразовать их только в печатные символы. Вы можете сделать это с опцией -base64 (или -a):

echo 'Текст для шифрования' | openssl enc -base64 -aes-256-cbc -iter 1000000 -pass pass:ПАРОЛЬ

Вывод:

U2FsdGVkX19dVUjYAX58nYeNWEcJUqpywiFsZzD2DHPz7kNX97YUwqvp7KxV9Dme
dwfBncJ5zcoIRctPdQkXsg==

Расшифровка делается таким же образом (нужно дополнительно указать опцию -d):

echo "U2FsdGVkX19dVUjYAX58nYeNWEcJUqpywiFsZzD2DHPz7kNX97YUwqvp7KxV9DmedwfBncJ5zcoIRctPdQkXsg==" | openssl enc -base64 -d -aes-256-cbc -iter 1000000 -pass pass:ПАРОЛЬ

ВНИМАНИЕ: Если вы используете openssl, то можно предположить, что конфиденциальность данных и, следовательно, пароль, важны для вас. Если это так, вы никогда не должны указывать пароль в командной строке, потому что он может быть показан любому, кто имеет право запускать ps (смотрите Как использовать команду ps для мониторинга процессов Linux).

Лучшее решение — сохранить пароль в переменной окружения и открыть его с помощью openssl:

export passwd="ПАРОЛЬ"
echo "U2FsdGVkX19dVUjYAX58nYeNWEcJUqpywiFsZzD2DHPz7kNX97YUwqvp7KxV9DmedwfBncJ5zcoIRctPdQkXsg==" | openssl enc -base64 -d -aes-256-cbc -iter 1000000 -pass env:passwd

Асимметричное шифрование файлов в OpenSSL

Необходимо сгенерировать приватный ключ и извлечь из него публичный ключ. Публичным ключом данные будут шифроваться, а приватным ключом — расшифровываться. Команды для генерации ключей уже рассмотрены выше, напомним их (в данном случае приватный ключ будет сохранён в файл private.key):

openssl genpkey -algorithm RSA -out private.key -pkeyopt rsa_keygen_bits:8192

Для извлечения публичного ключа в файл (public.key) из приватного ключа (private.key):

openssl rsa -in private.key -pubout -out public.key

Для шифрования файла:

openssl rsautl -encrypt -pubin -inkey ПУБЛИЧНЫЙ-КЛЮЧ.key -in ЗАШИФРОВАТЬ.txt -out ЗАШИФРОВАНО.txt

Для расшифровки:

openssl rsautl -decrypt -inkey ПРИВАТНЫЙ-КЛЮЧ.key -in ЗАШИФРОВАНО.txt -out РАСШИФРОВАНО.txt

Описанным методом невозможно зашифровать большие файлы!

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

1. Ассиметричное шифрование для симметричного ключа

Сгенерируйте симметричный ключ, которым вы сможете зашифровывать большие файлы:

openssl rand -base64 32 > key.bin

Зашифруйте большие файлы используя симметричный ключ (как это показано в предыдущем разделе):

openssl enc -aes-256-cbc -in БОЛЬШОЙ-ФАЙЛ -out БОЛЬШОЙ-ФАЙЛ.enc -pass file:./key.bin

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

openssl rsautl -encrypt -inkey public.pem -pubin -in key.bin -out key.bin.enc

Удаляем незашифрованный симметричный ключ, чтобы никто его не узнал:

shred -u key.bin

Теперь отправляем зашифрованный симметричный ключ (key.bin.enc) и зашифрованный большой файл (БОЛЬШОЙ-ФАЙЛ.enc) другому лицу.

Другое лицо может при получении расшифровать симметричный ключ используя свой приватный ключ:

openssl rsautl -decrypt -inkey private.pem -in key.bin.enc -out key.bin

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

openssl enc -d -aes-256-cbc -in БОЛЬШОЙ-ФАЙЛ.enc -out БОЛЬШОЙ-ФАЙЛ.enc -pass file:./key.bin

2. С помощью команды smime

Решение для безопасного и высокозащищенного кодирования любого файла в OpenSSL и командной строке:

Для шифрования файлов вы должны иметь готовый сертификат X.509 в формате PEM.

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

openssl req -x509 -nodes -days 100000 -newkey rsa:8192 -keyout private_key.pem -out certificate.pem

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

openssl req -x509 -days 100000 -newkey rsa:8192 -keyout private_key.pem -out certificate.pem

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

openssl req -x509 -new -days 100000 -key private_key.pem -out certificate.pem

Чтобы зашифровать файл выполните:

openssl smime -encrypt -binary -aes-256-cbc -in plainfile.zip -out encrypted.zip.enc -outform DER yourSslCertificate.pem

В этой команде:

  • smime — ssl команда для S/MIME утилиты
  • -encrypt — выбранным действием с файлом является шифрование
  • -binary — использовать безопасный файловый процесс. Обычно входное сообщение преобразуется в «канонический» формат, как того требует спецификация S/MIME, этот переключатель отключает его. Это необходимо для всех двоичных файлов (например, изображений, звуков, ZIP-архивов).
  • -aes-256-cbc — выбран шифр AES в 256 бит для шифрования (сильный). Если не указано, используется 40-битный RC2 (очень слабый).
  • -in plainfile.zip — файл для шифрованиия
  • -out encrypted.zip.enc — файл для сохранения зашифрованных данных
  • -outform DER — закодировать выходной файл как двоичный файл. Если не указан, файл будет закодирован в base64, а размер файла будет увеличен на 30%.
  • yourSslCertificate.pem — имя файла вашего сертификата. Он должен быть в формате PEM.

Эта команда может очень эффективно сильно шифровать большие файлы независимо от их формата.

Известная проблема: что-то не так происходит, при попытках зашифровать огромный файл (> 600 МБ). Ошибка не выводится, но зашифрованный файл будет повреждён. Всегда проверяйте каждый файл! (или используйте PGP — больше поддержки шифрования файлов с открытым ключом).

Расшифровка файла:

openssl smime -decrypt -binary -in encrypted.zip.enc -inform DER -out decrypted.zip -inkey private.key -passin pass:ВАШ-ПАРОЛЬ

В этой команде:

  • -inform DER — то же самое, что и в -outform выше
  • -inkey private.key — имя файла вашего приватного ключа. Он должен быть в формате PEM и может быть зашифрован паролем.
  • -passin pass:ВАШ-ПАРОЛЬ — ваш пароль для зашифрованного приватного ключа.

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

Пининг сертификатов (pinning)

[СКОРО БУДЕТ ДОБАВЛЕНО]

 

Словарь основных терминов OpenSSL

[СКОРО БУДЕТ ДОБАВЛЕНО]

 

 

Программы для проверки настроек SSL и сбора информации

[СКОРО БУДЕТ ДОБАВЛЕНО]


Рекомендуется Вам:

8 комментариев to OpenSSL: принципы работы, создание сертификатов, аудит

  1. Kali:

    Очень жду добавления. Хотелось бы проверить сертификаты…

  2. Аноним:

    1.
    Вы пишите:
    "Он «т.е. сертификат« может зашифровать данные (в нём есть публичный ключ), которые способен расшифровать только приватный ключ составляющий пару этому сертификату

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

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

    Не до конца понятен механизм процедуры шифрования в обе стороны: есть сертификат, его проверил браузер, отправил какие-то данные на сервер и эти "данные может расшифровать только владелец приватного ключа" - как мы знаем, этот ключ хранится только на сервере, но "происходит согласование ключа, используемого для последующего шифрования" - это тот ключ который позволяет расшифровать зашифрованный ответ с сервера при последующих соединениях? - потому что каким образом расшифровывает запрос от пользователя наш сервер, это понятно.
    2.
    Опишите еще как правильно настроить Diffie-Hellman key.
    Просто создать ключ и поместить в папку с сертификатами, не требуеются дополнительные строки чтобы его подключить или указать на его присутствие в системе?

    sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
     

    спасибо за ответ

    • Alexey:

      это тот ключ который позволяет расшифровать зашифрованный ответ с сервера при последующих соединениях?

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

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

      Ключ для симметричного шифрования меняется для каждого соединения.

      Это упрощённое описание, поскольку есть ещё понятие сессий и master secret.

      На самом деле происходит следующее:

      1. Во время ассиметричного шифрования происходит согласование master secret

      2. Для каждого нового соединения генерируется новый ключ для симметричного шифрования

      3. Время от времени master secret тоже меняется

      Ещё раз, в пределах одной сессии (определяется session ID который клиент и сервер отправляют друг другу в их ClientHello и ServerHello сообщениях) используется один master secret.. Для каждого нового соединения создаётся новый ключ для симметричного шифрования, который является производным master secret.

      Когда клиент открывает соединение с сервером, они могут участвовать:

      • в полном рукопожатии, когда выполняется согласование нового master secret.
      • в сокращённом рукопожатии (abbreviated handshake), когда они соглашаются использовать master secret из предыдущего соединения.
    • Alexey:

      Опишите еще как правильно настроить Diffie-Hellman key.

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

      DH уже используется. Не нужно генерировать дополнительные ключи и что-либо настраивать.

  3. Аноним:

    мне кажется, что эта строчка не работает

    openssl req -new -sha256 -key mydomain.com.key -subj "/C=US/ST=CA/O=MyOrg, Inc./CN=mydomain.com" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:mydomain.com,DNS:www.mydomain.com")) -out mydomain.com.csr

    ошибка:
    unable to find ‘distinguished_name’ in config
    problems making Certificate Request

    делаю что-то не так?

    • Alexey:

      Я тоже не знаю, что вы делаете на так. Только что проверил на двух системах (Kali Linux и Arch Linux), команда сработала без ошибок.

      Эта ошибка связана с файлом /etc/ssl/openssl.cnf. Возможно, вы вносили в него изменения и в конечном счёте сделали невалидным.

      Попробуйте восстановить исходный файл (возможные пути до оригинального файла /etc/ssl/openssl.cnf.original, /etc/ssl/openssl.cnf.dist или поищите с locate openssl.cnf) и повторите команду.

  4. подраздел: Автоматическая генерация CSR

    [req]

    prompt = no

    distinguished_name = dn

    req_extensions = ext

    input_password = ЗДЕСЬ_ПАРОЛЬ

    ЗДЕСЬ_ПАРОЛЬ - здесь имеется в виду пароль из challengePassword ?

    Please enter the following 'extra' attributes
    to be sent with your certificate request
    A challenge password []:

    Attributes:
                challengePassword        :123456

     

  5. Алексей:

    Добрый, день. А как шифровать/подписывать с помощью ECDSA, с указанием вида эллиптической кривой?

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

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