OpenSSL, часть 1: Создание собственного Удостоверяющего Центра (Certification Authority)
В данной серии публикаций предполагается, что читатель знаком с концепцией криптографических систем с открытым ключом PKI. Почитать теорию можно, например, в Википедии. Для реализации PKI будем использовать свободное ПО OpenSSL. В отличии от большинства публикаций, буду параллельно описывать процедуру сразу в 2-х вариантах PKI для криптоалгоритма RSA и ГОСТ Р 34.10-2012. Синтаксис команд не отличается для различных дистрибутивов Linux и даже для Windows, полная инструкция будет состоять из следующих частей:
- Часть 1: Создание корневого Удостоверяющего Центра (УЦ) [ВЫ НАХОДИТЕСЬ ЗДЕСЬ];
- Часть 2: Создание ключа и сертификата для веб-серверов;
- Часть 3: Создание ключа и сертификата для пользователей.
Подготовительный этап
Для криптоалгоритмов RSA достаточно установить пакет openssl, для установки используйте стандартный менеджер пакетов вашего дистрибутива:
$ sudo pacman -S openssl
Для варианта ГОСТ потребуется дополнительно установить пакет из AUR openssl-gost-engine, в других дистрибутивах он может называется gost-engine, libengine-gost-openssl или возможно ещё как-то по-другому:
$ yay -S openssl-gost-engine
После установки внесите следующие изменения в файл конфигураци openssl /etc/ssl/openssl.cnf (инструкция выводится сразу после установки пакета):
# Вставить в начале перед первой секций в скобках [...]:
openssl_conf=openssl_gost
[ new_oids ]
...
# Вставить в самом конце файла после всех секций:
# GOST Engine Configuration
[openssl_gost]
engines = engine_section
[engine_section]
gost = gost_section
[gost_section]
engine_id = gost
dynamic_path = /usr/lib/engines-3/gost.so
default_algorithms = ALL
init = 0
# GOST Engine Configuration End
Для нового корневого УЦ необходимо выбрать своё уникальное название, например имя вашей компании, в тексте далее это будет 'Demo Root CA 2023'. В любом защищённом от постороннего доступа месте подготовьте структуру каталогов по примеру ниже. Все команды и скрипты из статьи предназначены для запуска из корневой папки, поэтому перед началом работы нужно выполнить переход командой cd [ваша корневая папка]:
$ tree
. # в корне будут располагаться исполняемые скрипты и файлы конфигурации
├── ca # место для хранения закрытого ключа и сертификата УЦ (CA)
├── certs # здесь будет архив подписанных публичных сертификатов
├── crl # место для списка отзывов сертификатов
└── newkey # здесь генерируется все новые пары ключей и сертификаты, для последующей передачи клиенту
Создание ключа и самоподписанного сертификата Удостоверяющего Центра (RSA)
С помощью нижеследующего скрипта генерируем закрытый ключ нового УЦ c длиной ключа 4096 бит, шифруем его алгоритмом aes256, подписываем им сертификат УЦ сроком на 20 лет (7300 дней):
#!/bin/bash
echo "*** Создание приватного ключа ***"
openssl genpkey \
-aes256 \
-algorithm RSA \
-pkeyopt rsa_keygen_bits:4096 \
-out ./ca/ca.key
echo "*** Самоподписывание сертификата ***"
openssl req \
-x509 \
-new \
-days 7300 \
-key ./ca/ca.key \
-out ./ca/ca.crt \
-addext "basicConstraints = critical,CA:TRUE" \
-addext "subjectKeyIdentifier = hash" \
-addext "authorityKeyIdentifier = keyid:always,issuer" \
-addext "keyUsage = critical,keyCertSign,cRLSign"
echo "*** Просмотр сертификата ***"
openssl x509 -text -in ./ca/ca.crt
Скрипт по ходу выполнения задаст вопросы, а в конце выводит на просмотр полученный сертификат. Проверяем его, обращаем особое внимание на выделенные места:
$ ./gen-ca-rsa.sh
*** Создание приватного ключа ***
.+.......+.....+...+...+......+....+...........+.............+..+...+
Enter PEM pass phrase: Придумываем и вводим пароль ключа УЦ
Verifying - Enter PEM pass phrase: Повторяем пароль ключа УЦ
*** Самоподписывание сертификата ***
Enter pass phrase for ./ca/ca.key: Вводим пароль УЦ третий раз
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:RU
State or Province Name (full name) [Some-State]:. #Вводим точку во всех полях, которые хотим оставить пустыми
Locality Name (eg, city) []:.
Organization Name (eg, company) [Internet Widgits Pty Ltd]:.
Organizational Unit Name (eg, section) []:.
Common Name (e.g. server FQDN or YOUR name) []:Demo Root CA 2023
Email Address []:.
*** Просмотр сертификата ***
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
2b:0e:f1:aa:fb:85:83:e3:f8:87:4d:b8:ab:b5:8c:51:05:06:47:ba
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = RU, CN = Demo Root CA 2023
Validity
Not Before: Oct 17 12:38:47 2023 GMT
Not After : Oct 12 12:38:47 2043 GMT
Subject: C = RU, CN = Demo Root CA 2023
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (4096 bit)
Modulus:
00:ce:e4:55:5e:1d:ed:50:0b:9b:2b:18:4c:a1:58:
...
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Subject Key Identifier:
0F:15:FA:80:32:90:70:6C:15:CA:0F:FC:E9:36:6E:C5:A2:2D:43:18
X509v3 Authority Key Identifier:
0F:15:FA:80:32:90:70:6C:15:CA:0F:FC:E9:36:6E:C5:A2:2D:43:18
X509v3 Key Usage: critical
Certificate Sign, CRL Sign
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
c3:e1:8c:10:33:5e:4d:92:a1:21:7f:ce:62:54:1d:80:0a:b2:
...
Файл ca.key и пароль для его расшифровки (PEM pass phrase) теперь являются самой чувствительной информацией ИТ-инфраструктуры и необходимо принять максимально возможные меры для защиты их от утечки. Файл с закрытым ключом УЦ ни в какой ситуации не подлежит копированию или передаче посторонним лицам! Так как скрипт генерации УЦ одноразовый, то во избежание случайного его запуска и затирания ключа после использования удалите его или переместите в безпасное место!
Если вы не хотите шифровать закрытый ключ, находящийся в файле ca.key, то можете не указывать опцию -aes256, но в этом случае у вас не будет никакого безопасного способа работы с УЦ, кроме как полностью отсоединить компьютер от сети и взаимодействовать с внешним миром исключительно через флешку.
Создание закрытого ключа Удостоверяющего Центра по ГОСТ Р 34.10-2012
Здесь все по аналогии с RSA, но с дополнительными опциями. Генерируем закрытый ключ нового УЦ c длиной ключа 512 бит и набором параметров подписи "C" и самоподписанный сертификат с помощью скрипта:
#!/bin/bash
echo "*** Создание приватного ключа ГОСТ ***"
openssl genpkey \
-aes256 \
-engine gost \
-algorithm gost2012_512 \
-pkeyopt paramset:C \
-out ./ca/ca-gost.key
echo "*** Самоподписывание сертификата ***"
openssl req \
-engine gost \
-x509 \
-new \
-days 7300 \
-key ./ca/ca-gost.key \
-out ./ca/ca-gost.crt \
-addext "basicConstraints = critical,CA:TRUE" \
-addext "subjectKeyIdentifier = hash" \
-addext "authorityKeyIdentifier = keyid:always,issuer" \
-addext "keyUsage = critical,keyCertSign,cRLSign"
echo "*** Просмотр сертификата ***"
openssl x509 -text -in ./ca/ca-gost.crt
Скрипт по ходу выполнения задаст вопросы, а в конце выводит на просмотр полученный сертификат. Проверяем его, обращаем особое внимание на выделенные места:
$ ./gen-ca-gost.sh
*** Создание приватного ключа ГОСТ ***
Engine "gost" set.
Enter PEM pass phrase: Придумываем и вводим пароль ключа УЦ
Verifying - Enter PEM pass phrase: Повторяем пароль ключа УЦ
*** Самоподписывание сертификата ***
Engine "gost" set.
Enter pass phrase for ./ca/ca-gost.key: Вводим пароль УЦ третий раз
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:RU
State or Province Name (full name) [Some-State]:. #Вводим точку во всех полях, которые хотим оставить пустыми
Locality Name (eg, city) []:.
Organization Name (eg, company) [Internet Widgits Pty Ltd]:.
Organizational Unit Name (eg, section) []:.
Common Name (e.g. server FQDN or YOUR name) []:Demo Root CA GOST
Email Address []:.
*** Просмотр сертификата ***
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
05:ef:29:a9:63:a1:a7:b6:0a:19:22:aa:01:1a:de:e7:d4:34:bb:ab
Signature Algorithm: GOST R 34.10-2012 with GOST R 34.11-2012 (512 bit)
Issuer: C = RU, CN = Demo Root CA GOST
Validity
Not Before: Oct 17 14:40:22 2023 GMT
Not After : Oct 12 14:40:22 2043 GMT
Subject: C = RU, CN = Demo Root CA GOST
Subject Public Key Info:
Public Key Algorithm: GOST R 34.10-2012 with 512 bit modulus
Public key:
X:A9CF8BB18699AEC8A5855B8877BD435FD42009C51A1EF3BF188187861534A0D171C0354CDB7C2189B300EF008A64BD8869E3450D482CEF5265E5D408D808CB40
Y:1E32B46EDF5BFFBF4CB5ECFB8E51F07C69D43C1EB0BF0A10A95C77ABC5D04740E241ADCCB73D499CCEFCBA86FA1FCCF846FF9F5D6C623E78D149DE1192C80CDE
Parameter set: GOST R 34.10-2012 (512 bit) ParamSet C
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Subject Key Identifier:
00:C1:39:05:41:60:42:D0:7C:A8:16:41:B5:EE:7F:C9:52:C7:01:2F
X509v3 Authority Key Identifier:
00:C1:39:05:41:60:42:D0:7C:A8:16:41:B5:EE:7F:C9:52:C7:01:2F
X509v3 Key Usage: critical
Certificate Sign, CRL Sign
Signature Algorithm: GOST R 34.10-2012 with GOST R 34.11-2012 (512 bit)
Signature Value:
0b:f1:3a:2a:9c:ec:df:e4:a2:8d:3b:be:22:80:b4:e4:29:d5:
...
Что делать дальше
Если с сертификатом полный порядок, то рекомендуется скопировать ca.crt в общедоступный каталог на сервере или разместить на веб-сервере компании, чтобы любой сотрудник мог его установить себе на компьютер. Имя файла никакого значения не имеет, можно переименовать, главное что нужно - это сохранить расширение crt, для удобства пользователей Windows и графических сред Linux.
Как вы наверно понимаете, любой софт, использующий системное хранилище, будет доверять только тем самоподписанным УЦ, открытые сертификаты которых установлены и системе, либо в хранилище самой этой программы. Этим вопросом и займемся в следующей главе.
Установка сертификата корневого УЦ на компьютеры под управлением Linux
У каждого дистрибутива Linux есть свои особенности, универсального рецепта нет. В Arch установка нашего нового сертификата ЦС в список доверенных корневых центров сертификации выполняется следующим способом:
$ sudo cp ./ca/ca.crt /etc/ca-certificates/trust-source/anchors
$ sudo trust extract-compat
В Debian и Ubuntu по-другому:
$ sudo cp ./ca/ca.crt /usr/local/share/ca-certificates
$ sudo update-ca-certificates
Кроме того, развитые десктопы имеют встроенные средства графического управления. Например, в KDE Plasma в "Параметрах системы" можно посмотреть результат выполненной выше команды, или добавить файл ca.crt без консоли с помощью кнопки. При добавлении графическим способом разница будет в том, что корневой сертификат установится только для текущего десктопного пользователя. Службы, работающие под своей учёткой, такой корневой сертификат не увидят и будут проблемы.
Установка сертификата корневого УЦ на компьютеры под управлением Windows
Здесь всё просто, вы и сами это знаете: дважды щелкаем в проводнике на файл crt и выполняем установку. В больших компаниях установка производится автоматически с помощью политик, скриптов или стандартных заранее подготовленных образов для установки.
Установка сертификата корневого УЦ на мобильные устройства под управлением Android
В настройках аппарата делаем поиск по ключемым словам 'certificate' или 'сертификат', находим меню установки и выполняем установку файла ca.crt. Следует иметь ввиду, что не каждая вендорская прошивка позволяет устанавливать пользовательские корневые сертификаты УЦ.