TLS-рукопожатие: пошаговое руководство по установке защищенного соединения
Что такое TLS-рукопожатие?
TLS-рукопожатие (TLS handshake) — это процесс, в ходе которого клиент и сервер устанавливают зашифрованное соединение. Каждый раз при посещении SSL/TLS проверку-сайта происходит TLS-рукопожатие до передачи любых данных приложения. Понимание этого процесса необходимо для диагностики проблем соединения, оптимизации производительности и настройки безопасных серверов.
TLS 1.2: пошаговый разбор
Рукопожатие TLS 1.2 требует двух циклов обмена данными между клиентом и сервером до начала передачи зашифрованных данных.
Первый цикл: приветствие и обмен ключами
- ClientHello: клиент отправляет поддерживаемые шифронаборы, версию TLS, случайное число и расширения (например, SNI — Server Name Indication).
- ServerHello: сервер выбирает шифронабор, отправляет свое случайное число и цифровой сертификат с открытым ключом.
- Проверка сертификата: клиент проверяет сертификат сервера по доверенным удостоверяющим центрам (CA), срок действия, статус отзыва и соответствие домену.
- Обмен ключами: с помощью выбранного алгоритма (RSA или Diffie-Hellman) обе стороны вычисляют предварительный секрет (pre-master secret).
Второй цикл: завершение рукопожатия
- Client Finished: клиент отправляет сообщение ChangeCipherSpec и зашифрованное сообщение Finished с использованием производных сеансовых ключей.
- Server Finished: сервер отправляет свои ChangeCipherSpec и Finished.
- Безопасный канал установлен: данные приложения могут передаваться в зашифрованном виде.
Клиент Сервер
|--- ClientHello ------------------>|
|<-- ServerHello, Certificate ------|
|<-- ServerKeyExchange, Done -------|
|--- ClientKeyExchange ------------>|
|--- ChangeCipherSpec, Finished --->|
|<-- ChangeCipherSpec, Finished ----|
|=== Зашифрованные данные =========|
TLS 1.3: ускоренное рукопожатие
TLS 1.3, утвержденный в 2018 году (RFC 8446), значительно упрощает и ускоряет процесс рукопожатия. Главное улучшение — сокращение с двух циклов до одного.
Ключевые улучшения TLS 1.3
- 1-RTT рукопожатие: клиент отправляет свою долю ключа в первом сообщении, позволяя серверу немедленно вычислить ключи. Задержка рукопожатия сокращается на 50%.
- 0-RTT возобновление: для повторных подключений TLS 1.3 поддерживает возобновление без дополнительных циклов, отправляя зашифрованные данные в первом пакете.
- Удалены небезопасные алгоритмы: статический обмен ключами RSA, режим CBC, RC4, SHA-1, MD5 и произвольные группы Diffie-Hellman полностью исключены.
- Обязательная прямая секретность: все шифронаборы TLS 1.3 используют эфемерный обмен ключами, гарантируя защиту прошлых сессий при компрометации долгосрочных ключей.
- Зашифрованное рукопожатие: сертификат сервера и большинство сообщений рукопожатия зашифрованы, улучшая конфиденциальность.
Клиент Сервер
|--- ClientHello + KeyShare ------->|
|<-- ServerHello + KeyShare --------|
|<-- {EncryptedExtensions} ---------|
|<-- {Certificate, Finished} -------|
|--- {Finished} ------------------->|
|=== Зашифрованные данные =========|
Сравнение TLS 1.2 и TLS 1.3
| Характеристика | TLS 1.2 | TLS 1.3 |
|---|---|---|
| Циклы рукопожатия | 2 RTT | 1 RTT (0-RTT для возобновления) |
| Прямая секретность | Опционально | Обязательно |
| Шифронаборы | 37+ (многие небезопасны) | 5 (все безопасны) |
| Шифрование сертификата | Открытый текст | Зашифровано |
| Обмен ключами RSA | Поддерживается | Удален |
| 0-RTT возобновление | Недоступно | Поддерживается |
Влияние на производительность
Разница в производительности между TLS 1.2 и 1.3 существенна, особенно на каналах с высокой задержкой:
- Мобильные пользователи: в сотовых сетях с задержкой 100 мс+ TLS 1.3 экономит 100-200 мс на каждом новом соединении. Это напрямую влияет на TTFB и воспринимаемую скорость.
- API-сервисы: для микросервисов с тысячами межсервисных вызовов сниженные накладные расходы на рукопожатие дают измеримый рост пропускной способности.
- Узлы CDN: сети доставки контента значительно выигрывают от 0-RTT, обслуживая повторных посетителей с минимальной задержкой.
Оптимизация TLS-конфигурации
# Рекомендуемая конфигурация nginx для TLS
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
Частые ошибки рукопожатия
- Несовпадение сертификата: домен в сертификате не соответствует запрошенному хосту. Проверьте SAN (Subject Alternative Names) и покрытие wildcard.
- Истекший сертификат: автоматизируйте обновление с помощью certbot и мониторьте сроки действия заблаговременно.
- Несовместимость шифронаборов: клиент и сервер не имеют общих шифронаборов. Обновите конфигурацию сервера.
- Неполная цепочка сертификатов: сервер не отправляет промежуточные сертификаты CA. Всегда настраивайте полный файл цепочки.
- Рассинхронизация часов: значительная разница во времени между клиентом и сервером может вызвать ошибки валидации.
Заключение
TLS-рукопожатие — основа безопасной веб-коммуникации. Переход на TLS 1.3 обеспечивает и более сильную защиту, и лучшую производительность. Приоритизируйте поддержку TLS 1.3, обеспечьте правильное управление сертификатами и регулярно проводите аудит конфигурации TLS.
Проверьте ваш сайт прямо сейчас
Проверить →