В наши дни очень часто для повышения безопасности сетевых соединений или просто для аутентификации используются SSL сертификаты. Одна из самых популярных свободных программ для создания сертификатов - это OpenSSL. Это утилита командной строки, которая позволяет создавать различные виды сертификатов, например, PKI или HTTPS.
В этой статье мы рассмотрим что такое сертификаты, какими они бывают, разберем подробно создание сертификата OpenSSL. Причем рассмотрим каждый этап, чтобы вам было легче понять что и как происходит.
Содержание статьи
- Что такое сертификаты?
- Создание закрытого ключа
- Создание запроса на подпись
- Подпись сертификатов OpenSSL
- Просмотр сертификатов
- Как использовать сертификат
- Выводы
Что такое сертификаты?
Думаю нужно начать с самого начала. Сертификаты в первую очередь позволяют идентифицировать человека или сервис, подтвердить что вы тот, за кого себя выдаете. А работает это так - есть два ключа - закрытый и открытый. Зашифровать сообщение можно с помощью открытого ключа, но чтобы его расшифровать нужен только закрытый ключ. Если у вас нет закрытого ключа, то вы попросту не сможете расшифровать зашифрованное сообщение. Фактически зашифровать сообщение может каждый, но расшифровать его способен только владелец закрытого (секретного ключа).
Если вы смогли расшифровать отправленное сообщение, зашифрованное с помощью вашего открытого ключа, то значит - это вы. Ключи работают только в паре, и вы не сможете расшифровать ничего другим ключом. Но еще остался один момент. Как определить что этот открытый ключ именно ваш и ему можно доверять? Все просто, достаточно, чтобы кто-то из авторитетных источников, например, Comodo или LetsEncrypt подписал ваш ключ. Это так называемые центры сертификации.
В этой инструкции мы будем иметь дело с такими видами ключей:
- .pem, .crt, .cer - готовый, подписанный центром сертификации сертификат, расширения разные, но означают одно и то же. Если совсем просто, то сертификат, это подписанный открытый ключ, плюс немного информации о вашей компании;
- .key - закрытый или открытый ключ;
- .csr - запрос на подпись сертификата, в этом файле хранится ваш открытый ключ плюс информация, о компании и домене, которую вы указали.
А теперь рассмотрим как создать сертификат openssl, как его подписать и что для этого нужно сделать. Генерация ключей openssl - это довольно простая задача, если во всем разобраться.
Создание закрытого ключа
В этой статье я буду использовать папку ~/certs для создания сертификатов. Вы можете создать эту папку и сразу перейти в неё с помощью команды:
mkdir ~/certs && cd ~/certs
Прежде всего необходимо создать закрытый ключ для сертификата. Для этого нужно использовать команду genrsa:
openssl genrsa -out domain.key 2048
Ей необходимо передать имя файла ключа с помощью опции -out. Вы можете выбрать любое имя, оно не имеет значения. Также можно указать размер ключа, например 2048. Если этого не сделать, то будет создан ключ размером 512 бит. Все ключи размером меньше 512 бит считаются небезопасными. После выполнения команды в текущей папке появится файл ключа:
Для того чтобы получить сертификат, который можно использовать нужно этот ключ подписать. А для этого надо создать запрос на подпись.
Создание запроса на подпись
При создании запроса на подпись нужно указать необходимую информацию. Обязательное поле здесь только одно. Это CN. Здесь должно быть указанно ваше доменное имя, для которого вы собираетесь использовать сертификат, также можно указать дополнительную информацию о вашей компании, адресе и организации, но это уже необязательно. Для создания запроса на подпись для ранее созданного ключа используйте такую команду:
openssl req -key domain.key -new -out domain.csr
Во время создания запроса большинство параметров можно оставить по умолчанию. Обязательно заполнять только Common Name (e.g. server FQDN or YOUR name). Если вы хотите создать сертификат для сайта, то в этом поле нужно указать домен этого сайта. В этом примере будет создан сертификат для localhost:
Вы также можете создать закрытый ключ и запрос на подпись открытого ключа одной командой:
openssl req -newkey rsa:2048 -nodes -keyout domain.key -out domain.csr
Опция -newkey указывает, что нужно создать новую пару ключей, а в параметрах мы сообщаем тип rsa и сложность 2048 байт. Опция -nodes указывает, что шифровать ключ не нужно, опция -new указывает что нужно создать запрос csr.
Кроме того, можно создать csr запрос из уже существующего сертификата и закрытого ключа, тогда вам не придется вводить информацию, она будет получена из сертификата:
openssl x509 -in domain.crt -signkey domain.key -x509toreq -out domain.csr
Параметр -x509toreq указывает, что нужно использовать сертификат для X509 для получения CSR. X509, это сертификаты, подписанные сами собой. Обычно сертификат подписывается другим сертификатом, а этот был подписан сам собой. Если вы получили сертификат от CA, то этот параметр не нужен.
Подпись сертификатов OpenSSL
Допустим, у вас есть приватный ключ и запрос на подпись, фактически, открытый ключ. Теперь вам нужно его подписать чтобы получить сертификат, который можно использовать. Тут есть несколько вариантов. Можно отправить csr файл на подпись какому-либо центру сертификации, например, LetsEncrypt. Можно подписать сертификат тем же ключом, с помощью которого он был создан, и третий вариант - создать свой центр сертификации.
Первый способ я рассматривать не буду. Здесь все просто. Либо используете утилиту сервиса, либо заполняете веб форму и получаете готовый сертификат. Второй вариант гораздо интереснее.
Подпись сертификата самим собой
Мы подпишем наш сертификат сами, ключом, на основе которого он был создан:
openssl x509 -signkey domain.key -in domain.csr -req -days 365 -out domain.crt
С помощью параметра -days мы указываем что сертификат будет действительным в течение 365 дней, то есть в течение года. Обратите внимание, что во время подписи проверяется CN, поэтому если вы не зададите этот параметр на этапе создания запроса на подпись, то ничего не заработает.
Вы можете объединить все в одну команду и сразу создать закрытый ключ, csr и подписанный сертификат:
openssl req -newkey rsa:2048 -nodes -keyout domain.key
-x509 -days 365 -out domain.crt
Или создать самоподписанный сертификат openssl из существующего закрытого ключа без csr:
openssl req -key domain.key -new -x509 -days 365 -out domain.crt
Опция -new говорит, что нужно запросить информацию о csr у пользователя. Чтобы браузер доверял ключу нужно этот же сертификат импортировать в список доверенных.
Подпись сертификатов с помощью OpenSSL
А теперь рассмотрим третий способ выполнить создание сертификата OpenSSL - подписать его с помощью собственного CA, центра сертификации.
Вот вы сейчас думаете что это что-то такое сложное, да? А нет, это обычная папка, в которой лежит защищенный паролем закрытый ключ, с помощью которого мы будем подписывать все другие ключи. А открытая часть этого ключа должна быть добавлена во все браузеры, которые будут ему доверять.
Вообще, центр сертификации в крупных корпорациях находится на отдельных компьютерах, которые даже к сети не подключены. Но для примера мы разместим папку в нашей домашней папке:
mkdir ~/ca && cd ~/ca
Дальше нужно создать самоподписанный сертификат openssl для нашего CA.
openssl req -newkey rsa:2048 -nodes -keyout ca.key -x509 -days 3654 -out ca.crt
С помощью параметра -days мы устанавливаем долгий строк действия - десять лет. Программа запросит стандартные данные, которые используются при создании сертификатов. Эти данные будут выводится в браузере при просмотре информации о центре сертификации если вы будете использовать подписанные сертификаты для HTTPS. В поле Common Name можно указать имя вашей организации:
Осталось подписать наш сертификат, созданный ранее:
openssl x509 -req -in ~/certs/domain.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out domain.crt -days 365
Готово, теперь наш сертификат подписан. Но теперь, чтобы браузеры ему доверяли нужно добавить сертификат CA в список доверенных сертификатов браузера.
Подпись сертификатов с помощью EasyRSA
Создание центра сертификации можно немного упростить. Существует набор скриптов под названием EasyRSA, который позволяет инициализировать центр сертификации, а также подписывать и отзывать сертификаты. Сначала установите пакет easy-rsa из официальных репозиториев:
sudo apt install easy-rsa
Далее нужно создать папку в которой будут находится файлы центра сертификации. Например, в домашней папке:
mkdir ~/easy-rsa-ca
После этого скопируйте файлы из /usr/share/easy-rsa/ в эту папку:
cp -R /usr/share/easy-rsa/* ~/easy-rsa-ca
Дальше перейдите в неё и инициализируйте центр сертификации:
cd ~/easy-rsa-ca
./easyrsa init-pki
Прежде чем вы сможете создать сертификат, необходимо создать файл vars и в нём прописать информацию о центре сертификации. Например:
vi ./vars
Первые 7 параметров аналогичны тем, что заполняются при создании запроса на подписание сертификата. Параметр EASYRSA_ALGO позволяет настроить алгоритм шифрования, можно использовать стандартный RSA или алгоритм на основе эллиптических кривых ES. Последний параметр - это формат подписи сертификатов. После этого можно создать сертификат CA:
./easyrsa build-ca
Для корневого сертификата необходимо задать пароль. Если этого не сделать, сертификат не будет создан:
А в Common Name можно указать название центра сертификации, которое будет отображаться в браузере в информации о том кем подписан сертификат:
После этого можно переходить к подписи CSR. Например, давайте подпишем domain.csr, который был создан ранее. Сначала этот запрос надо импортировать. Для этого используйте такую команду:
./easyrsa import-req ~/certs/domain-server.csr domain-server
В первом параметре нужно указать путь к фалу CSR, а во втором имя, с помощью которого вы будете взаимодействовать с сертификатом.
После этого вы можете подписать этот запрос используя имя, заданное при импорте:
./easyrsa sign-req server domain-server
Команде необходимо передать два параметра тип сертификата и имя запроса. Тип сертификата может быть server или client. Программа попросит подтвердить данные сертификата, наберите yes и нажмите Enter:
А затем нужно будет ввести пароль от корневого сертификата. После этого будет создан новый сертификат в папке pki/issued с расширением .crt.
Просмотр сертификатов
Сертификаты сохраняются в формате PEM, а это значит, что вы не сможете их открыть как текстовый файл и нужно использовать специальные команды для просмотра информации о них. Сначала смотрим содержимое CSR:
openssl req -text -noout -verify -in domain.csr
Смотрим содержимое сертификата в режиме обычного текста:
openssl x509 -text -noout -in domain.crt
Проверяем действительно ли сертификат подписан нужным CA:
openssl verify -verbose -CAfile ~/easy-rsa-ca/pki/ca.crt pki/issued/domain-server.crt
Просмотр закрытого ключа:
openssl rsa -check -in domain.key
Чтобы проверить связаны ли между собой закрытый ключ, сертификат и открытый ключ (запрос на подпись) можно подсчитать сумы md5 для этих ключей, если значения совпадут, то есть вероятность что это ключи из одной пары:
openssl rsa -noout -modulus -in ~/certs/domain.key | openssl md5
openssl x509 -noout -modulus -in ~/certs/domain.crt | openssl md5
openssl req -noout -modulus -in ~/certs/domain.csr | openssl md5
Как использовать сертификат
Не зависимо от того какой способ создания сертификата OpenSSL вы выбрали у вас будет два файла. Это файл закрытого ключа с расширением .key и файл сертификата с расширение .crt. В данном примере это:
- domain.key
- domain-server.crt
Также вам может понадобится сертификат fullchain. Обычно этот файл содержит сам подписанный сертификат и сертификаты промежуточных центров сертификации. Но в случае если вы подписываете сертификат своим центром сертификации, промежуточных сертификатов у вас нет, а значит в качестве fullchain можно использовать сам подписанный сертификат.
Если вы хотите подключить ваши сертификаты к Apache, используйте такие директивы в файле виртуального хоста:
vi /etc/apache2/sites-enabled/000-default.conf
Для Nginx директивы подключения сертификатов выглядят похожим образом:
Их нужно добавить внутри блока server для сайта на котором вы хотите настроить HTTPS.
Выводы
В этой статье мы рассмотрели как выполняется генерация сертификата openssl, какие бывают сертификаты, ключи и как все эти понятия связаны между собой. Это очень сложная и обширная тема, и недостаточно одной статьи чтобы все охватить, но, надеюсь, что теперь вам намного понятнее как это все работает.
Подскажите как правильно создать сертификат для русскоязычного названия домена? Например для "мой_город".рф". Спасибо.
На шаге создания самоподписанного сертификата openssl для CA возникает ошибка:
Error Loading extension section x509_ca
Действительно, секции x509_ca в openssl.conf не нашел. Однако там есть секции ca, CA_default, v3_ca.
Можно какой-то из них использовать? Или лучше найти пример секции x509_ca и добавить в openssl.conf?
Спасибо!
По ошибке "Error Loading extension section x509_ca"
Для CentOS 7 заменить в команде - -extensions x509_ca на -extensions v3_req
Коллеги, нужна помочь, как я могу сгенерировать сертификат с определенным серийным номером.
Это бесполезная статья! Так как генерация ключа должна происходить для определённого домена, а название "domain" - это просто название файла с шифром, - о чём в тексте ни словом ни духом. Далее. Успешность генерации ключей/сертификатов также зависит от конфигурационного файла, который указан в переменной окружения OPENSSL_CONF. В конечном счёте главными для работы являются полученные файлы .crt и .key, которые можно использовать для работы по https соединению с доменом. Статья мне не помогла.
openssl ca -extensions x509_client -in docs.wantu.csr -out docs.wantu.crt
Using configuration from /usr/lib/ssl/openssl.cnf
Can't open ./etc/ca/private/cakey.pem for reading, No such file or directory
140046306350400:error:02001002:system library:fopen:No such file or directory:../crypto/bio/bss_file.c:69:fopen('./etc/ca/private/cakey.pem','r')
140046306350400:error:2006D080:BIO routines:BIO_new_file:no such file:../crypto/bio/bss_file.c:76:
unable to load CA private key
А без сертификатов прямо не повысить безопасность?
Я правда не дочитал всё, но по первой главе "что такое сертификаты?" не до конца разобрался в принципе. Какое он там сообщение зашифровывает и зачем?
Клиент заходит на сайт и его действия шифруются сертификатом? И проверяются владельцем сайта?
Разве во время аутентификации нельзя всеми возможными crypt/encrypt с солью и ключами устанавливать пароль на личные кабинеты и тд тп и никто не взломает?
openssl genrsa -out CA.key 4096
openssl req -x509 -new -key CA.key -days 365 -out CA.crt
openssl genrsa -out web-server.key 4096
openssl req -new -key web-server.key -out web-server.csr
openssl x509 -req -in web-server.csr -CA CA.crt -CAkey CA.key -CAcreateserial -out web-server.crt -days 365
"..Так как генерация ключа должна происходить для определённого домена, а название "domain" - это просто название файла с шифром, - о чём в тексте ни словом ни духом. "- в статье не написано, но в процессе генерации оно спрашивает "Common Name (e.g. server FQDN or YOUR name) []:" - FQDN это как раз и есть название сайта, для которого создается серт.
"...А без сертификатов прямо не повысить безопасность?" - например, SQUID-у нужен сертификат для работы с SSL. Или если ваш сайт работает с камерой и/или микрофоном - тоже обмен идет по SSL.
при подписи запроса на сертификат openssl "теряет" поля SAN(aubject alt names).
Есть ли возможность не терять эти поля, не перезабивая их вручную при подписании сертификата?