Это древний текст, он уже неактуален и вряд ли кому понадобится, но пусть хранится для истории.
В этой заметке в деталях описывается процесс создания собственного Центра сертификации и последующая генерация сопутствующих файлов: сертификатов, запросов на сертификат и так далее. Считаем, что работаем в терминале на линукс/юникс машине с установленным openssl.
Заметка является вольным переложением на русский язык вот этой статьи (плюс мой собственный материал). Здесь описываются базовые «низкоуровневые» команды для работы с сертификатами (x509, req и т.п.)
Больше о цифровых сертификатах в других постах:
Коротко о главном¶
Удостоверяющий центр (по-английски Certification authority, сокращённо CA) — это единый центр генерации цифровых сертификатов. У конечных клиентов (например, веб-браузеров) имеется база публичных ключей разных CA и они проверяют ими приходящие, например, от сайтов сертификаты. Нас интересуют сертификаты, используемые в сеансах, защищённых протоколом SSL/TLS.
Собственно, всю процедуру можно разбить на такие шаги:
- генерим приватный ключ (сильно случайный набор байтов);
- генерим на основе приватного ключа пару сертификатов для CA (публичный и приватный);
- генерим пару сертификатов для домена, подписанных созданным на прошлом шаге CA.
Создаём CA¶
Для начала сгенерим приватный ключ (файл ca.key), если хотите зашифровать приватный ключ с паролем, добавьте аргумент -des3
:
$ openssl genrsa -out ca.key 4096
Теперь сгенерим пару сертификатов для нашего CA (вместо 365 можно подставить любое другое значение, это срок годности пары сертификатов в днях):
$ openssl req -new -x509 -days 365 -key ca.key -out ca.crt
Вводим пароль к ключу (если ключ был зашифрован) и затем аккуратно заполняем поля субъекта (subject). По этим данным можно будет потом идентифицировать публичный сертификат среди списка других, например. На выходе получаем файл ca.crt — это публичный сертификат нашего CA.
Можно создать ключ и сертификат одной командой, причём в эту же команду можно включить параметры субъекта:
$ openssl req -x509 -newkey rsa:2048 -keyout ca.key -nodes -out ca.crt -subj '/CN=example.com/L=Novosibirsk/C=RU'
К сожалению, эта команда генерит невалидный ключ. Openssl и основанные на этой библиотеке приложения его понимает корректно, однако другие программы могут его не принять. Решается это такой командой (мы просто считываем и снова записываем файл):
$ openssl rsa -in ca.key -out ca.key
Содержимое параметра -subj состоит из сегментов вида /$KEY=$VALUE
, где $KEY
может принимать такие значения:
L
— locality, обычно это городST
— state, обычно это регион, область, район и т.д.C
— country, двухбуквенный код страны, например, RU или USO
— organization, название организацииOU
— organization unit, отдел в организацииCN
— common name, обычно это адрес веб-сайтаemailAddress
— email
Создаём пару сертификатов для домена¶
Итак, у нас есть некий домен (к примеру, example.com) и мы хотим выписать для него SSL-сертификат, подписанный только что созданным CA. Сертификат дальше использовать в браузере. Шаги примерно такие же, как и в случае создания CA:
- создаём новый приватный ключ (нужен новый приватный ключ, тот, нельзя использовать тот, который мы делали для CA);
- создаём Certificate signing request (CSR), который потом нужно отправить CA;
- со стороны CA генерим сертификат на основе Certificate signing request;
- устанавливаем полученный сертификат на сервер.
Итак, генерим ключ (можете добавить -des3
, чтобы зашифровать ключ паролем):
$ openssl genrsa -out server.key 4096
Приватный ключ хранится на стороне владельца сервера и не должен никогда никому отдаваться. На базе приватного ключа server.key генерится так называемый запрос на подпись сертификата (по-английски certificate signing request (csr)), в запросе заполняются параметры субъекта (имя, адрес, домены итп), затем этот файл отправляется CA и тот создаёт сертификат на основе данных из CSR, подписывает его своим приватным ключом, в результате получаем подписанный публичный сертификат.
Вот простейший способ создать csr:
$ openssl req -new -key server.key -out server.csr
В процессе работы нужно ответить на несколько вопросов (страна, город, имя домена итп), в результате получится csr-файл, который можно отправлять CA. Однако у такого способа есть несколько существенных недостатков — запрос данных идёт по заранее заданному шаблону, в который не входят некоторые важные поля, например, subjectAltName (это расширение для включения нескольких DNS-имён в сертификат).
Единственный мне известный способ указать расширение subjectAltName — это воспользоваться собственным конфигом для openssl. Вот, например, таким:
###############################################
# Remaining options below should not be edited
###############################################
[ req ]
default_bits = 4096
distinguished_name = req_distinguished_name
req_extensions = req_ext
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = RU
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Russia
localityName = Locality Name (eg, city)
localityName_default = Irkutsk
organizationName = Organization Name (eg, company)
organizationName_default = Example, Co.
commonName = Common Name (eg, YOUR name or FQDN)
commonName_max = 64
[ req_ext ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
###############################################
# Edit this line to set subjectAltName contents
###############################################
subjectAltName = DNS:example.com, DNS:www.example.com, DNS:example.net
Сохраните его в файл openssl-csr.cnf и отредактируйте (нужно прописать в поле subjectAltName
свои домены, если вы в конфиге openssl разбираетесь, то можно и другие опции изменить/добавить), после чего выполните вот такую команду:
openssl req -new -key server.key -config openssl-csr.cnf -reqexts req_ext -out server.csr
Полученный файл server.csr теперь нужно «отправить» CA, чтобы там его подписали. Поскольку CA наш собственный, то подписывать будем сами. И здесь тоже есть нюанс, связанный с X509v3-расширениями — команда создания сертификата по умолчанию не включает расширения, указанные в csr (то есть указанные в csr значения для subjectAltName в сертификат не попадут). Мы пойдём по самому простому пути — будем использовать тот же конфиг (openssl-csr.cnf), что и для генерации csr, из него нам понадобится только секция [ req_ext ]
:
$ openssl x509 -req -days 365 -CA ca.crt -CAkey ca.key -set_serial 01 -extfile openssl-csr.cnf -extensions req_ext -in server.csr -out server.crt
В данном случае «срок годности» сертификата устанавливаем в один год (365 дней).
Теперь у нас есть практически полный комплект всех нужных сертификатов. Иногда в сервере нужно использовать незашифрованный ключ, вот как его можно вытащить в файл server.key.insecure, если в server.key лежит зашифрованный ключ:
$ openssl rsa -in server.key -out server.key.insecure
Для удобства использования можно немного переименовать файлы:
$ mv server.key server.key.secure
$ mv server.key.insecure server.key
Используем сертификаты¶
Для начала полезные команды, позволяющие «посмотреть» сертификаты и csr:
$ openssl rsa -noout -text -in server.key
$ openssl req -noout -text -in server.csr
$ openssl rsa -noout -text -in ca.key
$ openssl x509 -noout -text -in ca.crt
Теперь нужно положить сгенерированные сертификаты (server.crt и server.key) в нужное место на сервере. Конкретные детали уже выходят за рамки заметки.
Чтобы браузер не ругался на сертификат, нужно добавить в его репозиторий CA только что созданный CA, а именно файл ca.crt, импортируем, смотрим, что в списке он появился. Также можно сертификат положить в общесистемный репозиторий CA-сертификатов.
Старайтесь не пользоваться этой статьёй. Если будете использовать этот "Root CA", то у вас будет множество ограничений. обязательным требованием является наличие в "Root CA": keyUsage = critical, digitalSignature, keyCertSign, cRLSign
которых в этом мануале нет, если этого не будет, то все подписанные сртификаты будут с ограничениями и когда созреете для нормального PKI - необходимо будет заменять свой корневой сертификат, иначего все нижеподписанные сертификаты будут с ошибкой "Этот центр сертификации не имеет права выдавать сертификаты или не может являться конечным сертификатом."
Спасибо. Написано просто хорошо!
Спасибо. Ничего лишнего. Здорово
Автор, спасибо тебе большое за эту статью, очень помогла и очень вовремя.
Автор молодец!
openssl req -new -key server.key -config /etc/ssl/openssl-csr.cnf -reqexts req_ext -out server.csr
Выдает: Error opening Private Key server.key 24749:error:02001002:system library:fopen:No such file or directory:bss_file.c:356:fopen('server.key','r') 24749:error:20074002:BIO routines:FILE_CTRL:system lib:bss_file.c:358: unable to load Private Key
Здравствуйте !
Как решили ?
Читать невозможно. Весь текст волнами ~~~~~~~~~~. Такое впечатление, что буквы из разных шрифтов.
Спасибо за статью. Правда, еще можно немного добавить команд по генерации csr,key и crt в разных ситуациях (на лету без вопросом, с готовым ключом, с ключом без пароля, и тп.), как пишут здесь - http://sysadm.pp.ua/internet/pound-apache-nginx-ssl-setup.html
Подскажите если мне надо настроить SSL соиденение между одним сервером и множеством агентов, то при генерации ключа второй командой openssl req -new -key server.key -out server.csr вместо server.key указывать имя сервера-агента.key который будет стучатся к моему основному или же имя основного? Заранее спс
Если я правильно понял вопрос, то нужно ключ сервера указывать.
Спасибо, очень помогло