SkillGridИзучай computer science на практике

Что HTTPS добавляет к HTTP

Рукопожатие TLS, сертификаты и цепочка доверия за ними, что посредник может и чего не может, и почему прямая секретность меняет цену украденного ключа.

16 мин · 50 XP

HTTP — это текст в открытом виде. Всё, что вы вводите в форму, каждый cookie сессии и каждый токен API едут читаемыми байтами, и любое устройство на пути может их не только прочитать, но и изменить так, что ни одна сторона не заметит. HTTPS — тот же HTTP, только внутри TLS. Интересное здесь не шифрование, а то, что обе стороны умудряются договориться о секретном ключе, пока противник слышит каждое сообщение переговоров.

ClientServerTCP SYNTCP SYN-ACKTCP ACKClientHello: random, cipher list, key shareServerHello: random, chosen cipher, key shareCertificate chainFinishedFinishedhandshake key material is derived on both sidesGET /login HTTP/1.1HTTP/1.1 200 OK

Рукопожатие и есть эти переговоры, и происходит оно до первого запроса. Клиент открывает TCP-соединение, затем посылает ClientHello со случайным числом, списком поддерживаемых шифров и своим открытым ключом. Сервер отвечает своим случайным числом, выбранным шифром и своим открытым ключом. Дальше обе стороны выводят одни и те же сессионные ключи из своего секретного значения и чужого открытого, и никто, слушающий разговор, этот расчёт повторить не может. В конце обе стороны посылают сообщение Finished — хеш всего сказанного ранее, поэтому любая правка во время рукопожатия ломает проверку сразу.

Сертификат — это подписанное утверждение, связывающее открытый ключ с именем хоста. Внутри имя, открытый ключ, срок действия и подпись удостоверяющего центра. Именно подпись делает ключ заслуживающим доверия: сам по себе он не доказывает ничего. Если принимать любой предложенный ключ, противник просто предложит свой.

Chain
  1  leaf        CN=example.org
                 SAN: example.org, www.example.org
                 valid 2026-01-01 .. 2026-04-01
  2  intern     CN=R3 Intermediate CA
  3  root        CN=ISRG Root X1  (already on the device)

Validation
  signature of 1  checked with public key of 2    ok
  signature of 2  checked with public key of 3    ok
  signature of 3  checked with public key on device  ok
  name in SAN matches the host that was requested   ok
  current time inside the validity window           okЦепочка сертификатов и пять проверок, которые делает клиент.

Именно цепочка позволяет нескольким корневым центрам покрывать весь веб. Корневой центр подписывает промежуточный, промежуточный подписывает полученный вами сертификат, а ваше устройство должно изначально доверять только корню — корневые сертификаты поставляются вместе с операционной системой и браузером. Проверка идёт вверх по цепочке: подпись конечного сертификата сверяется ключом промежуточного, промежуточный сверяется с корнем, корень проверяется на доверие, а затем имя в сертификате сравнивается с тем хостом, который вы запросили, и сегодняшняя дата — со сроком действия. Любая одна неудача останавливает соединение.

У противника на пути, который не может предъявить действительный сертификат, серьёзная проблема. Он может выбрасывать и задерживать пакеты, может выдать себя за адрес, но прочитать зашифрованные байты не может и подделать рукопожатие без приемлемого для клиента сертификата тоже. Изменение одного зашифрованного байта не переворачивает бит в открытом тексте — проверка подлинности не проходит, и соединение обрывается. Поэтому проходить мимо предупреждения о сертификате плохая идея: либо это настоящая ошибка настройки, либо вы только что отдали сессию тому, кто её и вызвал.

$ curl -v https://example.org
*  SSL certificate problem: self-signed certificate in certificate chain
*  Closing connection

$ curl -vk https://example.org
*  Server certificate: CN=mitm-proxy.local
*  subjectAltName does not match example.org
<  HTTP/1.1 200 OKОдин и тот же запрос с проверкой сертификата и без неё.

Прямая секретность отвечает на конкретный вопрос: что будет с трафиком, записанным годы назад, если сегодня утечёт закрытый ключ сервера? В классическом обмене сессионный ключ шифровался открытым ключом сервера, поэтому записанное рукопожатие плюс утёкший ключ дают всё. При эфемерном обмене Диффи — Хеллмана ключ создаётся заново для этого одного соединения и выбрасывается, поэтому поздняя утечка ключа бесполезна против прошлого трафика. Активному противнику это не мешает, и от кражи самого сессионного ключа не спасает. Меняется ценность украденного ключа: вместо всей истории — одна сессия.

Практика

  1. Расставьте события первого HTTPS-запроса к хосту, с которым вы ещё не связывались.

    1. 1происходит обмен зашифрованным HTTP-запросом и ответом
    2. 2сервер предъявляет цепочку сертификатов
    3. 3клиент отправляет ClientHello со случайными данными и своим открытым ключом
    4. 4клиент открывает TCP-соединение на порт 443
    5. 5обе стороны завершают рукопожатие и выводят одинаковые сессионные ключи
    6. 6сервер отвечает своим случайным числом, выбранным шифром и своим открытым ключом
    Подсказки
    • Ничто зашифрованное не может уйти раньше, чем обе стороны договорятся, чем шифровать.
    • Сертификат приходит от сервера после обмена двумя приветствиями.
    • Данные приложения идут последними: рукопожатие должно завершиться с обеих сторон.
  2. Сервер предъявляет сертификат, выданный доверенным центром для правильного имени хоста, но срок действия истёк три дня назад. Браузер отказывается соединяться. Что на самом деле означает этот отказ?

    Подсказки
    • Спросите, что доказывает сертификат: это подпись центра, а не обещание про серверное ПО.
    • Сертификат с совершенно правильной подписью всё равно может быть выдан для другого имени.
    • Истёкший или отозванный сертификат это обычный ожидаемый отказ, и браузер сообщает о нём громко.
  3. Сопоставьте каждого противника или сбой с тем, чего он реально может добиться против современного HTTPS-соединения.

    Подсказки
    • Разделите противников по возможностям: читать и менять байты или просто копировать их и ждать.
    • Прямая секретность про трафик, записанный давно и расшифрованный позже, после утечки ключа.
    • Пассивный наблюдатель на пути всё равно узнаёт имена сайтов, которые вы посещаете, хотя содержимое страниц остаётся скрытым.

Вопросы по этому уроку

Зачем вообще учить сети?

Почти всё, что ты делаешь, в итоге с чем-то общается. Понимание того, как данные реально ходят, превращает «не работает» из загадки в список того, что можно проверить по очереди.

В чём реальная разница между TCP и UDP?

TCP следит, чтобы всё дошло и по порядку, и повторяет потерянное — за это платит временем. UDP отправляет и не оглядывается, поэтому видеозвонки и игры предпочитают его: опоздавший кадр хуже пропавшего.

Что такое DNS простыми словами?

Это телефонная книга интернета. Ты знаешь имя, а компьютеру нужен номер. DNS превращает имя вроде example.org в IP-адрес и запоминает ответ, чтобы не спрашивать каждый раз.

Это бесплатно?

Да. Первый уровень каждого предмета бесплатный и не требует аккаунта. Дальше уровни и старшие грейды платные — именно это позволяет проекту существовать.

На какой возраст рассчитано?

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

Нужно ли уже уметь программировать?

Нет. Логика, физика и сети начинаются с нуля. Код ты пишешь в разделе языков — и он тоже начинается с самого начала.

Нужно что-то устанавливать?

Нет. Всё работает в браузере: теория, практика и интерактивные симуляции. Скачивать нечего и настраивать нечего.

Сколько времени занимает один предмет?

Урок — от 10 до 15 минут. Грейд «джун» это примерно 12–20 уроков, то есть несколько недель регулярных занятий, а не один вечер.

Обязательно идти по порядку?

Внутри грейда уровни открываются по очереди: каждый опирается на предыдущий. А между предметами ты свободен — начинай с логики, физики или сетей.