Как работает протокол HTTPS и из каких этапов состоит установка защищённого соединения?

Ответ

HTTPS (HyperText Transfer Protocol Secure) — это расширение протокола HTTP, которое использует криптографические протоколы TLS/SSL для защиты данных. Он обеспечивает три ключевых аспекта безопасности:

  1. Шифрование: Защита данных от перехвата (атаки "человек посередине" - MITM).
  2. Целостность: Гарантия того, что данные не были изменены во время передачи.
  3. Аутентификация: Проверка того, что вы подключаетесь именно к тому серверу, к которому намеревались.

Процесс установки защищенного соединения называется TLS Handshake (рукопожатие) и состоит из следующих основных этапов:


  1. ClientHello: Клиент (браузер) отправляет серверу сообщение, в котором указывает поддерживаемые версии TLS и наборы шифров (cipher suites).



  2. ServerHello: Сервер выбирает из предложенного списка наиболее надежный набор шифров, который он тоже поддерживает. Затем сервер отправляет клиенту свой SSL-сертификат и публичный ключ.



  3. Проверка сертификата: Клиент проверяет подлинность сертификата сервера. Он смотрит, кем выдан сертификат, и проверяет его по цепочке доверия до корневого центра сертификации (CA), который уже встроен в ОС или браузер.



  4. Обмен ключами: Клиент генерирует случайное число (pre-master secret), шифрует его публичным ключом сервера и отправляет обратно. Только сервер, обладая приватным ключом, может расшифровать это сообщение. На основе этого секрета обе стороны генерируют одинаковый сессионный симметричный ключ.



  5. Защищенный обмен данными: Рукопожатие завершено. Весь дальнейший HTTP-трафик между клиентом и сервером шифруется с помощью быстрого симметричного сессионного ключа (например, AES). Асимметричное шифрование использовалось только на этапе рукопожатия для безопасной передачи ключа.


Пример простого HTTPS-сервера на Go:

package main

import (
    "log"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Hello, this is a secure server!"))
}

func main() {
    http.HandleFunc("/", handler)

    // Для запуска нужны файлы сертификата (cert.pem) и приватного ключа (key.pem).
    // Их можно сгенерировать самостоятельно для тестов или получить от Let's Encrypt.
    log.Println("Starting server on https://localhost:8443")
    err := http.ListenAndServeTLS(":8443", "cert.pem", "key.pem", nil)
    if err != nil {
        log.Fatal("ListenAndServeTLS: ", err)
    }
}