Где живёт TLS
TLS (Transport Layer Security, RFC 8446 для 1.3) - слой между TCP и приложением. То есть:
Application (HTTP, IMAP, SMTP, ...)
│
TLS (encryption + authentication)
│
TCP (reliability)
│
IP / Ethernet
HTTPS = HTTP внутри TLS. Когда браузер открывает https://...:
- DNS-резолв (см. dns-resolution)
- TCP tcp-handshake на порт 443
- TLS-handshake (см. ниже) - это новые пакеты внутри TCP-соединения
- После hadshake'а - обычный HTTP-обмен зашифрованным payload'ом
TLS 1.3 handshake (упрощённо)
TLS 1.3 - one-roundtrip версия handshake'а:
Client Server
│ │
│ ── ClientHello ───────────────► │
│ • TLS-versions supported │
│ • cipher-suites supported │
│ • SNI: hostname │
│ • client key share (X25519) │
│ │
│ ◄── ServerHello │
│ • chosen cipher (TLS_AES_256...)│
│ • server key share │
│ ◄── Encrypted Extensions │ (after this everything encrypted)
│ ◄── Certificate │
│ ◄── CertificateVerify │
│ ◄── Finished │
│ │
│ ── Finished ─────────────────► │
│ │
│ ◄═════════════ HTTP data ════════►│
В TLS 1.2 было 3 roundtrip'а - медленнее. 1.3 - 1 roundtrip + 0-RTT для сессии-resumption.
Что происходит в handshake
- Согласование версии и cipher'а - какой алгоритм шифрования использовать (TLS_AES_256_GCM_SHA384, ChaCha20-Poly1305 и т.п.)
- Key exchange - обмен ключевыми материалами через ECDH (X25519, secp256r1)
- Аутентификация сервера - сервер показывает x509-сертификат, клиент проверяет цепочку до известного CA
- (Опционально) Аутентификация клиента - mTLS, клиент тоже шлёт серт
- Derive keys - обе стороны вычисляют общие ключи для шифрования данных
- Finished - взаимное подтверждение что всё прошло без MITM
SNI (Server Name Indication)
Сертификаты сервера привязаны к доменному имени. Если на одном IP несколько сайтов (виртуальный хостинг), сервер не знает за какой домен отвечать пока HTTP-запрос не пришёл - но HTTP уже после handshake'а.
Решение: SNI - клиент в ClientHello открытым текстом пишет имя сервера. Сервер выбирает правильный сертификат. Это значит что hostname виден сетевому наблюдателю даже в HTTPS - повод для появления Encrypted Client Hello (ECH) в современных версиях.
Где увидеть в живую
openssl s_client -connect example.com:443 -servername example.com < /dev/null
Покажет: согласованный cipher, цепочку сертификатов, verification result.
В [[#cmd-tcpdump|tcpdump]] на порту 443 видны пакеты TLS-handshake - но payload зашифрован уже после ServerHello.