T. Dierks, E. Rescorla
Протокол безопасности транспортного уровня (TLS)
Версия 1.2
Запрос на комментарии 5246 (RFC 5246)
Август 2008
Часть 3.1
В статье приводится продолжение перевода на русский язык стандарта IETF - RFC 5246, описывающего работу протокола безопасности транспортного уровня TLS версии 1.2. Данная часть перевода охватывает первую половину описания работы рукопожатия TLS 1.2.
Предыдущие части перевода: Часть 1, Часть 2.
СОДЕРЖАНИЕ
7. Протоколы процесса рукопожатия TLS
[1] В TLS имеется три подпротокола, используемые для:
согласования двумя соединяющимися узлами параметров безопасности протокола записи;
аутентификации сторонами друг друга;
применения согласованных параметров безопасности;
сообщений друг другу об ошибках.
Протокол рукопожатия (The Handshake Protocol) необходим для согласования параметров сессии, которые состоят из следующих элементов:
session identifier
Идентификатор сессии – произвольная последовательность байт, выбранная сервером для обозначения активного состояния сессии [2], либо состояния ее возобновления (англ. resumable state).
peer certificate
Сертификат узла – сертификат стандарта X509v3 [PKIX] [3]. Данный элемент состояния может быть нулевым.
compression method
Алгоритм используемый для сжатия данных перед началом шифрования.
cipher spec
Параметры (спецификация) шифрования:
псевдослучайная функция (PRF) используемая для генерации ключевого материала;
алгоритм канального шифрования данных (англ. bulk cipher algorithm) (нулевой, AES, и т. д.);
алгоритм создания кода аутентификации сообщения (далее – MAC) (напр., HMAC-SHA1).
Также, этот параметр определяет криптографические атрибуты, такие как mac_length
. (Формальное определение находится в Прил. А.6). [4]
master secret
Общий для клиента и сервера секрет размером 48-байт.
is resumable
Флаг, показывающий возможно ли инициировать новое соединение в рамках текущей сессии [5].
Данные параметры используются для создания параметров безопасности, отправляемых уровню записи протокола TLS (см. Разд. 6), который, в свою очередь, использует параметры безопасности для защиты данных приложения. Используя возможность возобновления сессии, предоставляемую протоколом рукопожатия TLS, можно создавать несколько соединений в рамках одной и той же сессии.
7.1. Протокол изменения параметров шифрования (Change Cipher Spec)
Протокол изменения параметров шифрования нужен для сигнализации о смене стратегии шифрования. Протокол состоит из единственного сообщения, которое шифруется и сжимается в рабочем состоянии соединения (но не в состоянии ожидания (англ. pending state)). Все сообщение состоит из одного байта, значение которого равно 1:
struct {
enum { change_cipher_spec(1), (255) } type;
} ChangeCipherSpec;
Сообщение ChangeCipherSpec
посылается как клиентом, так и сервером [45] для сообщения реципиенту о том, что последующие записи будут защищаться заново согласованными параметрами шифрования и ключами. При приеме данного сообщения его реципиент дает инструкцию уровню (слою) записи немедленно скопировать состояние ожидания чтения (англ. read pending state) в рабочее состояние чтения (англ. read current state). Непосредственно после отправки данного сообщения, его отправитель должен дать инструкцию уровню записи сделать состояние ожидания записи (англ. write pending state) рабочим состоянием записи (англ. write current state). (См. Разд. 6. 1.). Сообщение ChangeCipherSpec
посылается во время рукопожатия после того, как были согласованы параметры безопасности, но до того как было послано подтвержденное сообщение Finished
.
Примечание: если повторное рукопожатие происходит во время передачи данных, стороны, устанавливающие связь, могут продолжить пересылать данные, используя старые параметры шифрования (CipherSpec
). Однако, если было послано сообщение ChangeCipherSpec
, новые значения CipherSpec
должны быть созданы в любом случае. Сторона, посылающая сообщение ChangeCipherSpec
не знает того, закончила ли другая сторона расчет ключевого материала (например, если для этого ей следует выполнить требующие определенного времени операции с открытым ключом). Таким образом, при этом может существовать небольшое временное окно, во время которого реципиент сообщения должен положить данные в буфер. На практике, при использовании современных машин такой интервал будет, вероятнее всего, весьма коротким.
7.2. Протокол оповещений
Одним из типов содержимого, поддерживаемый уровнем записи TLS, является тип содержимого alert
(оповещение). Сообщения оповещения (далее – alert-сообщения) содержат информацию о степени серьезности события (предупреждение или критическое) (англ. warning or fatal), а также описание оповещения. Alert-сообщения с уровнем значимости «критическое» ведут к немедленному прекращению соединения. В этом случае другие соединения, относящиеся к сессии, могут оставаться активными, но идентификатор сессии должен быть признан недействительным (англ. invalidated) в целях предотвращения создания новых соединений для этой сессии. Как и другие сообщения, alert-сообщения шифруются и сжимаются так, как это определено рабочим состоянием соединения.
Ниже даются два перечисления протокола оповещений - AlertLevel
и AlertDescription
. Первое из них содержит уровни опасности оповещений, второе - список самих оповещений. Структура Alert
, таким образом, имеет два поля содержащих информацию о уровне опасности оповещения, а также описание самого оповещения:
enum { warning(1), fatal(2), (255) } AlertLevel;
enum {
close_notify(0),
unexpected_message(10),
bad_record_mac(20),
decryption_failed_RESERVED(21),
record_overflow(22),
decompression_failure(30),
handshake_failure(40),
no_certificate_RESERVED(41),
bad_certificate(42),
unsupported_certificate(43),
certificate_revoked(44),
certificate_expired(45),
certificate_unknown(46),
illegal_parameter(47),
unknown_ca(48),
access_denied(49),
decode_error(50),
decrypt_error(51),
export_restriction_RESERVED(60),
protocol_version(70),
insufficient_security(71),
internal_error(80),
user_canceled(90),
no_renegotiation(100),
unsupported_extension(110),
(255)
} AlertDescription;
struct {
AlertLevel level;
AlertDescription description;
} Alert
7.2.1. Оповещения о закрытии соединения
Во избежание атаки отсечения (англ. truncation attack
) [6] клиент и сервер должны знать о том, что соединение закрывается. Любая из двух сторон может инициировать обмен сообщениями о закрытии. К данному типу сообщений относятся:
close_notify
Сообщение уведомляет реципиента о том, что в этом соединении отправитель не будет больше посылать каких-либо сообщений. Обратите внимание, что начиная с TLS 1.1 невозможность правильно закрыть соединение не влечет за собой требования о запрете на возобновление сессии. Это является изменением по сравнению с TLS 1.0 и было сделано с целью соответствия широко распространенной практике в реализации приложений.
Каждая из сторон может инициировать закрытие соединения путем отправки сообщения «close_notify
». При этом любые данные, полученные после сообщения о закрытии, будут проигнорированы.
Если не было передано каких-либо других критических оповещений, сторона, закрывающая соединение, должна отправить оповещение «close_notify
» перед тем, как закроет сторону записи соединения (исходящий трафик). Другая сторона должна ответить своим оповещением «close_notify
» и немедленно закрыть соединение, сбросив все ожидающие состояния записи (англ. pending writes). От инициатора закрытия соединения не требуется ожидать ответного сообщения «close_notify
» для того, чтобы закрыть сторону чтения (входящий трафик) в соединении.
Если протокол приложения, использующий TLS, обеспечивает то, что после закрытия TLS-соединения, любые данные могут быть перенесены базовым (нижележащим) транспортным сервисом (англ. underlying transport), то в этом случае TLS-реализация должна получить ответное оповещение «close_notify
» до того, как она просигнализирует прикладному уровню о том, что TLS-соединение было завершено [7]. Если протокол приложения не будет передавать какие-либо дополнительные данные, и только лишь начнет закрытие соединения с базовым транспортным сервисом (тж. транспортом), то в этом случае реализация может закрыть транспорт не ожидая ответного сообщения «close_notify
». Ни одна из частей данного стандарта не может быть использована для того, чтобы диктовать алгоритм действий при управлении протоколом TLS его транспортами данных, включая момент, когда будет открыто или закрыто соединение.
Примечание: подразумевается, что при закрытии соединения все данные, ожидающие своей обработки (англ. pending data), могут быть надежно пересланы до того как будет уничтожен транспорт.
7.2.2. Сообщения об ошибках
Механизм реагирования на ошибки в протоколе TLS-рукопожатия весьма прост. При обнаружении ошибки, сторона, обнаружившая ошибку, посылает сообщение об этом другой стороне. После приема или передачи сообщения о критической ошибке, обе стороны немедленно закрывают соединение. При этом и сервер и клиент должны удалить из памяти любые идентификаторы сессии, ключи и секреты, связанные с неудачным соединением. Таким образом, любое соединение, завершившееся сообщением о критической ошибке, не должно быть возобновлено.
Как только реализация встречается с условием, которое определено как критическая ошибка, она должна послать соответствующее сообщение перед закрытием соединения. Для всех сообщений, у которых протокол явно не указывает уровень опасности, сторона, пославшая сообщение, может определить по своему усмотрению должна ли ошибка оцениваться как критическая или нет. Если реализация посылает сообщение об ошибке, но при этом намеревается немедленно закрыть соединение, она должна послать сообщение о критическом уровне ошибки.
В общем случае, при приеме и отправке сообщения уровня предупреждения, соединение может нормально продолжать свою работу. Если принимающая сторона решает не продолжать работу соединения (напр., после получения оповещения «no_renegotiation
», которое принимающая сторона не желает получать), она должна послать сообщение критического уровня для закрытия соединения. Учитывая это, посылающая сторона не может, в общем случае, знать как поведет себя принимающая сторона. Таким образом, оповещения уровня предупреждения (англ. warning alerts) иногда могут совсем не посылаться в том случае, если посылающая сторона желает продолжить соединение, соответственно – их нельзя воспринимать в качестве чрезвычайно полезных. Например, если узел решает принять сертификат с истекшим сроком действия (возможно, после подтверждения этого пользователем) и желает продолжить соединение, в общем случае при этом не следует посылать сообщение «certificate_expired
».
Определены следующие сообщения об ошибках:
unexpected_message
Непредвиденное сообщение. Посылается при приеме несоответствующего сообщения. Данное сообщение всегда критично и не должно присутствовать при связи двух правильно реализованных приложений.
bad_record_mac
Данное оповещение высылается, если сторона записи получила неправильный MAC. Также, данное сообщение должно посылаться в том случае, если была неверно расшифрована структура «TLSCiphertext
» [8]: либо длина самой структуры не является четным кратным длине блока, либо значения набивок (англ. padding values) этой структуры являются некорректными. Данное сообщение всегда критично и не должно присутствовать при связи двух правильно реализованных приложений (за исключением случая искажения сообщения в сети).
decryption_failed_RESERVED
Данное оповещение использовалось в более ранних версиях TLS и могло быть использовано для осуществления атак при работе протокола в режиме шифрования CBC [9]. Совместимые с TLS 1.2 реализации никогда не должны высылать данное сообщение.
record_overflow
Была получена запись типа TLSCiphertext
, имеющая длину более 2^14+2048 байт, или же запись была расшифрована в запись типа TLSCompressed
, имеющую длину более 2^14+1024 байт. Данное сообщение всегда критично и не должно присутствовать при связи двух правильно реализованных приложений (за исключением случая искажения сообщения в сети).
decompression_failure
Функция распаковки (англ. decompression function) получила некорректные входные данные (например, размер данных превышают установленный лимит). Данное сообщение всегда критично и не должно присутствовать при связи двух правильно реализованных приложений.
handshake_failure
Получение сообщения «handshake_failure
» говорит о том, что отправитель не смог выработать приемлемый набор параметров безопасности с учетом доступных опций. Данная ошибка является критической.
no_certificate_RESERVED
Данное сообщение использовалось в стандарте SSLv3, но ни в одной из версий TLS. Совместимые с TLS 1.2 реализации никогда не должны высылать данное сообщение.
bad_certificate
Сертификат был поврежден, либо содержит подписи, которые не могут быть правильно проверены и т. д.
unsupported_certificate
Сертификат имеет неподдерживаемый тип.
certificate_revoked
Сертификат был отозван подписавшим его лицом.
certificate_expired
Срок действия сертификата истек, либо сам сертификат не является действительным на момент проверки.
certificate_unknown
При обработке сертификата возникли некоторые другие (неуказанные) проблемы, что не позволяет его принять.
illegal_parameter
Значение одного из полей сообщения рукопожатия выходит за установленные пределы, либо несовместимо с другими полями. Данная ошибка всегда является критической.
unknown_ca
Была получена действительная цепочка сертификатов или частичная цепочка, но сертификат не был принят, так как не было найдено местоположение сертификата удостоверяющего центра (УЦ), или же он не был сопоставлен с известным доверенным УЦ. Данная ошибка всегда является критической.
access_denied
Был получен действительный сертификат, но при контроле доступа отправитель не стал продолжать рукопожатие. Данная ошибка всегда является критической.
decode_error
Сообщение не могло быть декодировано, так как значение некоторого поля выходит за установленный диапазон либо длина сообщения является некорректной. Данное сообщение всегда критично и не должно присутствовать при связи двух правильно реализованных приложений (за исключением случая искажения сообщения в сети).
decrypt_error
Криптографическая операция во время рукопожатия неудачно завершена, включая случай невозможности корректно проверить подпись или действительность (тж. валидность) сообщения «Finished
» [10]. Данная ошибка всегда является критической.
export_restriction_RESERVED
Данное сообщение использовалось в некоторых более ранних версиях TLS. Совместимые с TLS 1.2 реализации никогда не должны высылать данное сообщение.
protocol_version
Версия протокола, указанная клиентом при попытке рукопожатия распознана, но не поддерживается. (Например, в целях безопасности не должны приниматься старые версии протоколов). Данная ошибка всегда является критической.
insufficient_security
Сообщение высылается вместо сообщения «handshake_failure
» в том случае, если выработка секретных параметров (англ. negotiation
) была неудачно завершена по причине того, что сервер запросил более защищенные шифры чем те, которые использует клиент. Данная ошибка всегда является критической.
internal_error
Внутренняя ошибка, не относящаяся к узлу или правильности протокола (такая как сбой распределения памяти (англ. memory allocation failure)), не позволяет продолжить выполнение приложения. Данная ошибка всегда является критической.
user_canceled
Рукопожатие сбрасывается по причине, не относящейся к сбою в протоколе. В том случае, если пользователь отменил операцию после завершенного рукопожатия, более приемлемым вариантом будет закрыть соединение, выслав сообщение «close_notify
». Данная ошибка, в общем случае, будет иметь уровень предупреждения.
no_renegotiation
Сообщение посылается клиентом в ответ на hello-запрос [11] или сервером в ответ на клиентское «hello
» (англ. client hello) [12] после начального процесса рукопожатия. При получении двух указанных типов сообщений, обычно, происходит процесс пересогласования параметров (англ. renegotiation); но если пересогласование неприемлемо, реципиент вышеуказанных сообщений должен ответить данным оповещением. В этот момент сторона, отправившая запрос и получившая в ответ данное сообщение, должна решить будет ли она продолжать соединение. Один из случаев, когда соединение может быть продолжено – сервер создал и запустил дочерний процесс (англ. to spawn a process) для выполнения некоторого запроса (англ. to satisfy a request); в этом случае запущенный процесс мог уже получить параметры безопасности (длина ключа, параметры аутентификации и т. п.) на старте соединения и передать изменения в этих параметрах после этого момента было бы довольно сложно. Данное сообщение всегда будет иметь уровень предупреждения.
unsupported_extension
Неподдерживаемое расширение. Сообщение посылается клиентом, который получил расширенное серверное сообщение «hello
», содержащее расширение, которое не может быть помещено в клиентское сообщение «hello
». Данная ошибка всегда является критической.
Новые значения кодов оповещений, назначаемые IANA, описываются в Разделе 12 данного стандарта [13].
7.3. Обзор протокола рукопожатия
Криптографические параметры состояния сессии [14] создаются протоколом рукопожатия TLS, который работает поверх уровня записи TLS (англ. TLS record layer) [15]. Когда клиент и сервер начинают впервые коммуницировать через протокол TLS, они согласовывают версию протокола, выбирают криптографические алгоритмы, а также могут дополнительно аутентифицировать друг друга, и задействовать методы шифрования с открытым ключом (англ. public key) для генерации общих секретов.
Протокол рукопожатия TLS включает в себя следующие шаги:
Обмен hello-сообщениями для согласования алгоритмов, обмена случайными значениями, и контроля за тем, возобновляется сессия или параметры соединения согласовываются заново;
Обмен необходимыми криптографическими параметрами для того, чтобы позволить клиенту и серверу выработать предварительный секрет (англ. premaster secret);
Обмен сертификатами и криптографической информацией для того, чтобы клиент и сервер могли аутентифицировать друг друга;
Генерация основного секрета (англ. master seсret) из предварительного секрета и случайных чисел, которыми обменялись клиент и сервер;
Обеспечение уровня записи параметрами безопасности;
Обеспечение возможности того, чтобы клиент и сервер могли проверить, что противоположная сторона рассчитала те же самые секретные параметры и то, что рукопожатие прошло без какого-либо внешнего вмешательства.
Нужно иметь ввиду, что верхние уровни не должны чрезмерно полагаться на то, что TLS всегда будет вырабатывать максимально возможные параметры безопасности при соединении двух узлов. Существует большое количество способов, при которых злоумышленник во время MITM-атаки [16] может попытаться заставить два узла перейти на минимально поддерживаемый ими метод безопасности. Протокол был разработан для минимизации этого риска, но возможность для атаки все еще сохраняется: например, злоумышленник может блокировать доступ к порту, через который служба безопасности отправляет данные или может попытаться заставить узлы соединяться через неаутентифицированный канал связи. Фундаментальное правило при этом – верхние уровни должны знать о своих требованиях безопасности и никогда не передавать информацию через канал, имеющий требования безопасности ниже, чем у них самих. Протокол TLS обеспечивает безопасность в той степени, в какой определенный криптонабор (англ. cipher suite) может обеспечить этот уровень безопасности: если при обмене данными с хостом, чей сертификат безопасности был проверен, при выработке секретных параметров используется блочный шифр 3DES с обменом RSA-ключами размером 1024-бит, ожидается, что верхний уровень должен обеспечивать такой же уровень безопасности.
Заявленные цели достигаются при работе протокола рукопожатия, работа которого может быть кратко представлена как:
Клиент посылает сообщение
ClientHello
, на которое сервер должен ответить своим сообщениемServerHello
, либо сбросить соединение при возникновении критической ошибки.Сообщения
ClientHello
иServerHello
используются для установления усиленных параметров безопасности при соединении между клиентом и сервером.Сообщения
ClientHello
иServerHello
устанавливают следующие атрибуты: версия протокола, идентификатор сессии (Session ID
), используемый криптонабор, метод сжатия.Дополнительно генерируются и обмениваются два случайных значения:
ClientHello.random
иServerHello.random
.
Действующие правила обмена ключами используют до 4 видов сообщений: серверный сертификат (server Certificate
), ServerKeyExchange
[17], клиентский сертификат (client Certificate
) и ClientKeyExchange
[18]. Новые методы обмена ключами могут быть созданы путем определения формата указанных сообщений и задания правил использования сообщений для согласования клиентом и сервером общего секрета. Этот секрет должен быть достаточно большой длины – текущие методы обмена ключами определяют минимальный размер ключа в 46 байт (368 бит).
В том случае, если сервер должен быть аутентифицирован, после своего hello-сообщения (ServerHello
) [19] сервер высылает свой сертификат в сообщении Certificate
[20]. Дополнительно, если требуется (например, если у сервера нет сертификата или у него есть сертификат только для подписи), сервером может быть выслано сообщение ServerKeyExchange
. Если сервер аутентифицирован, он может потребовать от клиента выслать его сертификат, если это приемлемо для выбранного криптонабора. После этого сервер высылает сообщение ServerHelloDone
[21], показывая, что hello-стадия (англ. hello-message phase) рукопожатия завершена. В этот момент сервер будет ждать ответа от клиента. Если сервер выслал сообщение CertificateRequest
[22], то клиент обязан отправить сообщение Certificate
[23]. После этого клиентом высылается сообщение ClientKeyExchange
, содержимое которого будет зависеть от алгоритмов создания открытого ключа, выбранных в сообщениях ClientHello
[24] и ServerHello
. Если клиент отправил сертификат с возможностью подписи, то им же высылается подписанное цифровой подписью сообщение CertificateVerify
[25] для того, чтобы явным образом удостоверить владение закрытым ключом сертификата.
В этот момент клиентом отправляется сообщение ChangeCipherSpec
и клиент копирует ожидающую спецификацию параметров шифрования в рабочую спецификацию параметров шифрования. После чего клиент немедленно отправляет сообщение Finished
[26] уже с использованием новых алгоритмов, ключей и секретов. В ответ сервер высылает свое собственное сообщение ChangeCipherSpec
, перемещает ожидающую спецификацию параметров шифрования (Cipher Spec) в рабочую спецификацию параметров шифрования, и посылает свое сообщение Finished
уже с использованием новых параметров шифрования. В этот момент рукопожатие завершается и клиент с сервером могут начать обмениваться данными уровня приложения (см. схему ниже). Данные приложения (англ. application data) не должны высылаться до завершения первого рукопожатия (до того как будет установлен криптонабор отличный от TLS_NULL_WITH_NULL_NULL
).
Клиент СерверClientHello -------->
ServerHello
Certificate*
ServerKeyExchange*
CertificateRequest*
<-------- ServerHelloDone
Certificate*
ClientKeyExchange
CertificateVerify*
[ChangeCipherSpec]
Finished -------->[ChangeCipherSpec]
<-------- Finished
Схема 1. Порядок сообщений (поток сообщений) при полном рукопожатии
Данные приложения <-------> Данные приложения
* Дополнительные или зависящие от ситуации сообщения, которые высылаются не всегда.
Замечание: во избежание потери скорости в канале передачи данных сообщение ChangeCipherSpec является независимым типом содержимого протокола TLS и, строго говоря, не является сообщением TLS-рукопожатия [27] [28].
В тот момент, когда клиент и сервер решают возобновить сессию, в которой некоторое время не было передачи данных, либо продублировать рабочую сессию (вместо того, чтобы вырабатывать новые параметры безопасности), порядок обмена сообщения (англ. message flow) будет следующий:
Клиент отправляет серверу сообщение
ClientHello
с использованием идентификатора сессии (Session ID
), которая должна быть возобновлена.В этом случае сервер проверяет свой сессионный кеш для сопоставления идентифкатора.
Если сопоставление прошло успешно и сервер желает заново установить сессию с заданным состоянием сессии, то сервер отправляет сообщение
ServerHello
с тем же самым значениемSession ID
.В этот момент и клиент и сервер должны послать сообщения
ChangeCipherSpec
и продолжить обмен сообщениями до сообщенийFinished
.
Как только сессия была повторно установлена клиент и сервер могут начать обмениваться данными приложения. (См. схему ниже). Если идентификатор сессии не найден в кеше сервера, то сервер генерирует новый код сессии, а TLS-клиент и TLS-сервер осуществляют полное рукопожатие.
Клиент СерверClientHello -------->
ServerHello
[ChangeCipherSpec]
<-------- Finished
[ChangeCipherSpec]Finished -------->
Данные приложения <-------> Данные приложения
Схема 2. Порядок сообщений (поток сообщений) при сокращенном рукопожатии.
Содержимое и значение каждого сообщения будут подробно изложены в следующих разделах стандарта.
7.4. Протокол рукопожатия
Протокол рукопожатия TLS является одним из определенных данным стандартом высокоуровневых клиентов протокола записи TLS (TLS Record Protocol [29]). Протокол используется для выработки секретных параметров сессии. Сообщения рукопожатия предоставляются протоколу записи TLS, где они инкапсулируются внутри одной или нескольких структур TLSPlaintext
, которые затем обрабатываются и пересылаются так, как это было указано текущим рабочим состоянием сессии.
Ниже приводится формат структуры Handshake
, а также перечисление, задающее поле типа HandshakeType
(тип рукопожатия):
enum {
hello_request(0), client_hello(1), server_hello(2),
certificate(11), server_key_exchange (12),
certificate_request(13), server_hello_done(14),
certificate_verify(15), client_key_exchange(16),
finished(20), (255)
} HandshakeType;
struct {
HandshakeType msg_type; /* тип рукопожатия */
uint24 length; /* число байт в сообщении */
select (HandshakeType) {
case hello_request: HelloRequest;
case client_hello: ClientHello;
case server_hello: ServerHello;
case certificate: Certificate;
case server_key_exchange: ServerKeyExchange;
case certificate_request: CertificateRequest;
case server_hello_done: ServerHelloDone;
case certificate_verify: CertificateVerify;
case client_key_exchange: ClientKeyExchange;
case finished: Finished;
} body;
} Handshake;
Сообщения протокола рукопожатия представлены ниже в том порядке, в котором они должны посылаться; отправка сообщений рукопожатия в неправильном порядке приводит к критической ошибке. Однако, ненужные сообщения рукопожатия могут быть пропущены. Существует одно исключение из этого правила: сообщение Certificate
отправляется в рукопожатии дважды, (от сервера к клиенту, а затем – от клиента к серверу), но описывается только для первого случая. Единственное сообщение, которое никак не привязано к этому порядку – сообщение HelloRequest
, которое может быть выслано в любой момент, но клиенту рекомендуется игнорировать его в том случае, если оно приходит в процессе уже начатого рукопожатия.
Значения для новых типов рукопожатия присваиваются IANA и описываются в разделе 12 [30].
7.4.1. Hello-сообщения
Сообщения hello-стадии используются для обмена усиленными параметрами безопасности между клиентом и сервером. При старте новой сессии шифрование состояния соединения уровня записи, хеш, а также алгоритмы сжатия инициализируются со значением null. Для повторной выработки секретных параметров используется рабочее состояние соединения.
7.4.1.1. Hello-запрос (Hello Request)
Сообщение HelloRequest
может быть отправлено сервером в любой момент времени.
Значение сообщения:
Запрос
HelloRequest
является уведомлением, при получении которого клиенту рекомендуется заново начать процесс согласования секретных параметров. Если у клиента есть такая возможность, ему рекомендуется выслать в ответ сообщениеClientHello
.Данное сообщение не несет в себе задачи установить какая из сторон является клиентом, а какая – сервером. Оно нужно только лишь для перезапуска процесса рукопожатия.
Серверу не рекомендуется высылать сообщение
HelloRequest
сразу же после начального соединения с клиентом, поскольку в этот момент именно клиент обязан выслать сообщениеClientHello
.
Данное сообщение будет проигнорировано клиентом, если он уже находится в процессе согласования параметров сессии. Если клиент не желает заново согласовывать параметры сессии, он может проигнорировать данное сообщение, или же ответить оповещением no_renegotiation
. Поскольку протоколом оговаривается, что сообщения рукопожатия предшествуют передаче данных приложения, ожидается, что новое рукопожатие начнется не раньше, чем от клиента будет получено какое-либо количество записей. Если сервер отправляет сообщение HelloRequest
, но не получает в ответ сообщение ClientHello
, он может закрыть соединение с сообщением о критической ошибке.
После отправки сообщения HelloRequest
, серверам не рекомендуется повторять этот запрос до тех пор, пока не будет закончен следующим за ним процесс согласования параметров.
Структура сообщения:
struct { } HelloRequest;
Данное сообщения не должно включаться в хеш сообщений, создаваемый во время рукопожатия, и используемый в сообщениях Finished
и сообщениях проверки сертификатов (CertificateVerify
).
7.4.1.2. Клиентское hello-сообщение
Данное сообщение посылается:
При первом соединении клиента и сервера требуется посылать сообщение
ClientHello
в качестве первого сообщения;также, клиент может послать сообщение
ClientHello
в ответ на сообщениеHelloRequest
или по своей собственной инициативе для повторной выработки (англ. renegotiation) параметров безопасности при существующем соединении.
Структура сообщения:
Сообщение ClientHello
включает в себя структуру со случайными значениями (Random
), которая впоследствии будет использоваться при работе протокола:
struct {
uint32 gmt_unix_time;
opaque random_bytes[28];
} Random;
gmt_unix_time
Текущее время и дата в стандартном 32-битном UNIX-формате (количество секунд, прошедших с 00:00 (UTC[31]) 1 января 1970 года за вычетом дополнительных секунд (англ. leap seconds [32]) согласно внутреннему времени отправителя сообщения. Для базовой работы протокола TLS не требуется того, чтобы часы были правильно установлены; протоколы высшего уровня, либо протоколы приложений могут вводить дополнительные требования. Имя поля по историческим причинам имеет приставку GMT (среднее время по Гринвичу) – которое было предшественником текущего мирового стандарта UTC.
random_bytes
Значение размером 28 байт, сгенерированное защищенным генератором случайных чисел.
Сообщение ClientHello
включает в себя идентификатор сессии (SessionID
) изменяемой длины. Данное значение идентифицирует (если не является пустым) сессию между одними и теми же клиентом и сервером, чьи параметры безопасности клиент желает повторно использовать. Идентификатор сессии может быть взят из более раннего соединения, текущего соединения, или же из другого активного на данный момент соединения. Второй вариант может быть использован, если клиент желает только обновить структуры со случайными величинами и производные от них значения во время какого-либо соединения. Третий вариант дает возможность установить несколько независимых безопасных соединений без повторения полного протокола рукопожатия. Эти независимые соединения могут происходить либо одновременно, либо последовательно во времени; SessionID
становится действительным (англ. valid) в тот момент, когда сгенерировавший его процесс рукопожатия завершается обменом сообщениями Finished
и продолжает действовать до тех пор, пока не будет удален в связи с истечением времени сессии, или по причине возникновения критической ошибки во время соединения, принадлежащему данной сессии. Содержимое идентификатора SessionID
определяется стороной сервера.
Внимание: так как значение SessionID
передается без шифрования и непосредственной защиты кодом аутентификации сообщения (MAC), сторона сервера не должна помещать внутри этого значения конфиденциальную информацию или же допускать бреши в системе безопасности при получении поддельных идентификаторов сессии. (При этом данные рукопожатия целиком, включая и значение SessionID
[33], защищены путем обмена сообщениями Finished
в конце процесса рукопожатия).
Список криптонаборов, передаваемых от клиента серверу в сообщении ClientHello
, содержат комбинации криптографических алгоритмов, поддерживаемых клиентом исходя из его предпочтений (наиболее предпочтительный криптонабор идет первым). Каждый криптонабор определяет алгоритм обмена ключами, алгоритм канального шифрования данных (включая длину секретного ключа), алгоритм создания MAC и псевдослучайную функцию (англ. PRF). Сервер выбирает какой-либо криптонабор или же, если доступного для него криптонабора не имеется, возвращает сообщение о невозможности провести рукопожатие (handshake_failure
) и закрывает соединение. Если список содержит криптонаборы, которые сервер не распознает, не поддерживает, или не желает использовать, сервер игнорирует данные криптонаборы и работает только с оставшимися криптонаборами.
uint8 CipherSuite[2]; /* Селектор криптонабора */
Сообщение ClientHello
содержит также список поддерживаемых клиентом алгоритмов сжатия, расположенных в порядке клиентских предпочтений.
enum { null(0), (255) } CompressionMethod;
Таким образом, вся структура сообщения ClientHello
выглядит следующим образом:
struct {
ProtocolVersion client_version;
Random random;
SessionID session_id;
CipherSuite cipher_suites<2..2^16-2>;
CompressionMethod compression_methods<1..2^8-1>;
select (extensions_present) {
case false:
struct {};
case true:
Extension extensions<0..2^16-1>;
};
} ClientHello;
TLS позволяет, чтобы за полем compression_methods
(методы сжатия) следовал блок расширений. Наличие расширений может быть обнаружено при наличии дополнительных байт данных идущих после поля compression_methods
в сообщении ClientHello
. Обратите внимание, что подобный способ обнаружения дополнительных данных отличается от нормального способа, используемого в протоколе TLS для обнаружения поля переменной длины, но он используется для совместимости с теми реализациями TLS, когда расширения еще не были определены [34].
client_version
Версия протокола TLS, которую клиент желает использовать при соединении во время сессии. Рекомендуется, чтобы это была последняя (с наибольшим значением) версия, поддерживаемая клиентом. Для TLS версии 1.2 данное значение будет равно 3.3 [35] (см. Прил. E для подробной информации об обратной совместимости).
random
Сгенерированная клиентом структура со случайными величинами.
session_id
Идентификатор сессии, который клиент желает использовать для данного соединения. Данное поле остается пустым в случае, если значение session_id
недоступно, или же клиент желает создать новые параметры безопасности.
cipher_suites
Список криптографических опций, поддерживаемых клиентом, в котором первым пунктом идет предпочтительный для клиента криптонабор. Если поле session_id
не является пустым (что подразумевает запрос на возобновление сессии), то данный вектор должен содержать, как минимум, список cipher_suite
, уже существующий в возобновляемой сессии. Значения данного поля определены в Прил. А.5.
compression_methods
Список поддерживаемых клиентом методов сжатия, расположенных в порядке предпочтения клиента. Если поле session_id
не является пустым (что подразумевает запрос на возобновление сессии), то данное поле должно включать список compression_method
возобновляемой сессии. Данный вектор должен содержать, и все реализации должны поддерживать значение CompressionMethod.null
. Таким образом, клиент и сервер всегда могут установить общий для них обоих метод сжатия.
extensions
Клиент может сделать запрос серверу на включение расширенной функциональности (расширений) в работу сессии, путем отправки данных в поле extensions
. Действующий формат расширений TLS описан в п.7.4.1.4.
В том случае, если клиент запрашивает о включении дополнительной функциональности, задействуя то или иное расширение, и данная функциональность не поддерживается сервером, клиент может окончить обмен сообщениями с сервером. Сервер должен принимать сообщения ClientHello
как с полем, так и без поля extensions
, и (как и для всех других сообщений) должен проверять, что общее количество данных в сообщении соответствует его формату; если этого не происходит сервер должен выслать сообщение о критической ошибке decode_error
.
После отправки сообщения ClientHello
клиент ждет ответного сообщения ServerHello
. Любые другие сообщения рукопожатия, возвращаемые сервером, за исключением сообщения HelloRequest, рассматриваются сервером в качестве критической ошибки.
7.4.1.3. Серверное hello-сообщение
Данное сообщение отправляется сервером в ответ на сообщение ClientHello
только в том случае, если он способен найти приемлемый набор алгоритмов. Если ему не удается найти подобный набор, сервер отвечает сообщением о критической ошибке рукопожатия.
Структура сообщения:
struct {
ProtocolVersion server_version;
Random random;
SessionID session_id;
CipherSuite cipher_suite;
CompressionMethod compression_method;
select (extensions_present) {
case false:
struct {};
case true:
Extension extensions<0..2^16-1>;
};
} ServerHello;
Наличие расширений может быть определено по наличию в структуре сообщения данных, идущих после поля compression_method
.
server_version
В общем случае данное поле содержит значение меньшее либо равное версии, указанной клиентом в его hello-сообщении, но в любом случае не больше самой высокой поддерживаемой сервером версии протокола. Для версии TLS 1.2 значение поля будет равно 3.3 (см. Прил. E для подробной информации об обратной совместимости).
random
Данная структура со случайными величинами должна генерироваться сервером независимо от структуры ClientHello.random
.
session_id
Идентификатор сессии, соответствующей текущему соединению. Если значение ClientHello.session_id
не является пустым, сервер обязан просмотреть свой сессионный кеш для поиска соответствия. Если соответствие найдено и сервер желает установить новое соединение с определенным состоянием сессии, сервер отвечает тем же сам значением, которое было передано клиентом. Это является признаком того, что сессия возобновлена и стороны должны перейти к обмену сообщениями Finished
. В противном случае значение поля будет отличаться от значения поля, полученного от клиента, что будет сигнализировать о начале новой сессии. Сервер может ответить пустым значением поля session_id
, что означает то, что сессия не будет кешироваться и, таким образом, не сможет быть восстановлена. При возобновлении сессии она должна работать с тем же криптонабором, который был согласован с клиентом при самом первом рукопожатии сессии. Обратите внимание, что для сервера не существует обязательного требования возобновлять сессию, если ему было предоставлено значение session_id
. Клиент должен быть готов к полному согласованию параметров во время любого рукопожатия, включая и согласование новых криптонаборов.
cipher_suite
Единственный криптонабор, выбранный сервером из списка, задаваемого полем ClientHello.cipher_suites
. При возобновлении сессии данное значение берется из состояния возобновляемой сессии.
compression_method
Единственный алгоритм сжатия, выбранный сервером из списка, задаваемого полем ClientHello.compression_methods
. При возобновлении сессии данное значение берется из состояния возобновляемой сессии.
extensions
Список расширений. Обратите внимание, что в списке сервера не содержится никаких других расширений, кроме тех, которые были указаны в списке клиента.
7.4.1.4. Расширения hello-сообщений
Формат расширения следующий:
struct {
ExtensionType extension_type;
opaque extension_data<0..2^16-1>;
} Extension;
enum {
signature_algorithms(13), (65535)
} ExtensionType;
Здесь:
"
extension_type
" указывает на определенный тип расширения;"
extension_data
" содержит информацию, касающуюся определенного типа расширения.
Начальный набор расширений определен в отдельном документе [TLSEXT] [36]. Список поддерживаемых типов расширений регулируется IANA по принципам, указанным в разделе 12 [37].
В сообщении ServerHello
не должен появляться тип расширения, не указанный в соответствующем сообщении ClientHello
. Если в полученном клиенте сообщении ServerHello
указывается тип расширения, на использование которого клиент не подавал запроса в соответствующем сообщении ClientHello
, то клиент должен прервать рукопожатие с сообщением о критической ошибке unsupported_extension
.
Тем не менее, в рамках развития протокола в будущем могут быть созданы «серверно-ориентированные» расширения. Такое расширение (предположим, типа x) будет требовать, чтобы сначала клиент отправил расширение типа x с пустым полем extension_data
в своем сообщении ClientHello
для того, чтобы показать, что он поддерживает расширение данного типа. В этом случае клиент сообщает о способности понимать конкретный тип расширения, а сервер принимает подобное предложение.
Если в сообщениях ClientHello
или ServerHello
присутствует более одного типа расширений, они могут следовать в произвольном порядке. В сообщении не должно присутствовать два или более расширения одного типа.
Обратите внимание, что список расширений может быть послан либо при создании новой сессии, либо при запросе на возобновление уже созданной. Более того, клиент, запрашивая возобновление сессии, в общем случае не знает примет ли сервер его запрос, таким образом, рекомендуется, чтобы он высылал в своем сообщении указанные им ранее расширения как если бы, он делал запрос на создание новой сессии.
В общем случае спецификация каждого типа расширения должна описывать алгоритм его действия как при полном рукопожатии, так и возобновлении сессии. Большинство существующих на данный момент расширений [38] релевантны только для создания сессии: при возобновлении сессии сервер не обрабатывает эти расширения в сообщении ClientHello
и не включает их в сообщение ServerHello
. Однако, при возобновлении сессии некоторые расширения могут вести себя по-другому.
При работе данного протокола могут возникнуть довольно узкие (и не особо) места при взаимодействии между расширениями с новой функциональностью и уже существующими расширениями, что может вылиться в существенное снижение общей безопасности. При разработке новых расширений следует учитывать некоторые моменты:
Некоторые случаи, при которых сервер не согласен использовать то или иное расширение, являются условиями для возникновения ошибки. Но в некоторых случаях сервер выдает отказ в поддержке конкретного расширения. В общем случае, в первом варианте рекомендуется выдавать сообщение об ошибке, а во втором – отправлять ответ сервера с поддерживаемыми расширениями.
Расширения, насколько это возможно, должны быть построены таким образом, чтобы предотвратить любую атаку, которая вынуждает использовать (либо не использовать) особенности (англ.
feature
) его работы при манипуляции сообщениями рукопожатия. Данный принцип должен соблюдаться несмотря на то, имеются или нет опасения того, что указанная особенность способствует возникновению проблем в безопасности.Часто для предотвращения таких угроз будет достаточным факта того, что поля расширений будут включаться во входные данные хеша сообщений
Finished
, но особенное внимание необходимо уделить в том случае, когда расширение изменяет смысл сообщений, посылаемых во время стадии рукопожатия. Разработчики и реализаторы должны знать факт того, что до того момента пока сообщение не будет аутентифицировано, злоумышленник может изменить сообщение и внедрить туда свои расширения, или же удалить или заменить указанные в нем расширения.Вполне вероятно, что появится техническая возможность заменять при помощи расширений главные аспекты работы протокола TLS; например, принцип согласования используемого криптонабора. Делать это не рекомендуется; наиболее приемлемым вариантом будет создание новой версии TLS – в особенности из-за того, что алгоритмы рукопожатия TLS имеют специфическую защиту против атак отката версии (англ.
version rollback attacks
), которая основывается на понижении версии протокола. Возможность отката версии должна стать одним из главных соображений при создании каких-либо значительных изменений в конструкцию протокола.
7.4.1.4.1. Расширение "алгоритмы подписи"
Расширение "signature_algorithms
" используется клиентом для указания серверу какие пары алгоритмов подписи/хеш-функции могут быть задействованы для цифровой подписи. Поле "extension_data
" данного расширения содержит значение "supported_signature_algorithms
":
enum {
none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5),
sha512(6), (255)
} HashAlgorithm;
enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) }
SignatureAlgorithm;
struct {
HashAlgorithm hash;
SignatureAlgorithm signature;
} SignatureAndHashAlgorithm;
SignatureAndHashAlgorithm
supported_signature_algorithms<2..2^16-2>;
Каждое значение SignatureAndHashAlgorithm
содержит единственную пару хеш/подпись, которую клиент желает подтвердить. Значения расположены в порядке снижения приоритета пар.
Обратите внимание: из-за того, что не все алгоритмы подписи и алгоритмы хэширования могут быть приняты реализациями протокола (напр., возможно использование DSA с SHA-1, но не с SHA-256) все алгоритмы в данном разделе приводятся в парах.
hash
Данное поле указывает на возможный к использованию алгоритм хеширования. Значения указывают на отсутствие функции хеширования, алгоритмы MD5 [MD5] [39], SHA-1,SHA-224, SHA-256, SHA-384, и SHA-512 соответственно[SHS] [40]. Значение "none
" добавлено для будущей расширяемости в случае работы с алгоритмом подписи, не требующим хеширования перед подписанием данных.
signature
Данное поле указывает на возможные алгоритмы подписи. Значения указывают на анонимную подпись, алгоритмы RSASSA-PKCS1-v1_5 [PKCS1][41], DSA [DSS] [42] [ECDSA][43], соответственно. Значение "anonymous
" (анонимная) в данном контексте не несет никакой смысловой нагрузки, но используется в разделе 7.4.3 (серверное сообщение об обмене ключами). Оно не должно присутствовать в данном расширении.
Семантика данного расширения в некоторой степени сложна, поскольку криптонаборы указывают на допустимый алгоритм подписи, но не на алгоритмы хеширования. В разделах 7.4.2 и 7.4.3 определены соответствующие правила для криптонаборов.
Если клиент поддерживает только установленные по умолчанию алгоритмы подписи и хеширования (приведенные в этом пункте), он может опустить расширение signature_algorithms
. Если клиент не поддерживает установленные по умолчанию алгоритмы, либо поддерживает другие алгоритмы подписи и хеширования (и желает использовать их для проверки отправленных сервером сообщений, например серверных сообщений Certificate
и ServerKeyExchange
), он должен выслать в своем hello-сообщении также и расширение signature_algorithms
с перечислением алгоритмов, которые он желает использовать.
В том случае, если клиент не высылает в своем hello-сообщении расширение signature_algorithms
, сервер обязан предпринять следующие шаги:
Если согласованный алгоритм обмена ключами является одним из следующих –
RSA
,DHE_RSA
,DH_RSA
,RSA_PSK
,ECDH_RSA
,ECDHE_RSA
– сервер должен вести себя так как если бы клиент отправил значение {sha1, rsa
}[44].Если согласованный алгоритм обмена ключами является одним из следующих –
DHE_DSS
,DH_DSS
– сервер должен вести себя так как если бы клиент отправил значение {sha1, dsa
}.Если согласованный алгоритм обмена ключами является одним из следующих –
ECDH_ECDSA
,ECDHE_ECDSA
– сервер должен вести себя так как если бы клиент отправил значение {sha1, ecdsa
}.
Обратите внимание: данное правило является изменением по сравнению с протоколом TLS 1.1, в котором нет четких указаний, касающихся подобных ситуаций, но в качестве практической меры следует сделать допущение, что каждый из узлов поддерживает протоколы MD5 и SHA-1.
Обратите внимание: данное расширение не распространяется на версии TLS, предшествующие версии 1.2. Клиент не должен включать его в свое сообщение ClientHello
, если он собирается работать с предыдущими версиями TLS. Однако, даже если клиент и включит его в свое сообщение, правила, определенные в [TLSEXT], обязывают сервер игнорировать неподдерживаемые ими расширения.
Сервер не должен отправлять сообщение с данным расширением. TLS-сервер должен иметь возможность получить сообщение с данным расширением.
При возобновлении сессии данное расширение не включается в сообщение ServerHello
, а при наличии данного расширения в сообщении ClientHello
сервер его игнорирует.
[1] Не следует смешивать термины «процесс рукопожатия» (англ. handshaking) и «рукопожатие» (англ. handshake). Процесс рукопожатия является более широким термином, который включает в себя три подпротокола: протокол рукопожатия (тж. согласования параметров) (англ. handshake protocol), оповещений (alert protocol), изменения параметров шифрования (англ. change cipher spec protocol). Таким образом, термин «процесс рукопожатия» включает в себя термин «рукопожатие» (Прим. перев.).
[2] Приложение B данного стандарта определяет TLS-сессию как: связь (англ. association) между клиентом и сервером, которая создается протоколом рукопожатия. Сессии определяют набор криптографических параметров безопасности, которые могут не меняться в течение многих соединений (англ. connection). Основная цель создания сессии: избежать лишних согласований новых параметров безопасности при каждом соединении (Прим. перев.).
[3] Housley, R., Polk, W., Ford, W., and D. Solo, "Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile", RFC 3280, April 2002. – На данный момент стандарт устарел, актуальная версия: D. Cooper, S. Santesson, S. Farrell, S. Boeyen, R. Housley, W. Polk, "Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile", RFC 5280, May 2008. В основе этого стандарта лежит более фундаментальный стандарт ITU-T Recommendation X.509 | ISO/IEC 9594-8, "Information technology - Open Systems Interconnection - The Directory: Public-key and attribute certificate frameworks". (Прим. перев.).
[4] Как видно, эти три параметра входят в число параметров безопасности, описанных в Разд. 6.1 и в Прил. A.6 данного Cтандарта. Криптографические атрибуты входят в состав структуры SecurityParameters
(тж. см. Разд. 6.1 и Прил. A.6) (Прим. перев.).
[5] По-другому – возобновляемая сессия или нет. То есть, существует ли возможность начать новое соединение в рамках текущей сессии с уже согласованными параметрами безопасности или же при новом соединении необходимо будет создавать и новую сессию с согласованием новых параметров безопасности (Прим. перев.).
[6] При атаке отсечения злоумышленник внедряет в сообщение TCP-код, сигнализирующий об окончании сообщения, не позволяя, таким образом, принять остаток сообщения. Для предотвращения этого начиная с SSL 3.0 было введено закрывающее рукопожатие для того, чтобы реципиент точно знал, в какой момент будет заканчиваться сообщение. См. тж. здесь (Прим. перев.).
[7] Стандарт TLS разрабатывается организацией IETF (Internet Engineering Task Force), которая придерживается сетевой модели со стеком протоколов TCP/IP, в которой после транспортного уровня идет сразу прикладной уровень (уровень приложения). В сетевой модели OSI (Open Systems Interconnection) между транспортным и прикладным уровнем существуют еще два уровня – сеансовый уровень и уровень представления (Прим. перев.).
[8] См. подробнее п. 6.2.3. данного стандарта.
[9] Moeller, B., "Security of CBC Ciphersuites in SSL/TLS: Problems and Countermeasures", http://www.openssl.org/~bodo/tls-cbc.txt. О режиме CBC-шифрования см. тж. п. 6.2.3.2 данного стандарта.
[10] Сообщение «Finished
» является финальным сообщением, посылаемым сервером клиенту во время выполнения протокола рукопожатия TLS. Данное сообщение говорит о том, что обмен ключами и операция аутентификация были выполнены успешно. (см. тж. п. 7.4.9 данного стандарта) (Прим. перев.).
[11] Hello-запрос (англ. hello request) является уведомлением о том, что клиент должен начать заново процесс выработки секретных параметров (англ. negotiation). (см. тж. п. 7.4.1.1 данного стандарта) (Прим. перев.).
[12] Клиентские «hello» рассматриваются в п. 7.4.1.2 данного стандарта.
[13] Коды сообщений об ошибках добавляются в регистр «TLS Alerts» (Оповещения TLS) раздела регистров «Transport Layer Security (TLS) Parameters», доступный по адресу: https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-6 (Прим. перев.).
[14] См. Раздел 6.1. данного стандарта.
[15] См. Раздел 6.2. данного стандарта.
[16] MITM-атака, тж. «атака man-in-the-middle», атака «человек посередине» - тип атаки, при которой злоумышленник внедряется в канал связи между двумя соединяющимися сторонами и тайно пропускает весь трафик через себя (Прим. перев.).
[17] См. пункт 7.4.3. данного стандарта.
[18] См. пункт 7.4.7. данного стандарта.
[19] См. пункт 7.4.1.3. данного стандарта.
[20] См. пункт 7.4.2. данного стандарта.
[21] См. пункт 7.4.5. данного стандарта.
[22] См. пункт 7.4.4. данного стандарта.
[23] См. пункт 7.4.6. данного стандарта.
[24] См. пункт 7.4.1.2. данного стандарта.
[25] См. пункт 7.4.8. данного стандарта.
[26] См. пункт 7.4.9. данного стандарта.
[27] Описание протокола изменения параметров шифрования (Change Cipher Spec) содержится в Разд. 7.1. данного стандарта.
[28] В разделе Errata (Ошибки) (https://www.rfc-editor.org/errata/eid4007) данного стандарта содержится предложение о перефразировке данного абзаца:
Для того, чтобы сообщение ChangeCipherSpec
не передавалось вместе с другими фрагментами рукопожатия в одной записи, ChangeCipherSpec
является независимым типом содержимого протокола TLS и, по сути, не является сообщением TLS-рукопожатия. Во избежание потери скорости в канале передачи данных сообщение ChangeCipherSpec
отправляется как от клиента, так и от сервера.
Обоснование: оригинальный текст можно трактовать так, будто мы можем отправлять ChangeCipherSpec асинхронно. Это небезопасно, так как может стать причиной уязвимости CCS Injection (ChangeCipherSpec Ingection).
Об уязвимости CCS Injection см. здесь, здесь и здесь. (Прим. перев.).
[29] Описание протокола записи TLS (TLS record protocol) содержится в Разд. 6. данного стандарта.
[30] Кодовые значения для существующих типов рукопожатия добавляются в регистр «TLS HandshakeType» (Типы рукопожатия TLS) раздела регистров «Transport Layer Security (TLS) Parameters», доступный по адресу: https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-7 (Прим. перев.).
[31] UTC – всемирное координированное время, (англ. Coordinated Universal Time, фр. Temps Universel Coordonné). Всемирный стандарт времени. Для повсеместного использования, когда не требуется высокая точность, может использоваться как аналог среднего времени по Гринвичу (GMT) или всемирного времени UT1 (Прим. перев.).
[32] Дополнительные секунды (тж. високосные секунды, англ. leap seconds) – дополнительные секунды, прибавляемые к UTC для координации его со всемирным временем UT1. Начиная с 1972 года к UTC было добавлено 27 дополнительных секунд. В связи с ускорением вращения Земли в будущем возможно не прибавление, а вычитание секунд из UTC (Прим. перев.).
[33] В разделе Errata (Ошибки) (https://www.rfc-editor.org/errata/eid5036) данного стандарта содержится предложение о введении дополнительного поля "Session ID Length
" длиной 1 байт в сообщениях ClientHello
и ServerHello
.
Обоснование: при пропуске TLS-трафика через программу-анализатор WireShark в сетевых пакетах всегда присутствует поле "Session ID Length" с записанным в него значением либо 0, либо 32. (Прим. перев.).
[34] В данном стандарте описано только одно расширение – алгоритмы подписи (signature_algorithms, см. пп. 7.4.1.4. и 7.4.1.4.1 Стандарта). Основной документ, определяющий расширения TLS версии 1.2 – стандарт RFC6066 «Transport Layer Security (TLS) Extensions: Extension Definitions». Также, все поддерживаемые протоколом TLS расширения указаны в разделе «TLS ExtensionType Values» раздела регистров IANA «Transport Layer Security (TLS) Extensions» (https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#tls-extensiontype-values-1) (Прим. перев.).
[35] Поскольку протокол TLS 1.0 выпущен на основе протокола SSL 3.0, то в целях исторической преемственности версия TLS 1.0 кодируется значением {3, 1}. Соответственно, версия протокола TLS 1.2 кодируется значением {3, 3} (Прим. перев.).
[36] D. Eastlake 3rd, «Transport Layer Security (TLS) Extensions: Extension Definitions», RFC6066, January 2011.
[37] См. тж. прим. 34.
[38] На момент опубликования стандарта в августе 2008 года (Прим. перев.).
[39] Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321, Апрель 1992. Стандарт обновлен стандартом: S. Turner, L. Chen, "Updated Security Considerations for the MD5 Message-Digest and the HMAC-MD5 Algorithms", RFC 6151, Март 2011.
[40] NIST FIPS PUB 180-2, "Secure Hash Standard", National Institute of Standards and Technology, U.S. Department of Commerce, August 2002. На данный момент стандарт устарел и актуален следующий стандарт: NIST FIPS PUB 180-4, "Secure Hash Standard (SHS)", National Institute of Standards and Technology, U.S. Department of Commerce, August 2015 (Прим. перев.).
[41] Jonsson, J. and B. Kaliski, "Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography Specifications Version 2.1", RFC 3447, February 2003.
[42] NIST FIPS PUB 186-2, "Digital Signature Standard", National Institute of Standards and Technology, U.S. Department of Commerce, 2000. На данный момент устарел, актуален стандарт: На август 2021 года указанный стандарт является недействующим. Действующий стандарт - NIST FIPS 186-4, "Digital Signature Standard", National Institute of Standards and Technology, U.S. Department of Commerce, 2013 (Прим. перев.).
[43] American National Standards Institute, "Public Key Cryptography for the Financial Services Industry: The Elliptic Curve Digital Signature Algorithm (ECDSA)"( Алгоритм цифровой подписи на основе эллиптических кривых), ANSI X9.62-2005, November 2005.
[44] То есть использовать алгоритм хеширования SHA-1 и алгоритм цифровой подписи – DSA. И т. д. (Прим. перев.).
[45] В рамках протокола TLS термины «клиент» и «сервер» не несут смысловой нагрузки по аналогии с этими же терминами в рамках реализации приложений клиент-серверной архитектуры. В Приложении B Стандарта клиент определен как: приложение, инициировавшее TLS-соединение. При этом особо подчеркивается, что клиент не обязательно должен инициировать соединение и на нижележащем уровне. Основное операционное отличие клиента TLS от сервера TLS в том, что сервер, в общем случае, должен быть обязательно аутентифицирован (выслать свой сертификат клиенту), в то время как для клиента нет такого обязательства (хотя он и может быть аутентифицирован, если этого требуют настройки сервера) (Прим. перев.).