Кратко
- CertificateVerify подписывает transcript закрытым ключом сертификата;
Finishedаутентифицирует следующую границу ключом из handshake traffic secret отправителя. - Успешный Finished сервера не доказывает Finished клиента, принятие 0-RTT, upstream прокси, прикладные полномочия или устойчивый результат операции.
Успех объявили на одно сообщение раньше
Цепочка, имя сервиса и CertificateVerify были допустимы. Затем verify_data не совпал с transcript и ключом, вычисленными клиентом. RFC 9846 требует фатального завершения. Это не частично успешная сессия, а неудавшееся рукопожатие.
CertificateVerify подтверждает контроль закрытого ключа credential и подписывает разделённую по роли конструкцию до Certificate. Проверка цепочки и сервисной идентичности остаётся отдельной.
Finished не является второй подписью сертификата. TLS 1.3 выводит finished_key из handshake traffic secret отправителя и считает HMAC по transcript до CertificateVerify, если оно было. Так подтверждаются вычисленные ключи и история именно этого соединения.
При PSK сообщения Certificate и CertificateVerify могут отсутствовать, а Finished остаётся обязательным. Эти доказательства нельзя подменять друг другом.
Transcript не равен последовательности пакетов
Хеш охватывает сообщения рукопожатия по порядку вместе с их типом и длиной, но не заголовки record, alerts и прикладные данные. Фрагментация не меняет логическую историю.
После HelloRetryRequest первый ClientHello представляется синтетическим message_hash. Остальная часть рукопожатия TLS 1.3 зашифрована. Поэтому точная реконструкция требует диагностических секретов конечной точки или равноценного свидетельства реализации, а не простого склеивания видимых байтов.
Хеш набора шифров используется и в transcript, и в HKDF. Длина verify_data в TLS 1.3 равна длине результата хеша, а не фиксированным 12 октетам TLS 1.2.
У каждого направления свой момент окончания
Клиент и сервер имеют разные secrets, создают разные Finished и проверяют партнёра в разное время. После отправки Finished сервер может перейти на application traffic key и передавать данные до получения Finished клиента. Но личности и активности клиента он ещё не знает: ClientHello мог быть воспроизведён.
Клиент проверяет сервер, при запросе отправляет свою аутентификацию, затем Finished. Один tls_complete скрывает, кто что отправил и проверил. Нужны отдельные finished_sent, peer_finished_verified и проверенное состояние реализации для каждой стороны.
0-RTT — явное исключение: оно использует прежний PSK и допускает повтор. Предложение, принятие или отказ early data должны храниться отдельно от обычного завершения.
У прокси две истории
Соединения клиент–прокси и прокси–origin не разделяют transcript, secrets или Finished. Перенос downstream-метки в upstream выдумывает непрерывность. Прикладная корреляция связывает запросы, но каждое плечо обязано доказать своё рукопожатие.
OpenSSL разделяет SSL_is_init_finished() и SSL_get_verify_result(), относящийся к сертификату. Key log полезен в лаборатории, но раскрывает secrets. BoringSSL указывает, что Finished-accessors возвращают ноль в TLS 1.3; GnuTLS предлагает hooks и отдельную ошибку. Сходное имя API не даёт переносимого доказательства.
Решающая проверка сохраняет сертификат и CertificateVerify правильными, меняет один байт Finished и требует фатального отказа. Затем удерживает Finished клиента, выполняет PSK без сертификата, вызывает HelloRetryRequest и повторяет через разные плечи прокси. Только поведение работающего кода доказывает границу.
Обзор для участников
Подробный контекст профиля
Войдите с подходящим уровнем подписки, чтобы открыть полный обзор и примечания к источникам.
Только для Стратегического сообщества
Стратегическое сообщество
Открыто всем читателям. Вступите и войдите, чтобы открыть обзоры профилей.
Вступить в Стратегическое сообществоТолько для Альянса лидеров
Альянс лидеров
Для проверенных владельцев IP-активов и руководителей. Войдите, чтобы открыть обзоры Альянса.
Вступить в Альянс лидеров