Получаем сертификат от Let’s Encrypt
Итак, я считаю, что вы настроили почтовый сервер по предложенной выше ссылке. Значит, у вас установлен веб сервер Apache, а так же все в порядке с dns записями. Сертификатов мы получим сразу два. Для доменных имен:
- mail.site.ru — имя почтового сервера, этот сертификат будут использовать postfix и apache
- webmail.site.ru — домен для web интерфейса почты, будет использовать веб сервер
Для настройки получения сертификатов let’s encrypt и настройки apache, нам нужно будет установить несколько пакетов. Напоминаю, что речь идет про Centos 8. В других системах настройка будет аналогичной, только имена пакетов могут отличаться.
# dnf install certbot python3-certbot-apache mod_ssl
Пакеты эти живут в репозитории epel, так что если он еще не подключен, подключите.
# dnf install epel-release
Дальше нам нужно добавить 2 виртуальных домена в настройки apache. Для этого создаем 2 конфига в директории /etc/httpd/conf.d/.
1. mail.site.ru.conf
<VirtualHost *:443> ServerName mail.site.ru DocumentRoot /var/www/mail.site.ru/ <Directory /var/www/mail.site.ru/> Options -Indexes +FollowSymLinks AllowOverride All </Directory> ErrorLog /var/log/httpd/mail.site.ru-error.log CustomLog /var/log/httpd/mail.site.ru-access.log combined </VirtualHost> <VirtualHost *:80> ServerName mail.site.ru DocumentRoot /var/www/mail.site.ru/ <Directory /var/www/mail.site.ru/> Options -Indexes +FollowSymLinks AllowOverride All </Directory> ErrorLog /var/log/httpd/mail.site.ru-error.log CustomLog /var/log/httpd/mail.site.ru-access.log combined </VirtualHost>
2. webmail.site.ru.conf
<VirtualHost *:443> ServerName webmail.site.ru DocumentRoot /var/www/webmail.site.ru/ <Directory /var/www/webmail.site.ru/> Options -Indexes +FollowSymLinks AllowOverride All </Directory> ErrorLog /var/log/httpd/webmail.site.ru-error.log CustomLog /var/log/httpd/webmail.site.ru-access.log combined </VirtualHost> <VirtualHost *:80> ServerName webmail.site.ru DocumentRoot /var/www/webmail.site.ru/ <Directory /var/www/webmail.site.ru/> Options -Indexes +FollowSymLinks AllowOverride All </Directory> ErrorLog /var/log/httpd/webmail.site.ru-error.log CustomLog /var/log/httpd/webmail.site.ru-access.log combined </VirtualHost>
По сути конфиги идентичные, только названия доменов разные. Теперь можно проверить конфигурацию apache и перезапустить его.
# apachectl -t # apachectl reload
Если увидите ошибку:
AH00526: Syntax error on line 85 of /etc/httpd/conf.d/ssl.conf: SSLCertificateFile: file '/etc/pki/tls/certs/localhost.crt' does not exist or is empty
Просто удалите конфиг /etc/httpd/conf.d/ssl.conf. Он нам не нужен.
Если нет ошибок, то можно запускать certbot и получать сертификаты. Делается это очень просто.
# certbot --apache
Если все прошло без ошибок, то вы увидите в директории /etc/letsencrypt/live две папки с сертификатами для каждого из доменов.
Так же certbot автоматически добавит в конфигурации виртуальных хостов apache несколько дополнительных параметров.
<VirtualHost *:443> ServerName webmail.site.ru DocumentRoot /var/www/webmail.site.ru/ <Directory /var/www/webmail.site.ru/> Options -Indexes +FollowSymLinks AllowOverride All </Directory> ErrorLog /var/log/httpd/webmail.site.ru-error.log CustomLog /var/log/httpd/webmail.site.ru-access.log combined SSLCertificateFile /etc/letsencrypt/live/mail.site.ru/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/mail.site.ru/privkey.pem Include /etc/letsencrypt/options-ssl-apache.conf </VirtualHost> <VirtualHost *:80> ServerName webmail.site.ru DocumentRoot /var/www/webmail.site.ru/ <Directory /var/www/webmail.site.ru/> Options -Indexes +FollowSymLinks AllowOverride All </Directory> ErrorLog /var/log/httpd/webmail.site.ru-error.log CustomLog /var/log/httpd/webmail.site.ru-access.log combined RewriteEngine on RewriteCond %{SERVER_NAME} =mail.site.ru RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} </VirtualHost>
В этот виртуальный хост установите веб почту, если вам она нужна.
Что в TLS 1.3?
- Плохие шифры удалены, остались только хорошие. Инициализировать сессию TLS 1.3 на плохих шифрах не получится. Всё дело в новых cipher suites: тут и другие алгоритмы обмена сеансовых ключей, и так называемый HMAC – не будем углубляться в подробности, потому что Патрик устал. Вкратце: раньше подпись каждого TLS-пакета шла отдельно. На это были атаки, потому что было известно, какой там контент находится. Сейчас ее запихали вовнутрь (режим AEAD), и в TLS 1.3 по-другому быть не может, соответственно, мы избавились от таких атак.
- Handshake стал короче – нет старых сообщений, нет старых расширений, нет возможности по каким-то странным штукам обменяться ключиками. То есть, он тупо короче количественно – даже самый полный TLS 1.3 handshake короче, чем в TLS 1.2.
- Переход на шифрованный канал происходит почти что сразу. Для этого используются разные ключики: да, пока не договорились о хороших ключиках, оптимальных, мы используем какие попало, но канал уже шифрованный. То есть hello – hello и пошло всё зашифрованное. Из-за этого сложнее всё это ломать.
- Всё регламентировано, больше не надо пытаться менять размеры пакетов, забивая их ноликами, чтобы сложнее было расшифровывать.
- Своя пара ключей на каждую сеансовую фазу. Сеансовые ключи меняются: пока мы ни о чем не договорились – они такие, договорились о более крутых – они более крутые, сертификаты проверили и всё хорошо – еще другие ключи. В итоге их много, они усложняются и очень трудно это всё поломать. Еще одна важная вещь, почему это быстрее: Early Data (она же 0-RTT, Zero Round Trip Time) – это когда у тебя в TLS-handshake посылается полезная инфа – ну например GET-запрос. То есть нет такого, что поговорили-поговорили и только потом посылаем что-то отдельным потоком. Сразу же в handshake идет запрос. Как только сервер его получил, он начинает его обрабатывать, отдает клиенту свои данные, сертификат и пока клиент проверяет, сервер уже готов отдать. И может даже в TLS-handshake и отдать иногда.
- Есть pre-shared key, то есть клиент с сервером могут договориться и сохранить сеансовые ключи для последующих соединений. И, соответственно, когда происходит handshake таких вот договорившихся клиентов, на этап выбора ключей время не тратится. Долго объяснять, как это сделано криптографически, но тех атак, которые были на Session ID, вот в этом месте сейчас нет (что хорошо). Всё стало безопаснее и быстрее.
6 ответов
12
Интересно, как номер порта меняет средний поток:
Это заставляет меня думать, что где-то между клиентом и сервером существует неправильное устройство NAT, устройство с очень кратковременными записями таблицы состояний, которое меняет номер порта источника, который он применяет к установленному потоку клиента, вызывая сервер полагает, что две короткоживущие коммуникации продолжаются, а не один непрерывный.
Такие устройства обычно делают это только с UDP, поэтому я посоветовал вам подтвердить, что вы используете UDP, и вместо этого попробуйте TCP. Это вы сделали и обнаружили, что он исправляет проблему. Следующий шаг — выявить плохое устройство NAT, нанести ему ударный молот и заменить его на тот, который не делает кардинальную ошибку, предполагая, что все сообщения UDP являются эфемерными; но вы указали, что довольны переходом на TCP в качестве обходного пути, и поэтому дело завершено.
2
Это одна из самых распространенных ошибок при настройке Openvpn, и для этого есть элемент часто задаваемых вопросов. Я приведу это здесь:
Весьма вероятно, что любой из них вызывает такую же проблему и в вашем случае. Поэтому просто перейдите по списку один за другим, чтобы разрешить его.
Ссылка:
1
У меня была такая же ошибка, и ни один совет не помог, все было в порядке: IP-адреса, порты, брандмауэр, все. Прошел безумие на 2 часа.
Решение заключалось в том, чтобы изменить протокол с UDP на TCP в конфигурацию клиента (по-видимому, я отключил UDP уже давно).
Надеюсь, это поможет кому-то:)
1
Я получал тайм-ауты согласования ключей TLS, подобные этому. Но в моем случае я понял, что удаленная ссылка была локальным IP-адресом.
VPN на нашем брандмауэре pfSense ошибочно поместился в интерфейс LAN вместо интерфейса WAN, и поэтому экспортированная конфигурация была настроена на попытку подключения к IP-адресу локальной сети брандмауэра — который никогда не работал с клиентом естественно, находясь в другой локальной сети.
Я думаю, что основные выходы из этого:
-
Получение тайм-аута согласования ключей не обязательно означает, что вы даже подключены к VPN-серверу.
Итак, на этом этапе все равно стоит проверить, что вы действительно подключаетесь к нужному месту, и нет правил брандмауэра, блокирующих соединение и т. д. Особенно если ваша конфигурация была автоматически сгенерирована.
-
Убедитесь, что ваш VPN-сервер прослушивает правый интерфейс
(Конечно, это одна из нескольких неправильных конфигураций на стороне сервера, которые могут возникнуть, например, правила брандмауэра, неправильный номер порта, смешение TCP и UDP и т. д.)
Обратите внимание, что вы можете получить ошибку согласования ключа TLS без успешного подключения к серверу OpenVPN — или даже успешно подключиться к чему-либо вообще!
Я изменил конфигурацию VPN для подключения к localhost, на порт, который не прослушивал ничего:
OpenVPN 2.4.6 x86_64-w64-mingw32 построена 26 апреля 2018 г. Windows версии 6.2 (Windows 8 или выше) 64 бит версии библиотеки: OpenSSL 1.1.0h 27 марта 2018 года, LZO 2.10 TCP /UDP: сохранение недавно использованного удаленного адреса: 127.0.0.1:12345 UDP-ссылка локальная (связанная): : 0 Удаленный UDP-канал: 127.0.0.1:12345 Ошибка TLS: согласование ключа TLS не произошло в течение 60 секунд (проверьте сетевое подключение) Ошибка TLS: сбой связи TLS SIGUSR1 , перезапуск процесса ...
Ошибка может усыпить вас ложным чувством, что вы разговариваете с VPN-сервером.
Сначала вы можете получить запрос на учетные данные, но ничего за пределами вашего компьютера не попросил их.
Я столкнулся с этой ошибкой в AWS, где OpenVPN был установлен на сервере с открытым IP-адресом, но в экземпляре, который находился в частной подсети, то есть в подсети, у которой не было маршрута к интернет-шлюзу.
Как только я развернул OpenVPN на сервере в общедоступной подсети, все это прекрасно работало:)
В общедоступных /частных подсетях в AWS: https: //docs .aws.amazon.com /VPC /последний /UserGuide /VPC_Subnets.html
Аутентификация в TLS-рукопожатии
Исторически двумя основными вариантами обмена ключами являются RSA и Диффи-Хеллман (DH), в наши дни DH часто ассоциируется с эллиптическими кривыми (ECDH). Несмотря на некоторые основные сходства, между этими двумя подходами к обмену ключами есть фундаментальные различия.
Иными словами, TLS-рукопожатие RSA отличается от TLS-рукопожатия ECDH.
RSA использует простую факторизацию и модульную арифметику. Большие простые числа требуют много ресурсов процессора при вычислениях и их сложно подобрать.
Диффи-Хеллмана иногда называют экспоненциальным обменом ключами, что указывает на возведение в степень (в дополнение к модульной арифметике), но на самом деле сам DH вообще ничего не шифрует и не дешифрует. Поэтому называть его «методом шифрования» вместо «математического обоснования» может быть немного неверно.
Небольшой экскурс в историю может пояснить этот момент.
Ещё в 1976 году Уитфилд Диффи и Мартин Хеллман создали протокол обмена ключами, основанный на работе Ральфа Меркля, чьё имя, по мнению обоих, должно также присутствовать в названии протокола.
Они пытались решить проблему безопасного обмена ключами по незащищённому каналу, даже если злоумышленник прослушивает его. У них получилось, но был один серьёзный недостаток: обмен ключами DH не включал в себя проверку подлинности, поэтому не было возможности проверить сторону на другом конце соединения.
Это можно считать рождением криптографии с открытым ключом и ИОК. Вскоре после того, как Диффи и Хеллман представили свой протокол обмена ключами, были завершены самые ранние версии криптосистемы RSA. Диффи и Хеллман создали концепцию шифрования с открытым ключом, но ещё не придумали саму функцию одностороннего шифрования.
Именно Рон Ривест (R в RSA) создал концепцию, которая в итоге стала криптосистемой RSA.
Во многих отношениях RSA является духовным преемником DH. Он осуществляет:
- генерацию ключей;
- обмен ключами;
- шифрование;
- дешифрование.
Таким образом, RSA является более функциональным алгоритмом, который может обрабатывать как обмен ключами, так и цифровые подписи, то есть производить аутентификацию в дополнение к безопасному обмену ключами. Поэтому у RSA ключи больше: должна быть обеспечена достаточная безопасность для цифровой подписи.
В то время как RSA осуществляет аутентификацию и обмен ключами, Диффи-Хеллман только облегчает обмен ключами. Существует четыре распространённых варианта семейства DH:
- Диффи-Хеллман (DH);
- эфемерный (краткосрочный) Диффи-Хеллман (DHE);
- эллиптическая кривая Диффи-Хеллмана (ECDH);
- эллиптическая кривая эфемерного Диффи-Хеллмана (ECDHE).
Опять же, Диффи-Хеллман сам по себе ничего не аутентифицирует. Его нужно использовать в паре с алгоритмом цифровой подписи. Так, например, если вы использовали ECDH или ECDHE, большинство шифронаборов будут сопряжены с алгоритмом цифровой подписи эллиптической кривой (ECDSA) или RSA.
Откуда берутся сертификаты?
Еще совсем недавно было всего 2 способа заполучить X.509 сертификат, но времена меняются и с недавнего времени есть и третий путь.
- Создать свой собственный сертификат и самому же его подписать. Плюсы — это бесплатно, минусы — сертификат будет принят лишь вами и, в лучшем случае, вашей организацией.
- Приобрести сертификат в УЦ. Это будет стоить денег в зависимости от различных его характеристик и возможностей, указанных выше.
- Получить бесплатный сертификат LetsEncrypt, доступны только самые простые DV сертификаты.
Для первого сценария достаточно пары команд и чтобы 2 раза не вставать создадим сертификат с алгоритмом эллиптических кривых. Первым шагом нужно создать закрытый ключ. Считается, что шифрование с алгоритмом эллиптических кривых дает больший выхлоп, если измерять в тактах CPU, либо байтах длины ключа. Поддержка ECC не определена однозначно в TLS < 1.2.
Далее, создает CSR — запрос на подписание сертификата.
И подписываем.
Результат можно посмотреть командой:
имеет огромное количество опций и команд. Man страница не очень полезна, справочник удобнее использовать так:
Ровно то же самое можно сделать с помощью утилиты .
Следует серия вопросов, чтобы было чем запомнить поля и
Конвертируем связку ключей из проприетарного формата в PKCS12.
Смотрим на результат:
Значению соответствует определение ASN.1, согласно RFC 3280 оно всегда . Точно так же можно узнать смысл и возможные значения других , которые присутствуют в сертификате X.509.
LetsEncrypt
Можно бесплатно получить X.509 сертификат LetsEncrypt и для этого не нужно даже заходить на вебсайт, достаточно установить .
Серверный сертификат
Для подписи сертификата для сервера нам нужно выполнить следующие действия:
1) Сгенерировать ключ
2) Сгенерировать запрос на подпись
3) Отправить CSR-файл в авторизационный центр или подписать самостоятельно
В серверный сертификат может включаться цепочка сертификатов, которыми подписан сертификат сервера, но ее можно также хранить в отдельном файле. В принципе, выглядит всё примерно так же, как и при генерации корневого сертификата
$ openssl genrsa -out server.key 2048 Generating RSA private key, 2048 bit long modulus ...................................................................................+++ ..........................+++ e is 65537 (0x10001) $ openssl req -new -key server.key -out server.csr 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) :RU State or Province Name (full name) :N/A Locality Name (eg, city) []:Saint-Petersburg Organization Name (eg, company) :My Company Organizational Unit Name (eg, section) []:IT Service Common Name (e.g. server FQDN or YOUR name) []:www.mycompany.com Email Address []:[email protected] Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: $ openssl x509 -req -in server.csr -CA root.pem -CAkey root.key -CAcreateserial -out server.pem -days 365 Signature ok subject=/C=RU/ST=N/A/L=Saint-Petersburg/O=My Company/OU=IT Service/CN=www.mycompany.com/[email protected] Getting CA Private Key $ openssl x509 -noout -issuer -subject -enddate -in server.pem issuer= /C=RU/ST=N/A/L=Saint-Petersburg/O=My Company/OU=IT Service/CN=My Company Root Certificate/[email protected] subject= /C=RU/ST=N/A/L=Saint-Petersburg/O=My Company/OU=IT Service/CN=www.mycompany.com/[email protected] notAfter=Jan 25 12:22:32 2016 GMT
Таким образом сертификат сервера подписан и мы будем знать, какой организацией выдан этот сертификат. После подписи готовый сертификат можно использовать по назначению, например, установить на веб-сервер.
«Прослушка» информации о сертификате при помощи openssl
Для проверки взаимодействия сервера с клиентскими сертификатами можно проверить, устанавливается ли соединение с использованием TLS/SSL.
На стороне сервера запускаем прослушку порта при помощи openssl:
openssl s_server -accept 443 -cert server.pem -key server.key -state
На стороне клиента обращаемся к серверу, например, culr’ом:
curl -k https://127.0.0.1:443
В консоли со стороны сервера можно наблюдать процесс обмена информацией между сервером и клиентом.
Можно также использовать опции -verify и -Verify . Опция с маленькой буквы запрашивает у клиента сертификат, но он не обязан его предоставлять. С большой буквы — если сертификат не предоставлен, возникнет ошибка. Запустим прослушку со стороны сервера таким образом:
openssl s_server -accept 443 -cert server.pem -key server.key -state -Verify 3
Со стороны сервера ошибка выглядит так:
140203927217808:error:140890C7:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:peer did not return a certificate:s3_srvr.c:3287:
Со стороны клиента так:
curl: (35) error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure
Добавим с клиентской стороны сертификат и доменное имя (можно для проверки вписать в файл /etc/hosts имя хоста для адреса 127.0.0.1):
curl https://www.mycompany.com:443 --cacert root.pem --cert client.pem --key client.key
Теперь соединение пройдет успешно и можно устанавливать серверный сертификат на веб-сервер, клиентский отдать клиенту, и работать с ними.
Транспортные протоколы
- AH (authentication headers). Про AH я дальше говорить не буду, так как он не обеспечивает конфиденциальности данных и, насколько слышал, его сделали исключительно чтобы как-то «мириться» с законами некоторых стран в 1990-х об ограничениях использования шифрования. Шифрование настолько легковесно относительно всего остального, что не имеет смысла им жертвовать. Но почти везде, где упоминается ESP, также подразумевается и AH.
- ESP (encapsulating security payloads). ESP со временем немного эволюционировал и сейчас используется его ESPv3 версия, которая часто обратно совместима и не отличается от прошлой версии.
NAT-T
Обмен ключами RSA
Называть это обменом ключами RSA на самом деле неправильно. На самом деле это RSA-шифрование. RSA использует асимметричное шифрование для создания ключа сеанса. В отличие от DH, пара открытого/закрытого ключей играет большую роль.
Вот как это происходит:
- Клиент и сервер обмениваются двумя простыми числами (x и y), которые называют случайными числами.
- Клиент генерирует pre-master secret (a), а затем использует открытый ключ сервера для его шифрования и отправки на сервер.
- Сервер расшифровывает pre-master secret с помощью соответствующего закрытого ключа. Теперь обе стороны имеют все три входных переменных и смешивают их с некоторыми псевдослучайными функциями (PRF) для создания мастер-ключа.
- Обе стороны смешивают мастер-ключ с ещё большим количеством PRF и получают совпадающие сеансовые ключи.
Обмен ключами DH
Вот как работает ECDH:
- Клиент и сервер обмениваются двумя простыми числами (x и y), которые называют случайными числами.
- Одна сторона выбирает секретный номер, называемый pre-master secret (a), и вычисляет: xa mod y. Затем отправляет результат (A) другому участнику.
- Другая сторона делает то же самое, выбирая свой собственный pre-master secret (b) и вычисляет xb mod y, а затем отправляет обратно своё значение (B).
- Обе стороны заканчивают эту часть, принимая заданные значения и повторяя операцию. Один вычисляет ba mod y, другой вычисляет ab mod y.
Существует свойство показателей по модулю, которое говорит, что каждая сторона получит одно и то же значение, которое будет ключом, используемым для симметричного шифрования во время соединения.
Рукопожатие TLS 1.2 для DH
Теперь, когда мы узнали, чем DH отличается от RSA, посмотрим, как выглядит рукопожатие TLS 1.2 на основе DH.
Опять же, между этими двумя подходами существует множество сходств. Мы будем использовать ECDHE для обмена ключами и ECDSA для аутентификации.
- Как и в случае с RSA, клиент начинает с сообщения «Client Hello», которое включает в себя список шифронаборов, а также случайное число клиента.
- Сервер отвечает своим сообщением «Server Hello», которое включает в себя выбранный шифронабор и случайное число сервера.
- Сервер отправляет свой SSL-сертификат. Как и при TLS-рукопожатии RSA клиент выполнит серию проверок подлинности сертификата, но, поскольку сам DH не может аутентифицировать сервер, необходим дополнительный механизм.
- Чтобы провести аутентификацию, сервер берёт случайные числа клиента и сервера, а также параметр DH, который будет использоваться для вычисления сеансового ключа, и шифрует их с помощью своего закрытого ключа. Результат будет выполнять роль цифровой подписи: клиент использует открытый ключ для проверки подписи и того, что сервер является законным владельцем пары ключей, и ответит своим собственным параметром DH.
- Сервер завершает эту фазу сообщением «Server Hello Done».
- В отличие от RSA, клиенту не нужно отправлять pre-master secret на сервер с использованием асимметричного шифрования, вместо этого клиент и сервер используют параметры DH, которыми они обменялись ранее, чтобы получить pre-master secret. Затем каждый использует pre-master secret, который он только что рассчитал, для получения одинакового сеансового ключа.
- Клиент отправляет сообщение «Change Cipher Spec», чтобы сообщить другой стороне о своём переходе на шифрование.
- Клиент отправляет финальное сообщение «Finished», чтобы сообщить, что он завершил свою часть рукопожатия.
- Аналогично, сервер отправляет сообщение «Change Cipher Spec».
- Рукопожатие завершается сообщением «Finished» от сервера.
Аутентификация в рукопожатии TLS 1.2
Как было только что сказано, дополнительная функциональность RSA для аутентификации с помощью цифровых подписей требует больших ключей, устойчивых к атакам перебором. Размер этих ключей сильно увеличивает затраты на их вычисление, шифрование и дешифрование во время рукопожатия.
С другой стороны, если Диффи-Хеллман не выполняет аутентификацию, то что он делает? Как было сказано выше, DH часто используют совместно с криптографией на основе эллиптических кривых, чтобы обеспечить аутентификацию и обмен ключами.
Эллиптическая криптография (ECC) имеет гораздо меньшие размеры ключей, которые соответствуют эллиптической кривой, на которой они основаны. Для этого контекста есть пять подходящих кривых:
- 192 бит;
- 224 бита;
- 256 бит;
- 384 бит;
- 521 бит.
Но это не единственное различие между открытыми/закрытыми ключами ECC и ключами RSA. Они используются для двух совершенно разных целей во время рукопожатия TLS.
В RSA пара открытый/закрытый ключ используется как для проверки подлинности сервера, так и для обмена симметричным ключом сеанса. Фактически, именно успешное использование секретного ключа для расшифровки секрета (pre-master secret) аутентифицирует сервер.
С Диффи-Хеллманом пара открытый/закрытый ключ НЕ используется для обмена симметричным сеансовым ключом. Когда задействован Диффи-Хеллман, закрытый ключ фактически связан с прилагаемым алгоритмом подписи (ECDSA или RSA).
RSA-аутентификация
Процесс RSA-аутентификации связан с процессом обмена ключами. Точнее обмен ключами является частью процесса аутентификации.
Когда клиенту предоставляется SSL-сертификат сервера, он проверяет несколько показателей:
- цифровую подпись с использованием открытого ключа;
- цепочку сертификатов, чтобы убедиться, что сертификат происходит от одного из корневых сертификатов в хранилище доверенных сертификатов;
- срок действия, чтобы убедиться, что он не истёк;
- статус отзыва сертификата.
Если все эти проверки прошли, то проводится последний тест — клиент шифрует pre-master secret с помощью открытого ключа сервера и отправляет его. Любой сервер может попытаться выдать любой SSL/TLS-сертификат за свой. В конце концов, это общедоступные сертификаты. А так клиент может провести аутентификацию сервера, увидев закрытый ключ «в действии».
Таким образом, если сервер может расшифровать pre-master secret и использовать его для вычисления сессионного ключа, он получает доступ. Это подтверждает, что сервер является владельцем используемой пары из открытого и закрытого ключа.
DH-аутентификация
Когда используются Диффи-Хеллман и ECDSA/RSA, аутентификация и обмен ключами разворачиваются бок о бок. И это возвращает нас к ключам и вариантам их использования. Открытый/закрытый ключ RSA используется как для обмена ключами, так и для аутентификации. В DH + ECDSA/RSA асимметричная пара ключей используется только для этапа цифровой подписи или аутентификации.
Когда клиент получает сертификат, он всё ещё проводит стандартные проверки:
- проверяет подпись на сертификате,
- цепочку сертификатов,
- срок действия,
- статус отзыва.
Но владение закрытым ключом подтверждается по-другому. Во время обмена ключами TLS-рукопожатия (шаг 4) сервер использует свой закрытый ключ для шифрования случайного числа клиента и сервера, а также свой DH-параметр. Он действует как цифровая подпись сервера, и клиент может использовать связанный открытый ключ для проверки, что сервер является законным владельцем пары ключей.
Издержки TLS-рукопожатия
Исторически одна из претензий к SSL/TLS заключалась в том, что он перегружал серверы дополнительными издержками. Это повлияло на ныне несуществующее представление, что HTTPS медленнее, чем HTTP.
Рукопожатия до TLS 1.2 требовали много ресурсов и в больших масштабах могли серьёзно нагрузить сервер. Даже рукопожатия TLS 1.2 могут замедлить работу, если их происходит много в один момент времени. Аутентификация, шифрование и дешифрование — дорогие процессы.
На небольших веб-сайтах это скорее всего не приведёт к заметному замедлению работы, но для корпоративных систем, куда ежедневно приходят сотни тысяч посетителей, это может стать большой проблемой. Каждая новая версия рукопожатия существенно облегчает процесс: TLS 1.2 совершает две фазы, а TLS 1.3 укладывается всего в одну и поддерживает 0-RTT.