Как работает HTTPS

HTTPS (Hypertext Transfer Protocol Secure) — это расширение протокола передачи гипертекста (HTTP). HTTPS передаёт зашифрованные данные с использованием протокола TLS (Transport Layer Security). Если данные будут перехвачены в сети, всё, что получит злоумышленник, — это бинарный код.

Процесс установки защищенного соединения через протокол TLS (Transport Layer Security). Схема показывает, как происходит обмен ключами между клиентом и сервером для обеспечения безопасной передачи данных.

Пояснение к диаграмме (этапы соединения)

#1. TCP Handshake (Рукопожатие TCP)

Клиент и сервер устанавливают соединение через три этапа: SYN, SYN + ACK и ACK - известные как трёхстороннее рукопожатие (Three-Way Handshake).

▷ TCP SYN

Synchronize — Клиент посылает серверу начальный номер последовательности (например, Sequence Number = 1000). Это значение сообщает серверу, с какого номера будут начинаться байты данных от клиента.

◁ TCP SYN + ACK

Synchronize + Acknowledge — Сервер отвечает своим собственным начальным номером последовательности (например, Sequence Number = 3000) и подтверждает, что получил начальный номер клиента с помощью номера подтверждения Acknowledgment Number = 1001 (номер последовательности клиента + 1).

▷ TCP ACK

Acknowledge — Клиент подтверждает получение начального номера последовательности сервера, отправляя Acknowledgment Number = 3001 (номер последовательности сервера + 1).

Теперь клиент и сервер могут начать обмен данными. Таким образом, каждый из участников знает, с какого номера будут начинаться данные, и может следить за их последовательностью и целостностью.

Номер последовательности (Sequence Number) — это уникальный идентификатор, используемый в протоколе TCP для отслеживания каждого байта данных, передаваемых между клиентом и сервером. Он обеспечивает упорядоченную передачу данных и помогает избежать дублирования или потери пакетов.

#2. Certificate Check (Проверка сертификата)

Клиент и сервер обмениваются сообщениями для проверки подлинности и установления доверия на основе сертификата сервера.

  • Клиент отправляет сообщение Client Hello.
  • Сервер отвечает Server Hello и отправляет сертификат, подтверждающий его подлинность.
  • Клиент проверяет сертификат и принимает решение о продолжении соединения.

▷ Client Hello

Клиент отправляет серверу сообщение Client Hello, в котором указывает:

  • Поддерживаемую версию протокола TLS.
  • Список предпочитаемых алгоритмов шифрования.
  • Случайное число (random nonce).

Это сообщение инициирует начало процесса проверки подлинности.

◁ Server Hello

Сервер отвечает сообщением Server Hello, выбирая параметры, которые будут использоваться для соединения. Он также генерирует свое случайное число и отправляет его клиенту для дальнейшего использования - создания сессионных ключей.

◁ Certificate (public key)

Сервер отправляет клиенту свой сертификат, который включает публичный ключ, информацию о центре сертификации (CA), срок действия и другие параметры. Сертификат подписан доверенным CA, чтобы клиент мог проверить его подлинность.

◁ Server Hello Done

Сервер завершает этап проверки сертификата, отправляя сообщение Server Hello Done, которое сигнализирует клиенту о завершении передачи всех необходимых данных для проверки.

Проверка сертификата — это процесс, при котором клиент проверяет подлинность сертификата сервера, включая подпись CA, срок действия, соответствие доменного имени и проверку отзыва сертификата.

#3. Key Exchange (Обмен ключами)

Клиент и сервер обмениваются сессионным ключом для дальнейшего шифрования данных.

  • Клиент генерирует сессионный ключ (Session Key) и шифрует его с помощью публичного ключа (Public Key) сервера.
  • Зашифрованный сессионный ключ передается на сервер.
  • Оба участника устанавливают параметры шифрования, используя "Change Cipher Spec" и завершают настройку с помощью сообщения Finished.

▷ Client Key Exchange

Клиент создает сессионный ключ, шифрует его с помощью публичного ключа сервера, полученного из сертификата, и отправляет зашифрованный ключ на сервер.

▷ Change Cipher Spec

Клиент уведомляет сервер о том, что он будет использовать новые параметры шифрования (сессионный ключ) для дальнейших сообщений, отправляя сообщение Change Cipher Spec.

▷ Finished

Клиент завершает настройку, отправляя сообщение Finished, зашифрованное новым сессионным ключом, чтобы подтвердить успешное завершение обмена ключами.

◁ Change Cipher Spec

Сервер принимает сессионный ключ, отправленный клиентом, и отвечает сообщением Change Cipher Spec, указывая, что он также будет использовать этот ключ для шифрования данных.

◁ Finished

Сервер завершает процесс обмена ключами, отправляя сообщение Finished, зашифрованное сессионным ключом, чтобы подтвердить успешное завершение настройки.

Сессионный ключ (Session Key) — это временный ключ, используемый для шифрования данных во время сеанса связи. Его используют для симметричного шифрования, так как это быстрее и эффективнее по сравнению с асимметричным шифрованием.

#4. Data Transmission (Передача данных)

После успешного обмена ключами клиент и сервер используют симметричное шифрование для безопасной передачи данных, используя сессионный ключ.

▷ Encrypted Data (session key)

Клиент шифрует все передаваемые данные с помощью сессионного ключа и отправляет их на сервер.

◁ Encrypted Data (session key)

Сервер получает зашифрованные данные, расшифровывает их с помощью того же сессионного ключа и отправляет обратно зашифрованный ответ.

Симметричное шифрование используется для всех последующих обменов данными после установления соединения, что обеспечивает высокую производительность и безопасность при передаче информации.

Заметки

HTTPS используют оба типа шифрования

  1. Ассиметричное шифрование (asymmetric encryption) используется на этапе обмена ключами. Это необходимо для безопасной передачи сессионного ключа. Ассиметричное шифрование использует публичный и приватный ключи.

  2. Симметричное шифрование (symmetric encryption) используется для передачи данных после установления соединения. Оба участника используют одинаковый сессионный ключ для шифрования и дешифрования данных.

Таким образом, в HTTPS ассиметричное шифрование применяется только на начальном этапе, а затем для основной передачи данных используется симметричное шифрование.

Случайное число (random nonce)

Случайное число (random nonce) — это уникальное, случайно сгенерированное число или строка, используемая один раз в криптографических протоколах для обеспечения безопасности. Оно предотвращает атаки воспроизведения (replay attacks) и помогает установить уникальные параметры для каждой новой сессии.

В контексте TLS и SSL, случайное число используется при рукопожатии (handshake) следующим образом:

  1. Client Hello: Клиент генерирует свое случайное число (Client Random) и отправляет его серверу.
  2. Server Hello: Сервер генерирует свое случайное число (Server Random) и отправляет его клиенту.

Эти случайные числа используются для:

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

Иными словами, случайное число гарантирует, что каждое новое соединение между клиентом и сервером будет уникальным и безопасным, даже если оно происходит между одними и теми же сторонами.

Как создается сессионный ключ

Создание сессионного ключа зависит от конкретного метода обмена ключами, который используется в протоколе TLS. Рассмотрим основные варианты: RSA и ECDHE.

RSA: Создание сессионного ключа с использованием RSA (TLS 1.2 и ниже)

При использовании алгоритма RSA, клиент самостоятельно генерирует сессионный ключ следующим образом:

  1. Генерация Pre-Master Secret:
    Клиент создает случайное число (Pre-Master Secret), которое будет использоваться в процессе создания сессионного ключа.

  2. Шифрование с помощью публичного ключа:
    Клиент шифрует Pre-Master Secret с помощью публичного ключа, полученного из сертификата сервера.

  3. Отправка на сервер:
    Зашифрованное значение Pre-Master Secret отправляется на сервер в сообщении Client Key Exchange.

  4. Создание Master Secret:
    Клиент и сервер используют свои случайные числа (Client Random и Server Random) вместе с Pre-Master Secret для создания Master Secret.

  5. Генерация сессионного ключа:
    На основе Master Secret обе стороны (клиент и сервер) создают одинаковые сессионные ключи (Session Keys) для симметричного шифрования. Этот процесс выполняется с помощью функции псевдослучайных чисел (PRF), которая гарантирует уникальность ключей.

Итог: Клиент генерирует Pre-Master Secret, который служит основой для создания сессионного ключа.

ECDHE: Создание сессионного ключа с использованием ECDHE (TLS 1.2 и TLS 1.3)

Алгоритм ECDHE (Elliptic Curve Diffie-Hellman Ephemeral) используется для создания сессионного ключа на основе метода Диффи-Хеллмана с использованием эллиптических кривых. Это обеспечивает прямую секретность (PFS).

  1. Генерация пары ключей:
    Клиент генерирует свою пару ключей: приватный ключ (Private Key) и публичный ключ (Public Key) на основе эллиптической кривой.

  2. Отправка публичного ключа:
    Клиент отправляет свой публичный ключ серверу в сообщении Client Key Exchange.

  3. Генерация общего секрета:
    Клиент и сервер, используя свои приватные ключи и публичный ключ друг друга, вычисляют общий секрет (Shared Secret) с помощью алгоритма ECDHE.

  4. Создание Master Secret:
    Общий секрет (Shared Secret), вместе с случайными числами (Client Random и Server Random), используется для создания Master Secret.

  5. Генерация сессионного ключа:
    На основе Master Secret клиент и сервер генерируют сессионные ключи для симметричного шифрования данных.

Итог: Сессионный ключ создается на основе общего секрета, который высчитывается обеими сторонами на основе их приватных и публичных ключей.

Различия между RSA и ECDHE

  • RSA: Клиент генерирует Pre-Master Secret и передает его зашифрованным на сервер, который затем использует его для создания сессионного ключа.

  • ECDHE: Клиент и сервер совместно создают общий секрет (Shared Secret) на основе приватных и публичных ключей. Этот общий секрет используется для создания сессионного ключа.

Таким образом, при использовании ECDHE процесс создания сессионного ключа более безопасен, так как даже если приватный ключ сервера будет скомпрометирован в будущем, это не повлияет на безопасность прошлых сеансов (прямая секретность).

Пример запроса через curl

Давайте теперь, в качестве реального примера, сделаем HTTPS зарос на google.com с помощью curl, который выдаст нам подробную информацию о ходе запроса:

$ curl -v https://google.com

Получим:

*   Trying 173.194.221.138:443...
* Connected to google.com (173.194.221.138) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* TLSv1.0 (OUT), TLS header, Certificate Status (22):
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS header, Finished (20):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.2 (OUT), TLS header, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=*.google.com
*  start date: Aug 26 06:33:47 2024 GMT
*  expire date: Nov 18 06:33:46 2024 GMT
*  subjectAltName: host "google.com" matched cert's "google.com"
*  issuer: C=US; O=Google Trust Services; CN=WR2
*  SSL certificate verify ok.
* Using HTTP2, server supports multiplexing
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* Using Stream ID: 1 (easy handle 0x6387721e8eb0)
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
> GET / HTTP/2
> Host: google.com
> user-agent: curl/7.81.0
> accept: */*
>
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
< HTTP/2 301
< location: https://www.google.com/
< content-type: text/html; charset=UTF-8
< content-security-policy-report-only: object-src 'none';base-uri 'self'
< date: Sun, 29 Sep 2024 21:01:56 GMT
< expires: Tue, 29 Oct 2024 21:01:56 GMT
< cache-control: public, max-age=2592000
< server: gws
< content-length: 220
< x-xss-protection: 0
< x-frame-options: SAMEORIGIN
< alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
<
* TLSv1.2 (IN), TLS header, Supplemental data (23):
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="https://www.google.com/">here</A>.
</BODY></HTML>
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* Connection #0 to host google.com left intact

Видео по теме