Как происходит шифрование в HTTPS
Что проверяют
Знаете ли вы современный TLS, а не схему из старых учебников, где клиент шифрует сеансовый ключ открытым ключом сервера. Для Node.js-разработчика следом идёт практика: где в вашем сервисе снимается TLS и что делать с самоподписанным сертификатом в тестах.
Как отвечать
Рукопожатие TLS 1.3:
- ClientHello: шифры, имя хоста в SNI, протоколы ALPN (
h2,http/1.1) и сразу своя часть обмена ключами, обычно на кривой X25519; - ServerHello: сервер выбирает параметры и шлёт свою часть. Обе стороны по Диффи-Хеллману на эфемерных ключах (ECDHE) получают общий секрет, который по сети не передаётся, и через HKDF выводят ключи сессии;
- сертификат: идёт уже зашифрованным. Сервер присылает цепочку и подписывает рукопожатие закрытым ключом (
CertificateVerify), клиент проверяет цепочку до доверенного корня, срок и имя хоста; - данные: симметричный AEAD-шифр, AES-GCM или ChaCha20-Poly1305, он даёт и конфиденциальность, и целостность.
Итог: асимметрия нужна для аутентификации и согласования ключа, а не для шифрования данных. Благодаря эфемерным ключам утечка ключа сервера не раскрывает записанный раньше трафик (forward secrecy). Полное рукопожатие занимает один круг, при возобновлении возможен 0-RTT, но такие данные можно переотправить, поэтому туда пускают только идемпотентные запросы.
В Node.js: https.createServer({ key, cert }) поверх модуля tls. Минимальная версия по умолчанию TLS 1.2, клиент проверяет сертификат (rejectUnauthorized: true), корпоративный корень добавляют через NODE_EXTRA_CA_CERTS. В проде TLS часто снимает nginx или балансировщик, тогда в Express нужен trust proxy, чтобы протокол читался из X-Forwarded-Proto.
Где спотыкаются
Описывают RSA-обмен, где клиент шифрует ключ открытым ключом сервера. В TLS 1.3 его убрали как раз из-за отсутствия forward secrecy.
Лечат ошибку сертификата через NODE_TLS_REJECT_UNAUTHORIZED=0. Это отключает проверку для всего процесса, и такой код доезжает до прода.
Говорят «SSL». SSL 3.0 давно запрещён, как и TLS 1.0 и 1.1, протокол называется TLS.