Что такое Handshake (рукопожатие) в сетевых протоколах?

«Что такое Handshake (рукопожатие) в сетевых протоколах?» — вопрос из категории Сети, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Handshake (рукопожатие) — это процесс установления параметров соединения между клиентом и сервером перед началом обмена данными. Наиболее известен в контексте протокола SSL/TLS для установления безопасного соединения (например, для HTTPS).

Основные этапы TLS handshake:

  1. ClientHello: Клиент отправляет серверу информацию о поддерживаемых версиях TLS и наборах шифров.
  2. ServerHello: Сервер отвечает выбранной версией TLS, набором шифров и своим SSL-сертификатом.
  3. Проверка сертификата: Клиент проверяет подлинность сертификата сервера (например, по цепочке доверия).
  4. Обмен ключами: Клиент генерирует предварительный мастер-ключ, шифрует его открытым ключом сервера и отправляет.
  5. Генерация сессионных ключей: Обе стороны, используя общие данные, независимо вычисляют одинаковые сессионные ключи для симметричного шифрования данных.

Пример явного запуска handshake для SSL-сокета в Java:

SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, null, null); // Использует truststore по умолчанию
SSLSocketFactory factory = sslContext.getSocketFactory();
SSLSocket socket = (SSLSocket) factory.createSocket("example.com", 443);
socket.startHandshake(); // Явный вызов процесса рукопожатия

Почему это важно: Handshake обеспечивает аутентификацию сервера (а иногда и клиента) и безопасную генерацию ключей для шифрования всего последующего трафика. Сбой на этом этапе (например, из-за недоверенного сертификата) приводит к SSLHandshakeException.