Ответ
Установка HTTPS-соединения происходит во время процесса, называемого TLS Handshake. Его главная цель — аутентифицировать сервер, договориться об алгоритмах шифрования и безопасно сгенерировать общий секретный ключ для дальнейшего обмена данными.
Основные этапы:
ClientHello
Клиент отправляет серверу сообщение, содержащее:- Версию TLS, которую он поддерживает.
- Список поддерживаемых наборов шифров (Cipher Suites).
- Случайную последовательность байт (
Client Random
).
ServerHello
Сервер отвечает сообщением, в котором:- Выбирает один из предложенных клиентом наборов шифров.
- Отправляет свою случайную последовательность байт (
Server Random
). - Отправляет свой SSL-сертификат. Сертификат содержит публичный ключ сервера и информацию о его владельце, заверенную центром сертификации (CA).
Проверка сертификата клиентом
Клиент выполняет критически важные проверки:- Подлинность: Проверяет, что сертификат подписан доверенным центром сертификации (CA), который есть в хранилище клиента.
- Срок действия: Убеждается, что сертификат не просрочен.
- Имя хоста: Сверяет имя домена в сертификате (Common Name/SAN) с доменом, к которому он подключается.
Обмен ключами (Key Exchange)
- Клиент генерирует еще один секрет —
Pre-Master Secret
. - Шифрует его публичным ключом сервера (полученным из сертификата) и отправляет на сервер.
- Только сервер, обладая соответствующим приватным ключом, может расшифровать это сообщение и получить
Pre-Master Secret
.
- Клиент генерирует еще один секрет —
Генерация сессионных ключей
И клиент, и сервер теперь используютClient Random
,Server Random
иPre-Master Secret
для вычисления общего сессионного ключа. Этот ключ будет использоваться для симметричного шифрования всех последующих данных.Завершение (Finished)
Обе стороны обмениваются сообщениямиFinished
, зашифрованными новым сессионным ключом, чтобы подтвердить, что Handshake прошел успешно.
После этого этапа устанавливается защищенный канал, и начинается передача HTTP-данных.
В Go настройка проверки сертификата клиента выглядит так:
// tls.Config используется в http.Client или http.Server
tlsConfig := &tls.Config{
// По умолчанию false. Установка в true отключает проверку сертификата (ОПАСНО!)
InsecureSkipVerify: false,
// Можно указать свой пул доверенных корневых сертификатов
RootCAs: certPool,
}