Skip to content

Latest commit

 

History

History
310 lines (252 loc) · 22.1 KB

create_SSL_TLS_certificates_rus.md

File metadata and controls

310 lines (252 loc) · 22.1 KB

Как создать и подписать SSL/TLS сертификаты

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

# 1. Генерируем приватный ключ CA и самоподписанный сертификат

# 2. Генерируем приватный ключ веб-сервера и запрос на подпись сертификата (CSR)

# 3. Используем приватный ключ CA, чтобы подписать CSR веб-сервера и получить обратно подписанный сертификат

Для этого нам нужно будет установить openssl. Если вы используете Mac ОС, то скорее всего ничего делать не нужно. Попробуйте запустить openssl version, чтобы узнать, какая версия стоит в вашей системе. В моём случае — это LibreSSL версии 2.8.3. Давайте откроем браузер и перейдём на сайт libressl.org. Документация к команде openssl доступна по ссылке.

Генерируем приватный ключ и сертификат CA

Первая команда, которую мы собираемся использовать, - req, сокращение от request. Эта команда позволяет создать и обработать запрос на сертификат. Её также можно использовать для генерации самоподписанного сертификата CA, что нам и нужно на первом этапе. Параметр -x509 используется, чтобы указать openssl создавать самоподписанный сертификат, а не запрос на подпись. Возможно вы не знали, но X509 - это просто название стандартного формата сертификата публичного ключа. Вы можете нажать на замок рядом с названием любого HTTPS сайта, чтобы увидеть его сертификат в формате X509. Теперь вернемся в терминал и выполним:

openssl req -x509 -newkey rsa:4096 -days 365 -keyout ca-key.pem -out ca-cert.pem

Параметр -newkey rsa:4096 сообщает openssl, что нужно создать новый приватный ключ с 4096-битным RSA ключом одновременно с сертификатом. Поскольку мы используем параметр -x509, она будет выводить сертификат вместо запроса. Следующий параметр -days 365 определяет количество дней, в течение которых сертификат действителен. Затем мы используем параметр -keyout, чтобы openssl записал созданный приватный ключ в файл ca-key.pem и наконец -out указывает сохранить сертификат в ca-cert.pem. Когда мы нажимаем Enter, openssl начнёт генерировать приватный ключ. Как только он будет создан, нас попросят ввести пароль, который будет использоваться для шифрования приватного ключа перед его записью в PEM файл. Почему он шифруется? Потому что если каким-то образом файл приватного ключа будет взломан, хакер не сможет использовать его для каких-либо целей, не зная пароля для его расшифровки. Затем openssl запросит у нас некоторые персональные данные для создания сертификата. Сначала код страны, затем название штата или провинции, города, организации, подразделения, общее или доменное имя, адрес электронной почты. На этом всё! Файлы сертификата и приватного ключа будет успешно созданы. Если мы выполним команду cat для файла приватного ключа, то увидим, что он начинается с "ENCRYPTED PRIVATE KEY":

ca-key.pem

-----BEGIN ENCRYPTED PRIVATE KEY-----

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

openssl x509 -in ca-cert.pem -noout -text

Здесь мы используем параметр -in, чтобы передать название файла сертификата CA, -noout указывает, что не надо выводить исходно закодированное значение. Мы хотим отобразить информацию в удобном для чтения текстовом формате, поэтому давайте воспользуемся параметром -text и нажмем Enter. Теперь мы видим все информацию о сертификате, такую как версия, серийный номер. Издатель (issuer) и получатель (subject) в этом случае совпадают, потому что это самоподписанный сертификат. Затем выводится публичный RSA ключ и подпись. Я скопирую эту команду и сохраню её в скрипте gen.sh. С помощью этого скрипта я хочу автоматизировать процесс создания ключей и сертификатов.

# 1. Генерируем приватный ключ CA и самоподписанный сертификат
openssl req -x509 -newkey rsa:4096 -days 365 -keyout ca-key.pem -out ca-cert.pem

echo "CA's self-signed certificate"
openssl x509 -in ca-cert.pem -noout -text

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

openssl req -x509 -newkey rsa:4096 -days 365 -keyout ca-key.pem -out ca-cert.pem -subj "/C=FR/ST=Occitanie/L=Toulouse/O=Tech School/OU=Education/CN=*.techschool.guru/[email protected]"

Теперь давайте добавим команду, удаляющую все pem файлы, в начало этого скрипта, затем выполним gen.sh в терминале. Нас по-прежнему просят ввести пароль, но не требуют персональных данных, поскольку мы их уже указали в параметре subj. Здорово!

Генерируем приватный ключ и CSR веб-сервера

Следующий этап — создание приватного ключа и CSR для нашего веб-сервера. Команда практически не отличается от той, которую мы использовали на первом этапе. Но в этот раз мы не хотим сами подписывать его, поэтому должны удалить параметр -x509. Ключ -days тоже нужно удалить, поскольку мы создаём не сертификат, а CSR. Затем изменим название генерируемого ключа на server-key.pem. Создаваемый файл сертификата должен называться server-req.pem, поскольку мы создаем запрос на подпись сертификата. Теперь мы должны изменить всю информацию в параметре subj на информацию о нашем веб-сервере. Давайте выполним команду.

openssl req -newkey rsa:4096 -keyout server-key.pem -out server-req.pem -subj "/C=FR/ST=Ile de France/L=Paris/O=PC Book/OU=Computer/CN=*.pcbook.com/[email protected]"

Введите пароль для шифрования приватного ключа веб-сервера. После этого файлы будут успешно сгенерированы.

В этот раз файл server-req.pem начинается со строки CERTIFICATE REQUEST, а не CERTIFICATE как в ca-cert.pem. Таким образом, был создан не сертификат, а запрос на подпись сертификата.

-----BEGIN CERTIFICATE REQUEST-----
MIIE2DCCAsACAQAwgZIxCzAJBgNVBAYTAkZSMRYwFAYDVQQIDA1JbGUgZGUgRnJh
bmNlMQ4wDAYDVQQHDAVQ...pWofr2eOeBQ4Q=
-----END CERTIFICATE REQUEST-----
# ...

# 2. Генерируем приватный ключ веб-сервера и запрос на подпись сертификата (CSR)
openssl req -newkey rsa:4096 -keyout server-key.pem -out server-req.pem -subj "/C=FR/ST=Ile de France/L=Paris/O=PC Book/OU=Computer/CN=*.pcbook.com/[email protected]"

# ...

Теперь перейдём к третьему этапу и подпишем этот запрос.

Подписываем запрос на выдачу сертификата веб-серверу

Для этого мы будем использовать ту же команду x509, которую применяли для просмотра сертификата ранее. Откроем терминал и выполним:

openssl x509 -req -in server-req.pem -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem

В этой команде мы воспользуемся параметром -req, чтобы сообщить openssl, что мы собираемся передать запрос на подпись сертификата. Вводим ключ -in, за которым следует имя файла с запросом: server-req.pem. Затем используем ключ -CA для передачи файла сертификата CA: ca-cert.pem и -CAkey - для приватного ключа CA: ca-key.pem. Далее следует ещё один важный параметр - -CAcreateserial. Обычно центр сертификации должен гарантировать, что каждый сертификат, который он подписывает, имеет уникальный серийный номер. Благодаря этому ключу будет создан файл, если он не существует содержащий следующий серийный номер. Наконец, мы используем параметр -out, чтобы указать файл, в который будет сохраняться сертификат. Как видите, поскольку приватный ключ CA зашифрован, OpenSSL запрашивает пароль для расшифровки, прежде чем воспользоваться им для подписи сертификата. Это контрмера на случай взлома приватного ключа CA. После этого мы получили подписанный сертификат для нашего веб-сервера. Давайте выведем его в текстовом формате.

openssl x509 -in server-cert.pem -noout -text

It has its unique serial number 0xb141e873fd7b8567. Такой же серийный номер будет содержаться в файле ca-cert.srl.

B141E873FD7B8567

Раздел Issuer содержит информацию о центре сертификации, которым в данном случае является Tech School. По умолчанию сертификат действителен 30 дней. Мы можем изменить это, добавив параметр -days к команде подписи.

openssl x509 -req -in server-req.pem -days 60 -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem

Теперь срок действия изменен на 60 дней.

Если вы помните сертификат Youtube, который мы видели на предыдущей лекции, этот сертификат используется для многих веб-сайтов Google с разными доменными именами. Это возможность можно реализовать для нашего сервера, указав расширение Subject Alternative Name (Альтернативные имена субъектов) при подписывании запроса на выдачу сертификата. Здесь используется ключ -extfile, который позволяет указать файл, содержащий расширения. Формат этого конфигурационного файла приведен на этой странице. Найдите на странице с помощью поиска "subject alternative name".

В качестве альтернативного имени мы можем использовать различные параметры, например, email, DNS или IP. Я создам новый файл со следующим содержимым:

subjectAltName=DNS:*.pcbook.com,DNS:*.pcbook.org,IP:0.0.0.0

Здесь я использовал DNS для двух доменных имен: *.pcbook.com и *.pcbook.org, а также IP 0.0.0.0, который будет использоваться при разработке на локальной машине. Теперь в команду для подписи сертификата добавим ключ -extfile и передадим туда имя файла, содержащего настройки для расширений:

openssl x509 -req -in server-req.pem -days 60 -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile server-ext.cnf

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

Certificate:
    ...
    Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=FR, ST=Occitanie, L=Toulouse, O=Tech School, OU=Education, CN=*.techschool.guru/[email protected]
        Validity
            Not Before: Apr 10 18:17:05 2020 GMT
            Not After : Jun  9 18:17:05 2020 GMT
        Subject: C=FR, ST=Ile de France, L=Paris, O=PC Book, OU=Computer, CN=*.pcbook.com/[email protected]
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (4096 bit)
                Modulus:
                    00:cb:e2:2b:c3:68:...
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Alternative Name: 
                DNS:*.pcbook.com, DNS:*.pcbook.org, IP Address:0.0.0.0
    Signature Algorithm: sha1WithRSAEncryption
         5e:67:4d:f7:91:89:fc:...

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

# ...

# 3. Используем приватный ключ CA, чтобы подписать CSR веб-сервера и получить обратно подписанный сертификат
openssl x509 -req -in server-req.pem -days 60 -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile server-ext.cnf

echo "Server's self-signed certificate"
openssl x509 -in ca-cert.pem -noout -text

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

Для этого добавим ключ -nodes к команде openssl req следующим образом:

# 1. Генерируем приватный ключ CA и самоподписанный сертификат
openssl req -x509 -newkey rsa:4096 -days 365 -nodes -keyout ca-key.pem -out ca-cert.pem -subj "/C=FR/ST=Occitanie/L=Toulouse/O=Tech School/OU=Education/CN=*.techschool.guru/[email protected]"

echo "CA's self-signed certificate"
openssl x509 -in ca-cert.pem -noout -text

# 2. Генерируем приватный ключ веб-сервера и запрос на подпись сертификата (CSR)
openssl req -newkey rsa:4096 -nodes -keyout server-key.pem -out server-req.pem -subj "/C=FR/ST=Ile de France/L=Paris/O=PC Book/OU=Computer/CN=*.pcbook.com/[email protected]"

# 3. Используем приватный ключ CA, чтобы подписать CSR веб-сервера и получить обратно подписанный сертификат
openssl x509 -req -in server-req.pem -days 60 -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile server-ext.cnf

echo "Server's self-signed certificate"
openssl x509 -in ca-cert.pem -noout -text

Теперь если я снова запущу gen.sh, то он больше не будет запрашивать пароли. Откройте файлы с приватными ключами и вы увидите, что они начинаются с PRIVATE KEY, а не с ENCRYPTED PRIVATE KEY как раньше.

-----BEGIN PRIVATE KEY-----
MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQDL4ivDaIzDM3my
VDzT2Mw5R9bicXS...AxAt2Ldmc4=
-----END PRIVATE KEY-----

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

Прежде чем мы закончим, я покажу вам как проверить действителен ли сертификат или нет. Мы можем сделать это с помощью команды openssl verify:

openssl verify -CAfile ca-cert.pem server-cert.pem

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

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