Как стать автором
Обновить

Протокол безопасности транспортного уровня (TLS), версия 1.2 (RFC 5246) (Часть 1)

Время на прочтение26 мин
Количество просмотров14K
Автор оригинала: T. Dierks, E. Rescorla

T. Dierks, E. Rescorla

Протокол безопасности транспортного уровня (TLS)

Версия 1.2

Запрос на комментарии 5246 (RFC 5246) 

Август 2008

Часть 1

Другие части: Часть 2, Часть 3.1, Часть 3.2.

От переводчика

На настоящий момент (август 2021 года) мною не было найдено хоть сколько-нибудь приемлемого перевода стандарта протокола TLS версии 1.2 на русский язык. Единственный найденный перевод находится сайте protocols.ru и при всем уважению к его автору, не устраивает меня по причине неудобочитаемости и трудности восприятия. И хотя на сайте efim360.ru находится качественно выполненный перевод стандарта протокола TLS версии 1.3, многие места этого перевода могут вызвать некоторые трудности для понимания, особенно у начинающего изучать криптографию читателя. Для устранения таких «белых пятен»   и было задумано осуществить перевод стандарта протокола TLS версии 1.2 на русский язык.  

Развитием стандарта TLS занимается организация IETF (Internet Engineering Task Force). На настоящий момент протокол TLS 1.2 считается устаревшим после выхода в августе 2018 года стандарта протокола TLS 1.3. Тем не менее, спецификация протокола версии 1.2 до сих пор является наиболее распространенной версией протокола TLS, что не лишает практического смысла ее перевод на русский язык. С момента опубликования в августе 2008 года стандарта TLS 1.2 выходили другие стандарты, обновлявшие спецификацию TLS 1.2. Данные стандарты приведены в исходном тексте спецификации. Тем не менее, автор считает нужным привести их и здесь:

E. Rescorla, M. Ray, S. Dispensa, N. Oskov «Transport Layer Security (TLS) Renegotiation Indication Extension», RFC 5746, February 2010 – Устранение уязвимости во время пересогласования (англ. renegotiation) сервером и клиентом новых ключей. Описание расширения индикации пересогласования (Renegotiation Indication Extension).

M. Brown, R. Housley, «Transport Layer Security (TLS) Authorization Extensions», RFC 5878, May 2010 – Документ описывает расширения авторизации для протокола рукопожатия TLS (TLS Handshake Protocol). Расширения указываются в клиентских и серверных сообщениях «hello»[1] для подтверждения того, что обе стороны поддерживают желаемый тип авторизации данных.

S. Turner, T. Polk, «Prohibiting Secure Sockets Layer (SSL) Version 2.0», RFC 6176, March 2011 – Документ содержит требование запрета на согласование использования протокола Secure Sockets Layer (SSL) версии 2.0 при установлении соединения между сервером и клиентом.

A. Popov, «Prohibiting RC4 Cipher Suites», RFC 7465, February 2015 - Документ содержит требование запрета на согласование криптонаборов на основе потокового шифра RC4 при установлении соединения между сервером и клиентом. Документ обязателен для протокола TLS всех версий.

B. Moeller, A. Langley, «TLS Fallback Signaling Cipher Suite Value (SCSV) for Preventing Protocol Downgrade Attacks», RFC 7507, April 2015 – Документ определяет сигнальное значение криптонабора (Signaling Cipher Suite Value (SCSV)), предотвращающее атаки на понижение версии протоколов TLS и DTLS (Datagram Transport Layer Security).  

R. Barnes, M. Thomson, A. Pironti, A. Langley, «Deprecating Secure Sockets Layer Version 3.0», RFC 7568, June 2015 – Объявление о прекращении использования (англ. deprecating[2]) протокола Secure Sockets Layer версии 3.0 (SSLv3, SSL 3.0).

K. Bhargavan, Ed., A. Delignat-Lavaud, A. Pironti, A. Langley, M. Ray, «Transport Layer Security (TLS) Session Hash and Extended Master Secret Extension», RFC 7627, September 2015 – Спецификация определяет расширение TLS, которое контекстно связывает основной ключ[3] с полным логом протокола рукопожатия (TLS Handshake Protocol), вычисляющего этот ключ. Таким образом, предотвращается атака «man-in-the-middle», при которой злоумышленник при помощи одного основного ключа может устанавливать одновременно две сессии – одну с клиентом, другую – с сервером. 

A. Langley, «A Transport Layer Security (TLS) ClientHello Padding Extension», RFC 7685, October 2015 – Документ описывает расширение протокола TLS, позволяющее увеличивать до желаемого размера (англ. to pad) сообщения ClientHello. Данная необходимость возникла в связи с тем, что некоторые реализации протокола, основанные на новых криптонаборах и расширениях, увеличивают сообщение ClientHello.

A. Langley, W. Chang, N. Mavrogiannopoulos,J. Strombergson, S. Josefsson, «ChaCha20-Poly1305 Cipher Suites for Transport Layer Security (TLS)», RFC 7905, June 2016 – Документ описывает использование криптонабора ChaCha и аутентификатора Poly1305 в протоколах TLS и DTLS.  

D. Gillmor, «Negotiated Finite Field Diffie-Hellman Ephemeral Parameters for Transport Layer Security (TLS)», RFC 7919, August 2016 – Документ водит группы ffdhe в регистр Supported Groups (поддерживаемые группы) параметров TLS. Введение данных групп позволяет узлам (англ. peer) установить общие параметры алгоритма Диффи-Хеллмана для конечного поля (англ. common finite field DH parameters), что позволяет устранить недостатки традиционного обмена ключами с использованием алгоритма Диффи-Хеллмана на основе конечного поля.

J. Salowey, S. Turner «IANA Registry Updates for TLS and DTLS», RFC 8447, August 2018 – Документ описывает изменения в регистрах IANA для протоколов TLS[4] и DTLS, начиная добавлением примечаний, заканчивая изменением политики регистрации. 

Сам текст стандарта протокола может содержать ошибки, которые указываются в специальном разделе «Errata». Все ошибки разделены на два типа – подтвержденные (англ. verified)  и неподтвержденные (англ. reported). Текст стандарта приводится с учетом подтвержденных ошибок. Указанные ошибки в тексте перевода учитываться не будут, но места в тексте, имеющие указание на ошибку, будут отмечаться соответствующим комментарием.

Первая часть перевода содержит вступительную часть, описание псевдоязыка и хэш-функции HMAC. Вторая часть перевода будет содержать описание протокола записи (TLS Record Protocol), третья – протокола процесса рукопожатия (TLS Handshaking Protocol), четвертая – заключительные положения и приложения.

Ссылки на нормативные источники и литературу будут приведены как в примечаниях, так и в соответствии с текстом спецификации – в разделах "Литература" и "Нормативные источники" с расшифровкой условного обозначения работ. Условные обозначения для каждой работы даются в квадратных скобках и соответствуют оригинальному тексту документа. Все источники будут даваться так, как они приведены в тексте стандарта без перевода названия на русский язык.

Все примечания, сделанные переводчиком сопровождаются пометкой «(Прим. перев.)».

Официальный текст стандарта находится здесь

Содержание

ЧАСТЬ 2

  • 6. Протокол записи TLS

  • 6.1. Состояния соединения

  • 6.2. Уровень записей

  • 6.2.1. Фрагментация

  • 6.2.2. Сжатие и распаковка записей

  • 6.2.3. Защита записей

  • 6.2.3.1. Нулевой шифр и стандартный потоковый шифр

  • 6.2.3.2. Блочный шифр в режиме сцепления блоков (CBC-шифр)

  • 6.2.3.3. Шифры AEAD (с дополнительно прикрепляемыми данными)

  • 6.3. Вычисление ключа

ЧАСТЬ 3.1

  • 7. Протоколы процесса рукопожатия TLS

  • 7.1. Протокол изменения параметров шифрования (Change Cipher Spec)

  • 7.2. Протокол оповещений

  • 7.2.1. Оповещения о закрытии соединения

  • 7.2.2. Сообщения об ошибках

  • 7.3. Обзор протокола рукопожатия

  • 7.4. Протокол рукопожатия

  • 7.4.1. Hello-сообщения

  • 7.4.1.1. Hello-запрос (Hello Request)

  • 7.4.1.2. Клиентское hello-сообщение

  • 7.4.1.3. Серверное hello-сообщение

  • 7.4.1.4. Расширения hello-сообщений

  • 7.4.1.4.1. Расширение "алгоритмы подписи" (signature_algorithms)

ЧАСТЬ 3.2

  • 7.4.2. Серверный сертификат

  • 7.4.3. Серверное сообщение обмена ключами (ServerKeyExchange)

  • 7.4.4. Запрос сертификата

  • 7.4.5. Сообщение ServerHelloDone (завершение серверного этапа отправки hello-сообщений)

  • 7.4.6. Клиентский сертификат

  • 7.4.7. Клиентское сообщение обмена ключами (ClientKeyExchange)

  • 7.4.7.1. Сообщение с предварительным секретом, зашифрованное алгоритмом RSA

  • 7.4.7.2. Открытое число клиента в алгоритме Диффи-Хеллмана

  • 7.4.8. Сообщение о проверке сертификата (CertificateVerify)

  • 7.4.9. Сообщение Finished

  • 8. Криптографические вычисления

  • 8.1. Вычисление основного секрета

  • 8.1.1. Алгоритм RSA

  • 8.1.2. Алгоритм Диффи-Хеллмана

  • 9. Обязательные криптонаборы

  • 10. Протокол данных приложения

  • 11. Вопросы безопасности

  • 12. Регистры IANA

Общая часть

Данный документ описывает версию 1.2 протокола безопасности транспортного уровня TLS (англ. Transport Layer Security). Протокол TLS обеспечивает безопасность соединения в Интернете. Протокол позволяет клиент-серверным приложениям устанавливать между собой соединение, предотвращающее перехват (англ. eavesdropping), злонамеренное использование (англ. tampering) и фальсификацию (англ. forgery) сообщения.

1. Введение

Главная задача, реализуемая протоколом TLS – обеспечение конфиденциальности (англ. privacy) и целостности данных (англ. data integrity) при соединении между двумя приложениями. Протокол состоит из двух слоев: TLS Record Protocol (протокол записи) и TLS Handshake Protocol (протокол рукопожатия) [5]. На нижнем уровне, находящемся поверх какого-либо надежного транспортного протокола (напр. TCP [TCP][6]), находится TLS Record Protocol. TLS Record Protocol обеспечивает безопасность соединения с двумя базовыми свойствами:

Соединение конфиденциально. Для шифрования данных используется      симметричное шифрование (напр. AES [AES][7], RC4 [SCH][8] и т. д.). При этом для каждого соединения генерируются уникальные ключи на основе секрета, который согласовывается (англ. to negotiate) при работе другого протокола (напр. TLS Handshake Protocol). TLS Record Protocol может, также, работать и без использования шифрования.

Соединение надежно. При доставке сообщения осуществляется проверка его целостности при помощи кода утентификации сообщения[9] (далее – MAC) с использованием секретного ключа (англ. keyed MAC). Для вычисления MAC используются защищенные хеш-функции, (напр., SHA-1 и т. д.). TLS Record Protocol может функционировать и без вычисления MAC, но чаще всего используется в таком режиме только в том случае, если другой протокол использует TLS Record Protocol в качестве средства передачи (транспорта) для согласования (англ. negotiation) секретных параметров.

TLS Record Protocol используется для инкапсуляции различных протоколов высшего уровня. Один из таких протоколов - TLS Handshake Protocol позволяет серверу и клиенту аутентифицировать друг друга и согласовать алгоритм шифрования и криптографические ключи до того как протокол приложения передаст или получит первые байты данных. TLS Handshake Protocol обеспечивает безопасность соединения с тремя базовыми свойствами:   

Аутентифицировать соединяющийся узел (англ. peer) возможно с использованием асимметричного шифрования (тж. шифрования на основе открытого ключа) (англ. public key cryptography) (напр. RSA [RSA][10], DSA [DSS][11] и т. д.). Такая аутентификация может быть и не обязательной, но чаще всего требуется, как минимум, для одного из соединяющихся узлов.

Согласование (англ. negotiation) общего секрета (англ. shared secret) защищено: вырабатываемый секрет[12] невозможно перехватить, и для любого аутентифицированного соединения невозможно получить секрет, даже находясь между двумя соединяющимися узлами.

Согласование секрета надежно: атакующий не может модифицировать соединение во время согласования, не будучи обнаруженным соединяющимися узлами[13].

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

1.1. Требования к терминологии

Ключевые слова и фразы интерпретируются согласно RFC 2119 [REQ]. Ключевое слово «ДОЛЖЕН» "MUST" равноценно словам «ТРЕБУЕТСЯ» "REQUIRED", «БУДЕТ» "SHALL". Ключевая фраза «НЕ ДОЛЖЕН» "MUST NOT", равноценна фразе «НЕ БУДЕТ» "SHALL NOT". Ключевое слово «НУЖНО» "SHOULD" равноценно cлову «РЕКОМЕНДУЕТСЯ» "RECOMMENDED". Ключевая фраза «НЕ НУЖНО» "SHOULD NOT" равноценна фразе «НЕ РЕКОМЕНДУЕТСЯ» "NOT RECOMMENDED". Ключевое слово «МОЖЕТ/ИМЕЕТ ВОЗМОЖНОСТЬ» "MAY" равноценно cлову «НЕ ОБЯЗАТЕЛЬНО» "OPTIONAL". (подробнее см. тж. RFC 2119 [REQ][14]).

1.2. Основные отличия от TLS 1.1

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

- Комбинация хеш-функций MD5/SHA-1 используемая для работы псевдослучайной функции (англ. pseudorandom function, PRF) заменена на PRF, указанную в криптонаборах (cipher-suite-specified). Все криптонаборы данного документа используют функцию расширенного преобразования данных (англ. data expansion function) P_SHA256 (см. Раздел 5 данного стандарта).    

- Комбинация хеш-функций MD5/SHA-1 в документах, подписанных цифровой подписью заменена на вычисление одной хеш-функции (англ. single hash). Подписанные элементы (digitally-signed) теперь включают в себя поле, в котором явно указан используемый тип алгоритма хеширования (см. тж. Разд. 4.7 данного стандарта).   

- Существенно улучшены возможности для указания клиентом и сервером типов принимаемых ими алгоритмов хеширования и подписи. Это также смягчает некоторые ограничения на типы алгоритмов хеширования и подписи, накладываемых предыдущими версиями TLS.     

- Добавлена поддержка аутентифицированного шифрования с дополнительными данными (англ. Authenticated Encryption with Additional Data, AEAD) (см. Разд. 4.7, п. 6.2.3.3).

Существенно улучшены возможности для указания клиентом и сервером типов принимаемых ими алгоритмов хеширования и подписи. Это также смягчает некоторые ограничения на типы алгоритмов хеширования и подписи, накладываемых предыдущими версиями TLS.     

-В одном стандарте объединены определение расширений TLS (TLS Extensions definition) (см. п. 7.4.1.4) и AES-криптонаборы (Advanced Encryption Standard – усовершенствованные алгоритмы шифрования TLS), ранее определяемые в других документах ([TLSEXT][16] и [TLSAES][17]).

- Усилена процедура проверки номеров версий параметра EncryptedPreMasterSecret (см. п. 7.4.7.1).

- Увеличено число требований.

Длина verify_data теперь зависит от криптонабора (по умолчанию – 12). (см. п. 7.4.7.1).

Улучшено описание защиты от атаки Бляйхенбахера/Клима (Bleichenbacher/Klima attack). 

Сообщения о событиях (англ. alerts) ДОЛЖНЫ отправляться в большинстве случаев. 

- После запроса сертификата (certificate_request) клиент ДОЛЖЕН отправлять пустой список сертификатов в том случае, если ему недоступен ни один сертификат.

-  Криптонабор TLS_RSA_WITH_AES_128_CBC_SHA стал обязательным для использования при отсутствии иного в стандарте профиля приложения. (см п. 9).  

-  Добавлены криптонаборы HMAC-SHA256.

-  Удалены криптонаборы IDEA и DES. Они более не используются и будут опубликованы в отдельном документе.  

-  Поддержка обратно-совместимого с SSLv2 (SSL 2.0) сообщения «hello» теперь МОЖЕТ, а не БУДЕТ осуществляться. Поддержка, вероятно, НЕ БУДЕТ осуществляться в будущем.  

-  Для того, чтобы однородные case-блоки имели один и тот же код, в псевдоязык добавлено ограниченное «проваливание» (англ. fall-through). (см. тж. п. 4. 6. 1.).        

-  Добавлены разделы с описанием «подводных камней» при реализации протокола (англ. Implementation Pitfalls).          

-  Проведена редакторская работа для более ясного изложения материала.      

2.  Цели создания протокола

Цели разработки протокола TLS, в порядке значимости, следующие:

  1. Криптографическая защита: TLS рекомендуется использовать для установления защищенного соединения между двумя сторонами (англ. parties).

  2. Универсальное взаимодействие (Interoperability): независимые разработчики должны иметь возможность разрабатывать приложения, использующие TLS, которые могут обмениваться криптографическими параметрами без знания кода другого приложения.

  3. Расширяемость: TLS стремится создать такую конструкцию, в которую при необходимости могут быть внедрены новые методы работы с открытыми ключами и канальным шифрованием (англ. bulk encryption). Для этого потребуется выполнить две подзадачи: исключить необходимость создания нового протокола (с рисками возникновения новых уязвимостей), а также исключение необходимости разработки новой библиотеки для целей безопасности.    

  4. Относительная эффективность: Криптографические операции задействуют все больше вычислительной мощности, в частности – операции с открытым ключом. В связи с эти TLS включил в себя опциональную схему кеширования сессий, что позволит уменьшить количество соединений, устанавливаемых с изначальной точки (англ. from scratch). Кроме того, были приложены усилия для уменьшения сетевой активности.

3. Цели создания документа

Данный документ и сам протокол TLS основаны на спецификации протокола SSL 3.0, опубликованной фирмой Netscape. Различия между данным протоколом и протоколом SSL 3.0 – не критические, но они достаточно значимые для того, чтобы различные версии TLS и протокол SSL 3.0 могли не взаимодействовать между собой (хотя каждый протокол и содержит механизмы, которые позволяют ему возвращаться к предыдущим версиям). Данный документ предназначен, прежде всего, для разработчиков, внедряющих протокол в свои приложения, и для специалистов, занимающихся его криптографическим анализом. Спецификация была написана с учетом этого и предназначена для того, чтобы удовлетворить интересы указанных двух групп. По этой причине многие структуры данных, зависящие от алгоритмов, включены в текст спецификации (представлены в Приложениях), позволяя получить к ним более легкий доступ.         

Данный документ не предназначен для раскрытия каких-либо деталей определения служб (англ. service definition) или определения интерфейсов (англ. interface definition), хотя он и содержит места с описанием отдельных политик, поскольку в этом случае они требуются для поддержания устойчивой безопасности. 

4. Псевдоязык

Данный документ содержит особый формат внешнего представления (англ. external representation)[18] данных. В нем используется весьма обобщенный и нестрого определенный синтаксис. Синтаксис псевдоязыка в своей структуре имеет несколько источников. Хотя в своем синтаксисе он и похож на язык «C», и на XDR [XDR][19] – в своем синтаксисе и содержимом, было бы слишком опрометчиво проводить слишком много параллелей между ними. Цель создания этого псевдоязыка – использование в документации протокола TLS; у него нет какого-либо применения, выходящего за пределы этой цели.

4.1. Базовый размер блока

Представление всех элементов данных (англ. data item) явно определено. Базовый размер блока данных – один байт (т. е. 8 бит). Элементы данных, содержащие больше одного байта (далее – мультибайтовый элемент)– являются конкатенацией байтов, слева направо, сверху вниз. Мультибайтовый элемент (числовой в следующем примере) образуется из потока байтов (в нотации языка C) следующим образом:

value = (byte[0] <<[20] 8*(n-1)) | [33] (byte[1] << 8*(n-2)) | ... | byte[n-1];

Такой алгоритм размещения байтов (англ. byte ordering) в мультибайтовых значениях является стандартным сетевым порядком байтов (англ. network byte order), который, также, называется форматом от старшего к младшему (англ. big-endian format, BE format). 

4.2. Разное

Комментарии начинаются с символов «/*» и заканчиваются символами «*/».

Необязательные компоненты обозначаются заключением их в двойные скобки «[[ ]]».

Однобайтовые элементы (англ. single-byte entities), содержащие неинтерпретируемые данные, имеют непрозрачный тип данных (англ. type opaque).    

4.3. Векторы

Вектор (одномерный массив) – это поток однородных элементов данных. Размер вектора может быть определен в документации, либо не определён до момента запуска приложения. В любом случае, значение длины задает количество байт, но не число элементов вектора. Синтаксис для обозначения нового вектора типа T', то есть вектора типа T фиксированной длины:

T T'[n];  

Здесь T' занимает n байт в потоке данных, где n – кратно размеру T. Размер длины вектора не включается в кодированный поток.

В следующем примере Datum определен как три последовательных байта, не интерпретируемых протоколом, а Data – как три последовательных вектора Datum, которые в общей сложности, имеют длину 9 байтов:

opaque[21] Datum[3]; /* три неинтерпретируемых байта */
Datum Data[9]; /* 3 последовательных 3-байтовых вектора */
     

Векторы переменной длины определяются заданием поддиапазона действительных длин (англ. subrange of legal lengths) с использованием нотации <floor...ceiling> (<низ…потолок>). Когда поддиапазон задан, длина вектора предшествует основному содержимому вектора в байтовом потоке данных. Длина вектора задается таким типом целого числа, который может потребоваться для хранения заданного значения максимальной длины вектора (значение ceiling (потолок)), даже если текущее значение длины можно сохранить, задав для его хранения меньшее количество байтов. Вектор переменной длины, имеющий в поле размера значение 0, рассматривается как пустой вектор.  

T T'<floor..ceiling>;

 В следующем примере mandatory – это вектор, который должен содержать от 300 до 400 байт данных непрозрачного типа. Он ни в коем случае не может быть пустым. Поле длины указанного вектора должно иметь типuint16, занимая, таким образом 2 байта в памяти. Такой размер поля является достаточным для представления числа 400 (см. раздел 4. 4.).

С другой стороны, вектор longer может иметь размер до 800 байт, что может составить 400 элементов (блоков) типа uint16, также он может быть пустым. Его код должен включать двухбайтовое поле со значением длины (также, типа uint16), которое предшествует самому вектору. Длина закодированного вектора в данном случае должна быть четным числом (например, длина вектора, имеющего тип данных uint16, равная 17 байт, будет некорректной).

opaque mandatory<300..400>;/* поле длины занимает 2 байта, не может быть пустым */
uint16 longer<0..800>; /* от 0 до 400 беззнаковых целых чисел размером 16 бит (2 байта)*/
 

4.4.  Числа

Базовый числовой тип данных – беззнаковый байт (uint8). Все типы данных с большим размером – образуются из последовательностей байтов фиксированной длины, конкатенирующихся по правилам, указанным в разделе 4.1, и также являются беззнаковыми. Предопределены следующие числовые типы данных:

uint8 uint16[2];
uint8 uint24[3];
uint8 uint32[4];
uint8 uint64[8];

Все значения, указанные здесь или где-либо еще в спецификации – приведены в сетевом формате (от большего к меньшему) (англ. big-endian order). Число типа uint32, представленное 4 байтами с 16-ричными значениями (hex bytes) 01 02 03 04 эквивалентно десятичному числу 16909060.

Обратите внимание, что в некоторых случаях (например при расчете параметров DH (параметров алгоритма Диффи-Хеллмана) необходимо представлять целые числа как непрозрачные векторы. В таких случаях они представляются как беззнаковые целые (т. е., отсутствует требование о наличии в старших разрядах нулевых октетов, даже если самый старший бит числа равняется 1). 

4.5.  Перечисления (перечисленный тип)

В алгоритме доступен также иногда встречающийся тип данных enum (перечисленный тип или перечисление) (англ. enumerated). Поле, имеющее значение типа enum, может содержать только значения, указанные в определении перечисления. Каждое такое определение задает отличный от других определений тип. Сравниваться или получать значения могут только элементы (тж. указатели), принадлежащие одному определению (типу). Каждому элементу перечисления должно быть присвоено значение так, как это указано в примере ниже. Поскольку порядок расстановки элементов в определении перечисления не установлен, им может быть присвоено любое уникальное значение в любом порядке:

enum { e1(v1), e2(v2), ... , en(vn) [[, (n)]] } Te;

Перечисления занимают в битовом потоке столько места, сколько заняло бы максимальное значение указателя в его определении. Нижеприведенное определение задает размер поля типа Color, равный одному байту:

enum { red(3), blue(5), white(7) } Color;

Чтобы избежать определения излишних элементов, есть дополнительная возможность определить значение без присоединенного к нему указателя (англ. associated tag).     

В следующем примере поле типа Taste займет в потоке данных два байта, но при этом сможет принимать значения только 1, 2 или 4.

enum { sweet(1), sour(2), bitter(4), (32000) } Taste;   

Имена элементов перечисления ограничены именами, перечисленными в его определении. В первом примере полная ссылка на второй элемент перечисления будет выглядеть как Color.blue. Такой тип ссылки не является обязательным, если цель, которой присваивается имя, правильно определена:

Color color = Color.blue; /* может использоваться, избыточно */
Color color = blue; /* корректно, неявное указание */

Числовая информация может не указываться для перечислений, которые не будут преобразованы во внешнее представление:

enum { low, medium, high } Amount;

4.6. Структурированные типы (структуры)

Для удобства, можно создать типы структур из простейших типов. Каждая декларация (определение) задает новый уникальный тип. Синтаксис такой декларации в большой степени похож на синтаксис языка C:

struct {      
  T1 f1;      
  T2 f2;      
  ...      
  Tn fn;
} [[T]];  

Ссылки на поля внутри структуры могут быть даны с использованием имени его типа, при этом синтаксис будет очень похож на синтаксис ссылок на элементы перечислений. Например, T.f2 дает ссылку на второе поле предыдущей декларации. Определения (декларации) структурных типов данных могут быть встроенными (англ. embedded).  

4.6.1. Варианты

Продекларированные структуры могут включать в себя варианты, выбор которых основывается на некоторых особенностях окружения. Механизм выбора вариантов (англ. selector) задается перечислением, которое определяет возможные варианты, определенные структурой. Для каждого элемента перечисления, задающего механизм выбора, должен иметься свой вариант, задаваемый оператором case (англ. case arm), внутри определения, задающего структурный тип. Варианты имеют механизм ограниченного проваливания[22]: если два варианта идут непосредственно друг за другом и не имеют полей между собой, то в этом случае оба они будут содержать одни и те же поля. Так, в нижеприведенном примере два варианта «orange» и «banana» будут содержать поле со значением V2. Обратите внимание, что данный синтаксис является новшеством протокола TLS 1.2.   

Для указания на структуру выбора вариантов к ней может быть прикреплена метка (англ. label). В псевдоязыке не представлен механизм, при помощи которого происходит выбор варианта при запуске приложения.   

      struct {
          T1 f1;
          T2 f2;
          ....
          Tn fn;
           select (E) {
               case e1: Te1;
               case e2: Te2;
               case e3: case e4: Te3;
               ....
               case en: Ten;
           } [[fv]];
      } [[Tv]];

Например:

enum { apple, orange, banana } VariantTag;

struct {
uint16 number;
opaque string<0..10>; /* переменная длина */
} V1;

struct {
uint32 number;
opaque string[10];    /* фиксированная длина */
} V2;

struct {
select (VariantTag) { /* неявное значение механизма выбора*/
case apple:
V1;   /* VariantBody, указатель = apple */
case orange:
case banana:
V2;/* VariantBody, указатель = orange или banana */
} variant_body; /* необязательная метка структуры вариантов*/
} VariantRecord;

4.7. Криптографические атрибуты

Алгоритмом определено пять криптографических операций – цифровое подписание (англ. digital signing), потоковое шифрование (англ. stream cipher encryption), блочное шифрование (англ. block cipher encryption), аутентифицированное шифрование с дополнительными данными (англ. authenticated encryption with additional data (AEAD)), шифрование с открытым ключом (англ. public key encryption). Указанные операции имеют следующие ключевые обозначения (англ. key word designation): digitally-signed, stream-ciphered, block-ciphered, aead-ciphered, и public-key-encrypted, соответственно. Криптографическая обработка поля определяется путем прикрепления к нему спереди соответствующего ключевого обозначения, идущего перед описанием типа этого поля. На криптографические ключи влияет рабочее состояние сессии (см. Разд. 6. 1).                    

Элемент digitally-signed кодируется как структурированный тип (struct) DigitallySigned:

struct {
SignatureAndHashAlgorithm algorithm;
opaque signature<0..2^16-1>;
} DigitallySigned;

Поле algorithm описывает используемый алгоритм (см. п. 7.4.1.4.1. для подробной информации об этом поле). Обратите внимание, что введение поля algorithm является изменением по сравнению с предыдущими версиями. Поле signature – цифровая подпись, использующая указанные алгоритмы на содержимом элемента. Само содержимое этого поля находится не в сети, но вычисляется простым образом. Длина подписи определяется алгоритмом подписи и ключом.

При использовании для подписи алгоритма RSA, непрозрачный вектор содержит подпись, сгенерированную схемой RSASSA-PKCS1-v1_5, описанной в [PKCS1][23]. В обсуждении, поднятом в [PKCS1], было условлено, что тип данных DigestInfo[24][25] должен быть закодирован с использованием отличительных правил кодирования (англ. Distinguished Encoding Rules (DER))) [X680][26] [X690][27]. Для непараметрических алгоритмов хеширования (включая SHA-1), поле DigestInfo.AlgorithmIdentifier.parameters должно содержать значение NULL, но реализуемые приложения должны работать как со значением этого поля NULL, так и, вообще, без указания параметров. Обратите внимание, что более ранние версии TLS использовали другую схему подписания на основе алгоритма RSA, которая не включала в себя использование DigestInfo.                

При использовании для подписи алгоритма DSA, 20 байт хеша, полученного при помощи алгоритма SHA-1, пропускаются непосредственно через алгоритм цифрового подписания (англ. Digital Signing Algorithm (DSA)) без дополнительного хеширования. При этом рассчитывается два значения – r и s. Подпись, полученная при помощи DSA, является непрозрачным вектором, как и в случае использования RSA, содержимое которого рассчитывается при помощи DER-кодирования последовательности Dss-Sig-Value. При этом, Dss-Sig-Value выражается как:

Dss-Sig-Value ::=[28] SEQUENCE[29] {
r INTEGER,
s INTEGER,
}

Обратите внимание: в текущей терминологии аббревиатура «DSA» означает «Digital Signature Algorithm» (то есть, относится к алгоритму), в то же время аббревиатура «DSS» относится к стандарту NIST[30]. В оригинальных спецификациях TLS и SSL использовалась только аббревиатура «DSS». Данный документ для обозначения алгоритма использует аббревиатуру «DSA», а для обозначения стандарта – «DSS». В то же время использование в определениях кода аббревиатуры «DSS» сделано в целях исторической преемственности.  

При потоковом шифровании криптографически защищенный генератор псевдослучайных чисел с ключом  (англ. secure keyed pseudorandom number generator) генерирует последовательность, равную по размеру незашифрованному сообщению (англ. plaintext), после получают зашифрованное сообщение, применяя операцию сложения по модулю 2 (исключающего «ИЛИ») исходного сообщения и сгенерированной псевдослучайной последовательности. 

При блочном шифровании каждый блок незашифрованного сообщения зашифровывается в блок шифротекста. Блочное шифрование происходит в режиме построения цепи шифроблоков (англ. Cipher Block Chaining, CBC). Размер зашифрованных, таким образом, элементов, будет кратен длине шифроблока.

При AEAD-шифровании незашифрованное сообщение шифруется и одновременно с этим защищается его целостность. Входное сообщение может быть любой длины, при этом выходное сообщение, полученное при помощи AEAD-шифрования, обычно, больше, чем входное, поскольку содержит значение проверки целостности (англ. integrity check value).  

При шифровании с открытым ключом алгоритм открытого ключа используется для шифрования данных таким образом, чтобы расшифровка могла произойти только при помощи соответствующего закрытого ключа. Элемент public-key-encrypted (зашифрованный открытым ключом) является непрозрачным вектором переменной длины <0..2^16-1>, определяемой алгоритмом шифрования и ключом. 

RSA-шифрование выполняется на основе схемы RSAES-PKCS1-v1_5, указанной в [PKCS1].

В следующем примере содержимое внутренней структуры (field3 и field4) используется как входные данные для алгоритма подписи/хеширования, таким образом, вся структура целиком шифруется в потоковом режиме. Длина структуры в байтах будет равна два байта для полей field1 и field2 плюс два байта для алгоритма подписи и хеширования, плюс два байта для файла подписи, плюс длина выходных данных алгоритма подписи. Размер файла подписи известен, так как алгоритм и ключ, используемый для подписи, известны заранее до шифрования или дешифрования этой структуры. 

stream-ciphered struct {
uint8 field1;
uint8 field2;
digitally-signed opaque {
uint8 field3<0..255>;
uint8 field4;
};
} UserType;

4.8. Константы

Для целей спецификации типизованные константы могут быть определены путем объявления желаемого типа и присвоения ему значений. 

Неопределенным типам (непрозрачным (англ. opaque), векторам переменной длины, структурам, содержащим непрозрачный тип) не могут присваиваться значения. Ни одно из полей мульти-элементной структуры или вектора не может быть пропущено.   

Например:

struct {
uint8 f1;
uint8 f2;
} Example1;

Example1 ex1 = {1, 4};

Таким образом, структура типа Example1 будет содержать два поля f1 и f2 со значениями 1 и 4, соответственно.

5. HMAC и псевдослучайная функция

Для защиты целостности сообщений слой записи TLS (англ. TLS record layer) использует MAC с ключом (англ. keyed MAC). Шифронаборы (тж. криптонаборы) (англ. cipher suites), определенные в этом документе, используют конструкцию, известную как HMAC, в которой происходит хеширование MAC-аутентификатора, описанную в [HMAC][31]. При необходимости другие криптонаборы могут определять свои собственные MAC-конструкции.

В добавок к этому, этой конструкции требуется расширенное преобразование (англ. expansion) секретов в блоки данных для целей генерации либо валидации ключа. Данная псевдослучайная функция (англ. Pseudo Random Function (PRF)) в качестве входных данных берет секрет, свое начальное значение (тж. затравка) (англ. seed), метку идентификации (англ. identifying label, label) и выдает данные произвольной длины.     

 В данном разделе мы определяем только одну PRF, которая основана на алгоритме HMAC. Данная функция, работающая в связке с хеш-функцией SHA-256, используется для всех криптонаборов, определенных в этом документе, а также в других документах, касающихся протокола TLS 1.2, опубликованных ранее этого документа. Новые криптонаборы должны явно определять PRF и, в общем случае, должны использовать для протокола TLS PRF с хеш-функцией SHA-256, либо с более сильным стандартом хеширования.   

Для начала определим функцию расширенного преобразования данных (англ. data expansion function) P_hash(secret, data), которая использует одну хеш-функцию для преобразования секрета и начального значения в выходные данные произвольного размера:  

P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
HMAC_hash(secret, A(2) + seed) +
HMAC_hash(secret, A(3) + seed) + ...,

где "+" означает конкатенацию.

A() определяется как:

A(0) = seed
A(i) = HMAC_hash(secret, A(i-1))

Функция P_hash может иметь столько итераций, сколько это необходимо для выдачи требуемого количества данных. Например, если P_SHA256 используется для создания 80 байт данных, то необходимо будет произвести три итерации функции (до A(3) включительно), создав 96 байт выходных данных; последние 16 байтов финальной итерации будут отброшены, оставив 80 байт выходных данных. 

PRF для целей протокола TLS создается путем применения функции P_hash с секретом в качестве ее аргумента:

PRF(secret, label, seed) = P_<hash>(secret, label + seed)

Метка (англ. label) является ASCII-строкой. Ее следует включать в функцию в точной форме, в которой она была взята, без байта длины, а также не перенося нулевой символ (англ. null character). Например, метка «slithy toves», до начала обработки функцией хеширования будет выглядеть как:

73[32]6C 69 74 68 79 20 74 6F 76 65 73 


[1] Клиентские и серверные сообщения «hello» рассмотрены в п. 7.4.1 данного стандарта (Прим. перев.).

[2] Хотя в некоторых русскоязычных источниках слово «deprecating» дается в переводе «устаревание», автору перевода наиболее подходящим видится термин «прекращение использования», поскольку для термина «устаревший» в английском языке используется слово «obsolete» (Прим. перев.).

[3] Клиентское сообщение об обмене ключами (Client Key Exchange Message) содержит начальный ключ (англ. premaster key) после чего псевдослучайная функция вычисляет основной ключ (англ. master key) (подробнее см. разделы 7.4.7 и 8.1 спецификации протокола TLS 1.2) (Прим. перев.).  

[4] Регистры IANA для TLS разделены на две части: Transport Layer Security (TLS) Parameters (Параметры TLS) и Transport Layer Security (TLS) Extensions (Расширения TLS) (Прим. перев.). 

[5] Протокол рукопожатия также можно назвать протоколом согласования параметров. Но поскольку для термина «согласование параметров» в английском языке имеется слово «negotiation», был оставлен используемый в официальном документе для обозначения данного уровня протокола TLS сленговый термин «рукопожатие» (англ. handshake) (Прим. перев.).

[6] Postel, J., "Transmission Control Protocol", STD 7, RFC 793, September 1981.

[7] National Institute of Standards and Technology,"Specification for the Advanced Encryption Standard (AES)" FIPS 197.  November 26, 2001.

[8] B. Schneier. "Applied Cryptography: Protocols, Algorithms, and Source Code in C, 2nd ed.", Published by John Wiley & Sons, Inc. 1996.

[9] В русскоязычной источниках также используется термин «имитовставка».(Прим. перев.).

[10] R. Rivest, A. Shamir, and L. M. Adleman, "A Method for Obtaining Digital Signatures and Public-Key Cryptosystems", Communications of the ACM, v. 21, n. 2, Feb 1978, pp. 120-126.

[11] 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 (Прим. перев.).

[12] Также можно употребить термин «секретный ключ».(Прим. перев.). 

[13] Как было сказано в предисловии, в сентябре 2015 года вышел RFC 7627, который направлен на устранение уязвимости от атаки «man-in-the-middle», в которой злоумышленник устанавливает две сессии с клиентом и сервером, используя один и тот же секрет (секретный ключ). (Прим. перев.).   

[14] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.

[15] Dierks, T. and E. Rescorla, "The Transport Layer Security (TLS) Protocol Version 1.1", RFC 4346, April 2006.

[16] Eastlake, D., 3rd, "Transport Layer Security (TLS) Extensions:  Extension Definitions", Work in Progress, February 2008. – На август 2021 года актуальной версией является: Eastlake, D., 3rd, "Transport Layer Security (TLS) Extensions:  Extension Definitions", RFC 6066, January 2011 (Прим. перев.). – Поддерживаемые IANA расширения TLS также приведены в разделе регистров Transport Layer Security (TLS) Extensions. (Прим. перев.).

[17] Chown, P., "Advanced Encryption Standard (AES) Ciphersuites for Transport Layer Security (TLS)", RFC 3268, June 2002.

[18]  Внешнее представление (англ. external representation) является англоязычным термином для структурированного представления данных и информации, включающего как формальные структуры, так и и наглядный материал (графики, схемы, иллюстрации). Данный термин в англоязычной литературе противопоставляется внутреннему представлению данных (internal representation) или, также, промежуточному представлению (intermediate representation), обозначающему структуры данных или код, используемые компилятором или виртуальной машиной для представления исходного кода. (Прим. перев.). 

[19] Eisler, M., Ed., "XDR: External Data Representation Standard", STD 67, RFC 4506, May 2006.

[20] << - оператор побитового сдвига влево. (Прим. перев.). 

[21]  Opaque – непрозрачный тип данных. См. тж. раздел 4. 2 (Прим. перев.).

[22] Проваливанием (англ. fall-through) в языках С/C++ называется ситуация, когда в блоке case оператора передачи управления switch отсутствует служебное слово brake. До стандарта C++17 компилятор в этом случае выдал бы сообщение об ошибке проваливания. (Прим. перев.).

[23] Jonsson, J. and B. Kaliski, "Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography Specifications Version 2.1", RFC 3447, February 2003.

[24] О синтаксисе типа DigestInfo см. раздел A.2.4 RFC 3447 [PKCS1] (Прим. перев.).

[25] Результат преобразования данных хеш-функцией в английском языке может обозначаться термином «digest», что в русскоязычной литературе может переводиться как «сводка сообщения».  (Прим. перев.).

[26] ITU-T Recommendation X.680 (2002) | ISO/IEC 8824-1:2002, Information technology - Abstract Syntax Notation One (ASN.1): Specification of basic notation.

Российский аналог - ГОСТ Р ИСО/МЭК 8824-1-2001. Абстрактная синтаксическая нотация версии один (АСН.1). Часть 1. Спецификация основной нотации. (Прим. перев.).

[27]  ITU-T Recommendation X.690 (2002) | ISO/IEC 8825-1:2002, Information technology - ASN.1 encoding Rules: Specification of Basic Encoding Rules (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules (DER).

Российский аналог - ГОСТ Р ИСО/МЭК 8825-1-2003 Информационная технология. Правила кодирования ACH.1. Часть 1. Спецификация базовых (BER), канонических (СER) и отличительных (DER) правил кодирования.

[28] ::= - символ определения в форме нотации Бэкуса-Наура. (Прим. перев.).

[29] Sequence (англ.) – последовательность. В информатике – порядок действий, задаваемых алгоритмом. Таким образом, Dss-Sig-Value является последовательным вычислением значений r и s.

[30] NIST - The National Institute of Standards and Technology, Национальный институт стандартов и технологии (США). (Прим. перев.).

[31] Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed-Hashing for Message Authentication", RFC 2104, February 1997.

[32] 73 – ASCII-код в 16-ричном формате для символа «s» и т. д. (Прим. перев.).

[33] Операция побитового ИЛИ (Прим. перев.).

Теги:
Хабы:
Всего голосов 16: ↑12 и ↓4+8
Комментарии7

Публикации

Истории

Работа

Ближайшие события