Проект ЦИТадель
TLS защищает HTTPS, многие API, почтовые и другие прикладные протоколы. Обычно его настройка сводится к сертификату и нескольким параметрам сервера, но за этой настройкой стоят разные задачи: согласовать ключи, проверить имя узла и затем защитить поток данных. В статье разберём эти задачи по отдельности, пройдём рукопожатие TLS 1.3 и границы его гарантий, а в практикуме проверим живое соединение с помощью openssl.
При правильной проверке сертификата и имени TLS создаёт поверх транспорта канал со следующими свойствами:
Модель угроз включает активного противника в канале: он может читать, удалять, подменять и перенаправлять пакеты. Одного шифрования поэтому недостаточно: без проверки собеседника получится конфиденциальный разговор неизвестно с кем. TLS также не защищает уже скомпрометированную конечную точку, не скрывает все метаданные и не определяет, имеет ли аутентифицированный пользователь право выполнить операцию. Это границы протокола, а не его недостатки.
TLS 1.3 комбинирует несколько примитивов; их устройство и постквантовая стойкость подробнее разобраны в главах 12–14 курса о квантовых вычислениях.
Асимметрические операции нужны в рукопожатии, а основной объём данных защищает более быстрое симметричное шифрование. В TLS 1.3 шифронабор определяет AEAD и хеш, но не алгоритмы подписи и обмена ключами: они согласуются отдельно.
TLS 1.3 был опубликован в 2018 году, а в 2026 году его спецификацию обновил RFC 9846. По сравнению с TLS 1.2 из полного рукопожатия удалены статический RSA-обмен и многие устаревшие варианты, а данные приложения можно начать передавать после одного сетевого круга.
key_share для одной или нескольких ожидаемых групп. Если подходящей доли нет, сервер отвечает HelloRetryRequest, и рукопожатие требует дополнительного круга.TLS 1.2 обычно требовал для полного рукопожатия два сетевых круга и допускал статический RSA-обмен: клиент шифровал предварительный секрет долговременным открытым ключом сервера. В TLS 1.3 такого режима нет. Защита от отката версии использует специальную метку в случайном значении ServerHello: клиент TLS 1.3 обнаружит, что соединение подозрительно сведено к старой версии.
Возобновление и 0-RTT. Сервер может выдать билет сессии, а клиент — использовать связанный с ним предварительно согласованный ключ (PSK) в следующем соединении. Режим 0-RTT позволяет отправить ранние данные уже с первым ClientHello, но TLS не гарантирует их защиту от повторного воспроизведения и не даёт им полной прямой секретности. «Идемпотентный» не всегда значит «безопасный для повтора»: даже GET может менять состояние или расходовать ограниченный ресурс. Прикладной профиль должен явно определить допустимые ранние сообщения, а сервер — ограничивать повторы; для HTTP это описывает RFC 8470.
В полном рукопожатии с сертификатом TLS 1.3 использует эфемерный обмен: временные закрытые значения создаются для соединения и после него удаляются. Поэтому последующая компрометация ключа сертификата сама по себе не раскрывает ранее записанный трафик. У статического RSA-обмена в TLS 1.2 такого свойства не было: получив долговременный закрытый ключ, противник мог расшифровать сохранённые рукопожатия.
У возобновления есть важная оговорка. Режим psk_dhe_ke добавляет новый эфемерный обмен и сохраняет прямую секретность для обычных данных соединения даже при последующей компрометации PSK. Режим psk_ke полагается только на PSK и такой защиты не даёт. Ранние данные 0-RTT в любом случае выводятся до нового обмена и полной прямой секретности не имеют. Поэтому билеты и серверные ключи их защиты ограничивают по сроку, ротируют, а 0-RTT включают только после анализа повторов; компрометация ключа билетов не является универсальным способом расшифровать корректно установленную сессию psk_dhe_ke.
Прямая секретность защищает от будущей кражи долговременного ключа, но не от будущего алгоритма, способного восстановить сам эфемерный секрет по записанному обмену. На этой разнице основана угроза «собрать сейчас — расшифровать потом» и переход к постквантовому установлению ключей.
Подпись в CertificateVerify доказывает владение закрытым ключом. Связь этого ключа с именем сервера в публичном вебе обычно проверяет инфраструктура открытых ключей (Web PKI):
h2 для HTTP/2. Этот механизм понадобится в следующей статье.HSTS закрывает другой разрыв: после получения заголовка браузер обращается к сайту только по HTTPS. Однако при первом посещении открытого HTTP соединение ещё можно подменить; для включённых в него доменов это окно устраняет предварительно загруженный список HSTS. Не менее опасна отключённая проверка сертификата в клиентском коде (verify=False, InsecureSkipVerify): такая настройка сохраняет шифрование, но лишает клиента надёжной аутентификации сервера.
Российские алгоритмы. RFC 9189 и RFC 9367 описывают профили TLS 1.2 и TLS 1.3 с алгоритмами ГОСТ. Оба документа имеют информационный статус, и их публикация не означает одобрения IETF приведённых алгоритмов. Для работы нужны совместимые криптопровайдер, клиент, сервер и цепочка доверия; такие корни не обязаны входить в обычные браузерные хранилища. Общая схема TLS — согласование параметров, установление ключей, аутентификация и защита записей — сохраняется, но сообщения и криптографические правила надо проверять по профилю соответствующей версии.
Достаточно мощный отказоустойчивый квантовый компьютер смог бы применить алгоритм Шора к эллиптическим кривым. Срок появления такой машины неизвестен, но записывать шифрованный трафик можно уже сейчас, поэтому данные с длительным сроком секретности требуют упреждающей защиты.
X25519MLKEM768 объединяет эфемерный X25519 с постквантовым механизмом ML-KEM-768. Данные обоих механизмов передаются в key_share, а их результаты объединяются при выводе общего секрета. Гибрид рассчитан на сохранение защиты, пока остаётся стойкой хотя бы одна компонента. ML-KEM стандартизован NIST, общий способ гибридного обмена описан в RFC 9954, а конкретные группы ECDHE–ML-KEM стандартизованы в опубликованном в августе 2026 года RFC 10024; группа X25519MLKEM768 имеет статус Recommended.
Гибрид уже включён по умолчанию в Chrome и Firefox, поддерживается OpenSSL 3.5 и рядом серверных платформ. Это не означает, что каждое соединение постквантовое: алгоритм должен поддерживать и выбрать сервер, а крупный ClientHello иногда выявляет несовместимые промежуточные устройства. Сертификаты и подписи переходят отдельно, потому что они решают задачу аутентификации, тогда как гибридный обмен прежде всего защищает конфиденциальность записываемого сегодня трафика. Подробнее это различие разобрано в главе 12, а механизм ML-KEM и лабораторная работа — в главах 13–14.
Для заданий 1–3 достаточно распространённой версии OpenSSL 3.x; для X25519MLKEM768 нужна версия 3.5 или новее. Сначала проверьте openssl version.
Задание 1. Версия, ключи и проверка имени.
$ openssl s_client -connect example.com:443 -servername example.com \
-verify_hostname example.com -verify_return_error -brief </dev/null
Запишите версию, шифронабор, согласованную группу и результат проверки. Повторите команду с -msg без -brief и найдите ClientHello, ServerHello, CertificateVerify и Finished. OpenSSL показывает расшифрованные им сообщения; в сетевом дампе сертификат TLS 1.3 открытым текстом не виден.
Задание 2. Цепочка.
$ openssl s_client -connect example.com:443 -servername example.com \
-showcerts </dev/null 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates -ext subjectAltName
Команда после конвейера разбирает первый сертификат из присланного сервером набора. Найдите издателя, срок и имя в SAN. Затем изучите полный вывод -showcerts: сервер обычно присылает промежуточные сертификаты, но не обязан присылать доверенный корень. Не путайте показанную сервером последовательность с уже проверенной цепочкой.
Задание 3. Версии и группы. Повторите первое соединение с -tls1_2 и сравните порядок сообщений и видимость сертификата. Попробуйте -tls1: старая версия может быть запрещена самим OpenSSL, политикой ОС или сервером — по сообщению об ошибке определите, на каком уровне произошёл отказ. Параметром -groups ограничьте список групп и вызовите успешное согласование, HelloRetryRequest либо отсутствие общей группы.
Задание 4. Постквантовый гибрид.
$ openssl s_client -connect www.google.com:443 -servername www.google.com \
-verify_hostname www.google.com -verify_return_error \
-groups X25519MLKEM768 -brief </dev/null
При успешном согласовании OpenSSL укажет группу X25519MLKEM768. С приведённой командой возможны два исхода: гибрид согласован либо общей группы нет. Затем добавьте к списку классический резервный вариант, например :X25519, и проверьте, какой из двух вариантов выберут несколько разных серверов.
Задание 5*. Собственный сервер. Если nginx собран с OpenSSL 3.5 или совместимой библиотекой и завершает TLS сам, задайте поддерживаемые группы, оставив классический резервный вариант:
ssl_ecdh_curve X25519MLKEM768:X25519;
После проверки конфигурации и перезагрузки подтвердите обе ветви: клиент OpenSSL 3.5 согласует гибрид, а клиент без ML-KEM — X25519. Если TLS завершается на CDN или внешнем балансировщике, настройка должна выполняться там, а не на исходном nginx.
Задание 6*. Граница доверия. В отдельном тестовом профиле браузера поднимите mitmproxy. До установки его корня браузер должен отвергнуть подменённую цепочку; после установки корня соединение станет доверенным для этого профиля. Удалите корень по завершении и объясните, почему TLS не может отличить установленный администратором корень от установленного злоумышленником.
Задание 7*. Расшифровка собственного трафика. Запустите браузер с переменной SSLKEYLOGFILE или используйте параметр -keylogfile поддерживающего его клиента, затем передайте журнал Wireshark. Поддержка переменной зависит от приложения и TLS-библиотеки. Убедитесь, что в дампе появились HTTP-данные, и сформулируйте границу прямой секретности: она защищает от последующей компрометации долговременного ключа, но конечная точка во время сеанса знает трафиковые секреты.