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

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!

T. Dierks, E. Rescorla

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

Версия 1.2

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

Август 2008

Часть 2

Данный перевод является второй частью перевода протокола безопасности транспортного уровня (TLS) версии 1.2 (RFC 5246). Первая часть перевода находится здесь. Вторая часть перевода содержит описание протокола записи TLS.

Примечание о терминологии: в данном переводе используется термин «сложение по модулю 2», идентичный в русскоязычной литературе термину «операция исключающего «ИЛИ», оба из которых, в свою очередь, соответствуют англоязычным терминам «exclusive-OR» и «XOR».

Содержание

  • 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. Вычисление ключа

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

Протокол записи TLS (англ. TLS Record Protocol) является многоуровневым протоколом (англ. layered protocol). На каждом уровне сообщения могут включать поля со значениями длины, описанием и содержимым. Протокол записи принимает сообщения для их дальнейшей передачи, фрагментирует данные в оперируемые блоки, имеет дополнительную возможность сжатия, присоединения кода аутентификации сообщения (далее – MAC[1]), шифрования и передачи полученного результата. Полученные данные расшифровываются, проверяются, распаковываются (англ. decompressed), пересобираются (англ. reassembled), после чего отправляются клиентам более высоких уровней.

В данном документе описываются 4 протокола, использующие протокол записи: протокол рукопожатия (тж. согласования параметров) (англ. handshake protocol), оповещений (англ. alert protocol), изменения параметров шифрования (англ. change cipher spec protocol) и протокол данных приложения (англ. application data protocol). В целях расширяемости протокола TLS протоколом записи могут поддерживаться дополнительные типы содержимого записей (англ. record content). Новые значения, соответствующие новым типам содержимого записей, задаются IANA в регистре TLS ContentType (тип содержимого TLS) раздела регистров «Transport Layer Security (TLS) Parameters» по принципу, указанному в Разделе 12 данного документа.

Реализуемые приложения не должны пересылать типы записей, не определенные в этом документе, за исключением случаев, при которых они согласовываются каким-либо расширением. Если приложение, реализующее протокол TLS, получает сообщение с неизвестным (англ. unexpected) типом записи, оно должно отправить обратно сообщение «unexpected_message» (неизвестное сообщение).

Каждый разрабатываемый протокол, планируемый к использованию поверх TLS, должен строиться с учетом всех потенциальных атак, с которым этот протокол может столкнуться. На практике это означает, что разработчик протокола должен знать какие параметры безопасности предоставляет протокол TLS, а какие – нет и не упускать последнее из виду.

В частности, нужно обратить внимание, что тип и длина записи не защищены шифрованием. Если эта ситуация является чувствительной сама по себе, разработчики приложения могут предпринять некоторые шаги (увеличение размера поля, наложение шума) для минимизации утечки подобной информации.

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

Состояние соединения TLS (англ. TLS connection state) – это операционное окружение протокола записи TLS. Оно описывает алгоритм сжатия, алгоритм шифрования и алгоритм создания MAC. Вдобавок к этому, параметры этих алгоритмов известны: ключ MAC и ключи канального шифрования (англ. bulk encryption keys) для соединения в обоих направлениях - как для чтения, так и для записи. Исходя из логики, должно быть четыре наиболее заметных состояния соединения: рабочие состояния (англ. current states) чтения и записи, а также состояния ожидания (англ. pending states) чтения и записи. Все записи обрабатываются в рабочих состояниях чтения и записи. Параметры безопасности для состояний ожидания могут быть установлены протоколом рукопожатия TLS, а ChangeCipherSpec[2] может выборочно делать состояние ожидания рабочим, в случае чего соответствующее рабочее состояние выключает (англ. disposed of) и заменяет собой состояние ожидания; после чего состояние ожидания заново инициализируется как пустое состояние (англ. empty state). Не допускается делать рабочим состояние, инициализированное без параметров безопасности. Начальное рабочее состояние (англ. initial current state) всегда определяет то, что окружением еще не было задействовано ни одного из протоколов шифрования, сжатия или MAC.

Параметры безопасности для состояния чтения и записи соединения TLS задаются следующими значениями[3]:

connection end
Параметр отвечает за то, чем будет считаться конкретный узел в данном соединении – «клиентом» или «сервером».

PRF algorithm
Алгоритм псевдослучайной функции, используемый для генерации ключей из основного секрета (см. Разделы 5 и 6.3).

bulk encryption algorithm
Алгоритм канального шифрования[4]. Данная спецификация содержит размер ключа алгоритма, тип шифрования – блочное, потоковое или AEAD, размер блока шифра (в случае, если размер блока может меняться), длины явного и неявного векторов инициализации[5] (англ. initialization vectors, IV[6]) (либо nonce-параметры)[7].

MAC algorithm
Алгоритм, используемый для аутентификации сообщения. Данная спецификация включает размер значения, возвращаемый MAC-алгоритмом.

compression algorithm
Алгоритм сжатия данных. Спецификация должна включать всю информацию, требуемую алгоритму для сжатия (компрессии).

master secret
Общее для двух соединяющихся узлов секретное число размером 48 байт.

client random
32-битное значение, генерируемое клиентом.

server random
32-битное значение, генерируемое сервером.

Указанные параметры определены в псевдоязыке представления как:

enum { server, client } ConnectionEnd;
enum { tls_prf_sha256 } PRFAlgorithm;
enum { null, rc4, 3des, aes } BulkCipherAlgorithm;
enum { stream, block, aead } CipherType;
enum { null, hmac_md5, hmac_sha1, hmac_sha256,
hmac_sha384, hmac_sha512} MACAlgorithm;
enum { null(0), (255) } CompressionMethod;

/* Могут быть добавлены алгоритмы, определенные в CompressionMethod, PRFAlgorithm, BulkCipherAlgorithm и MACAlgorithm. */

struct {
        ConnectionEnd          entity;
        PRFAlgorithm           prf_algorithm;
        BulkCipherAlgorithm    bulk_cipher_algorithm;
        CipherType             cipher_type;
        uint8                  enc_key_length;
        uint8                  block_length;
        uint8                  fixed_iv_length;
        uint8                  record_iv_length;
        MACAlgorithm           mac_algorithm;
        uint8                  mac_length;
        uint8                  mac_key_length;
        CompressionMethod      compression_algorithm;
        opaque                 master_secret[48];
        opaque                 client_random[32];
        opaque                 server_random[32]; 
} SecurityParameters; 

Уровень записи использует параметры безопасности для генерации следующих шести элементов записи (некоторые из них не являются обязательными для всех шифров, оставаясь, таким образом пустыми):

client write MAC key /* секретный ключ для аутентификации данных, записанных клиентом*/
server write MAC key /* секретный ключ для аутентификации данных, записанных сервером*/
client write encryption key /* ключ шифрования данных, записанных клиентом */
server write encryption key /* ключ шифрования данных, записанных сервером */
client write IV /* вектор инициализации данных, записанных клиентом */
server write IV /* вектор инициализации для данных, записанных сервером */

Параметры записи клиента используются сервером при приеме и обработке записей (англ. records), и наоборот. Алгоритм, используемый для генерации этих параметров из параметров безопасности, описан в Разделе 6.3.

Если параметры безопасности были определены, а ключи – сгенерированы, то состояние соединения может быть преобразовано в рабочее состояние. Рабочие состояния должны подвергаться корректировке (англ. be updated) при обработке каждой записи. Каждое состояние соединения включает в себя следующие элементы:

compression state
Рабочее состояние алгоритма сжатия.

cipher state
Состояние шифрования - состояние алгоритма шифрования. Состоит из назначенного для данного соединения ключа. В случае использования потокового шифра в параметрах будет содержаться любая необходимая алгоритму информация для продолжения шифрования или расшифровки данных.

MAC key
Ключ MAC для данного соединения.

sequence number
Число последовательности, поддерживаемое отдельно для состояний чтения и записи, которое содержится в каждом состоянии соединения. Число последовательности должно быть определено как 0 всякий раз, когда состояние соединения устанавливается в качестве активного состояния. Числа последовательности имеют тип uint64 и не могут превышать значения 2^64-1. Числа последовательностей не обертываются (англ. do not wrap). Если реализации TLS понадобится обернуть число последовательности, в этом случае НУЖНО произвести пересогласование параметров (англ. to renegotiate). Число последовательности увеличивается после обработки каждой записи: в частности, первая запись, передаваемая в отдельном соединении, должно использовать число записи, равное 0.

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

Протокол записи TLS получает неинтепретированные данные от протоколов верхнего уровня в непустых блоках произвольного размера.

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

Уровень записи фрагментирует блоки с информацией в записи типа TLSPlaintext, передающие данные порциями (англ. chunks) размерами в 2^14 байт или менее. На уровне записей границы сообщения клиента никак не ограничены (то есть, множество сообщений клиента, имеющих одинаковое значение типа содержимого (ContentType) могут быть слиты в одну запись TLSPlaintext, и в то же время одно сообщение может быть фрагментировано на несколько отдельных записей).

struct {
       uint8 major;
       uint8 minor;
} ProtocolVersion;

enum {
      change_cipher_spec(20), alert(21), handshake(22),
      application_data(23), (255)  
} ContentType; /* перечисление со значениями типов содержимого*/
/*для которых отводится 1 байт памяти*/
/* принимает значения 20, 21, 22, 23 в зависимости от типа содержимого*/

struct {
       ContentType type;
        ProtocolVersion version;
        uint16 length;
        opaque fragment[TLSPlaintext.length];
} TLSPlaintext;

Каждая запись типа TLSPlaintext содержит следующие параметры:

type
Протокол TLS верхнего уровня, используемый для обработки помещаемого в запись типа TLSPlaintext фрагмента данных.

version
Версия применяемого алгоритма. Данный документ описывает TLS версии 1.2, который использует значение данного параметра, равное {3,3}[8]. Значение версии, равное 3,3 – историческое, поскольку для обозначения TLS 1.0 использовалось значение 3.1 (см. Прил. А.1). Обратите внимание, что клиент, поддерживающий несколько версий TLS, может не знать какую ему следует использовать версию до момента, пока не получит сообщение ServerHello. В Прил. Е рассматриваются вопросы того, какую версию следует применять при отправке сообщения ClientHello.

length
Длина в байтах элемента TLSPlaintext.fragment[9]. Значение длины не должно превышать 2^14 байт (16 кБ).

fragment
Данные приложения. Такие данные – прозрачны и рассматриваются протоколом TLS верхнего уровня, указанным в поле «type» в качестве независимого блока.

Реализации протокола не должны посылать фрагменты нулевой длины с типом содержимого ChangeCipherSpec, Alert или Handshake. Фрагменты нулевой длины данных приложения (англ. application data) могут посылаться, поскольку они являются потенциально полезными в качестве контрмеры в отношении анализа трафика.

Примечание. Данные различных типов содержимого слоя записи TLS могут перемежаться между собой (англ. be interleaved). Данные приложения, обычно, имеют меньший приоритет при передаче, чем другие типы содержимого. Однако, записи должны быть отправлены в сеть в том порядке, в котором они были обработаны уровнем записи. Реципиенты сообщения должны, в свою очередь, получить и обработать перемежающийся с другими данными трафик уровня приложения во время рукопожатий, происходящих после первого рукопожатия соединения.

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

Все записи сжимаются с использованием алгоритма, определенном в рабочем состоянии сессии. В сессии всегда явно указан активный алгоритм сжатия, однако в ее начале в параметрах безопасности алгоритм сжатия указан как CompressionMethod.null. Алгоритм сжатия переводит структуру TLSPlaintext в структуру TLSCompressed. Функция сжатия инициализируется, в тот момент, когда состояние соединения становится активным (рабочим), при этом имея установленное по умолчанию состояние. Алгоритмы сжатия для протокола TLS описаны в [RFC3749][10] .

Сжатие должно происходить без потерь и не должно превышать длину содержимого более чем на 1024 байта. Если функция распаковки данных обнаружит элемент TLSCompressed.fragment, который при распаковке будет иметь длину более 2^14 байт, она должна выдать сообщение о фатальной ошибке распаковки (англ. fatal decompression failure error).

struct {
       ContentType type; /* такой же тип, как и у TLSPlaintext.type */
       ProtocolVersion version; /* такая же версия, как и у */
                              /*TLSPlaintext.version */
       uint16 length;
       opaque fragment[TLSCompressed.length];
} TLSCompressed;

Параметры структуры TLSCompressed:

length
Длина (в байтах) элемента TLSCompressed.fragment. Длина не должна превышать 2^14 + 1024 байт.

fragment
Сжатая форма элемента TLSPlaintext.fragment.

Примечание: Операция CompressionMethod.null является операцией тождества (англ. identity operation). Это означает, что при ее выполнении не меняются значения полей.

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

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

Функции шифрования и создания MAC переводят структуру типа TLSCompressed в структуру типа TLSCiphertext. Функции расшифровки производят обратную операцию. Mac-код записи, кроме всего прочего, содержит число последовательности, что позволяет обнаружить пропавшие, излишние или повторяющиеся записи.

struct {
       ContentType type;
       ProtocolVersion version;
       uint16 length;
       select (SecurityParameters.cipher_type) {
            case stream: GenericStreamCipher;
            сase block:  GenericBlockCipher;
            case aead:   GenericAEADCipher;     
     } fragment;
} TLSCiphertext;  

Как видно, в приведенной выше структуре типа TLSCiphertext имеется механизм выбора, включающий три варианта шифрования: потоковое (GenericStreamCipher), блочное (GenericBlockCipher) либо с дополнительными данными (GenericAEADCipher).

type
Поле с указанием типа. Идентично полю TLSCompressed.type.

version
Поле с указанием версии. Идентично полю TLSCompressed.version.

length
Длина (в байтах) элемента TLSCiphertext.fragment. Длина не должна превышать 2^14 + 2048 байт.

fragment
Зашифрованная форма, содержащая MAC-код элемента TLSCompressed.fragment.

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

Потоковые шифры (включая BulkCipherAlgorithm.null см. Прил. А.6) превращают структуры TLSCompressed.fragment в поток структур TLSCiphertext.fragment и наоборот.

stream-ciphered struct {
       opaque content[TLSCompressed.length];
       opaque MAC[SecurityParameters.mac_length];
} GenericStreamCipher;

MAC генерируется как:

MAC(MAC_write_key, seq_num +
      TLSCompressed.type +
      TLSCompressed.version +
      TLSCompressed.length +
      TLSCompressed.fragment);

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

seq_num
Число последовательности для данной записи.

MAC
Алгоритм вычисления MAC, указанный в поле SecurityParameters.mac_algorithm.

Обратите внимание, что MAC вычисляется до шифрования. Потоковый шифр шифрует целый блок данных, включая и MAC. Потоковые шифры не использующие вектор синхронизации (например, RC4[11]), используют состояние шифрования[12], имеющееся в конце одной записи, попросту перенося его на следующий пакет данных. При использовании криптонабора TLS_NULL_WITH_NULL_NULL шифрование является операцией тождества (т. е. данные не шифруются, размер MAC равен 0, из чего следует, что MAC не используется). При использовании нулевого или потокового шифра поле TLSCiphertext.length, выражается как:

TLSCiphertext.length = TLSCompressed.length + SecurityParameters.mac_length

где «+» означает операцию сложения.

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

[13]Блочные шифры (такие как 3DES или AES), используя функции шифрования сообщения и создания MAC, превращают структуры TLSCompressed.fragment в блоки структур TLSCiphertext.fragment и наоборот.

struct {
       opaque IV[SecurityParameters.record_iv_length];
       block-ciphered struct {
           opaque content[TLSCompressed.length];
           opaque MAC[SecurityParameters.mac_length];
           uint8 padding[GenericBlockCipher.padding_length];
           uint8 padding_length;
       };
} GenericBlockCipher;

При этом MAC вычисляется так же, как указано в п. 6.2.3.1.

Структура GenericBlockCipher имеет следующие параметры:

IV
Вектор инициализации (англ. Initialization Vector) (далее – IV) рекомендуется выбирать случайным образом, в то же время он должен обладать свойством непредсказуемости. Обратите внимание, что в версиях TLS, вышедших до версии 1.1, не было поля IV, и в качестве IV использовался последний блок шифротекста предыдущей записи ("CBC-остаток", англ. "CBC residue"). Вектор IV был введен для предотвращения атаки, описанной в [CBCATT][14]. Длина IV для блочного шифра указывается в поле SecurityParameters.record_iv_length, равном значению поля SecurityParameters.block_size[15].

padding
Дополнительное заполнение (тж. набивка) – используется для того, чтобы длина незашифрованного текста (англ. plaintext) стала целым числом, кратным длине блока блочного шифра. Набивка может иметь длину до 255 байт включительно не имея обязательного значения. Единственное требование – значение TLSCiphertext.length в итоге должно быть целым числом кратным длине блока. Значение длины, больше необходимого, может оказаться желательным для противодействия атакам, основанным на анализе длины обмениваемых сообщений. Каждый вектор данных типа uint8 должен содержать значение длины набивки. Реципиент должен проверять входящие данные и отправлять сообщение "bad_record_mac" при возникновении ошибок при обработке полученных данных.

padding_length
Значение длины набивки – должно быть таким, чтобы общий размер структуры GenericBlockCipher был целым числом, кратным длине блока шифра. Значение поля может варьироваться от 0 до 255 включительно. Значение этого поля указывает длину поля padding, но при этом не учитывает саму длину поля padding_length.

Длина зашифрованных данных (TLSCiphertext.length), таким образом, превышает общую сумму полей SecurityParameters.block_length, TLSCompressed.length, SecurityParameters.mac_length и padding_length.

Пример: при размере блока, равном 8 байт, длина содержимого (TLSCompressed.length) равна 61 байт, длина MAC – 20 байт. Таким образом, длина незашифрованного сообщения до операции набивки равна 82 байта[16] (не включая IV). Таким образом, остаток от деления значения длины набивки на 8 должен быть равен 6 для того, чтобы общая длина сообщения была четным числом, кратным 8 (длине блока). Длина набивки, в данном случае, будет равна 6, 14, 22 и тд., вплоть до 254 байт. Если длина набивки будет минимальным необходимым значением (6 байт), то вектор набивки должен содержать в себе значение 6. Таким образом, последние 8 октетов элемента GenericBlockCipher до шифрования блока должны иметь форматxx 06 06 06 06 06 06 06 – где xx, последний октет MAC.

Обратите внимание: при блочном шифровании в режиме сцепления блоков (Cipher Block Chaining), критически важно, чтобы весь незашифрованный текст записи был известен до того как был передан какой-либо зашифрованный текст. В противном случае возможно осуществить атаку, описанную в [CBCATT].

Заметки для реализации: Canvel и другие в [CBCTIME][17] продемонстрировали атаку тайминга при обработке CBC-набивки, где в качестве уязвимости используется период времени, в который происходит расчет MAC. Для защиты от этой атаки все реализации должны обеспечивать одинаковое время обработки сообщения вне зависимости от того содержит набивка ошибки или нет. В общем случае, наилучшим решением для этого будет расчет MAC в любом случае – вне зависимости от того, корректна набивка или нет, и отбрасывать пакет только после этого расчета. Например, если набивка содержит какие-либо ошибки, конкретное приложение должно присваивать набивке нулевую длину, после чего вычислять MAC. При этом временной канал будет достаточно малым, поскольку обработка MAC, в некоторой степени, зависит от размера фрагмента данных, но и, как думается, не слишком большим для нормального функционирования, так как размер временного интервала будет слишком малым для расчета блока MAC достаточного размера.

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

При работе шифров [AEAD][18] (таких как [CCM][19] или [GCM][20]) функция AEAD превращает структуры TLSCompressed.fragment в AEAD-структуры TLSCiphertext.fragment, и наоборот.

Входными данными AEAD-шифров являются: один ключ (write-key), однократно используемый параметр nonce, незашифрованное сообщение (plaintext), а также «дополнительные данные», которые включаются в элемент проверки аутентифкации, как это описано в разделе 2.1 [AEAD]. Ключ является либо элементом client_write_key, либо server_write_key. При этом MAC-ключ не используется.

Криптонабор на основе AEAD-шифрования должен указывать как строится nonce, используемый в данном алгоритме, и какова длина GenericAEADCipher.nonce_explicit, являющейся частью структуры GenericAEADCipher. Во многих случаях приемлемо использовать технику вычисления частично скрытого nonce (англ. partially implicit nonce), описанную в п. 3.2.1 [AEAD], в то время как значение record_iv_length будет длиной открытой части этого параметра. В этом случае, рекомендуется чтобы скрытая часть была производной от блока ключа (key_block) являясь client_write_iv и server_write_iv (как описано в Разделе 6.3), а открытая часть – была включена в GenericAEAEDCipher.nonce_explicit.

Незашифрованное сообщение - TLSCompressed.fragment.

Дополнительные данные аутентификации, которые мы обозначаем как additional_data определяются следующим образом:

additional_data = seq_num + TLSCompressed.type + + TLSCompressed.version + TLSCompressed.length;

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

Выходные данные AEAD-шифра (aead_output) состоят из шифротекста, производимого операцией AEAD-шифрования. Значение длины этих данных, в общем случае, будет больше значения TLSCompressed.length, на величину, зависящую от типа AEAD-шифра. Поскольку результат шифрования может включать в себя и набивку, объем служебных данных, содержащихся в выходном сообщении шифра, может варьироваться в зависимости от значений TLSCompressed.length. При этом выходные данные любого AEAD-шифра не должны превышать исходные данные более чем на 1024 байт. Символически это может быть записано как:

AEADEncrypted = AEAD-Encrypt(write_key, nonce, plaintext, additional_data)

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

TLSCompressed.fragment = AEAD-Decrypt(write_key, nonce, AEADEncrypte, additional_data)

При невозможности расшифровки должно быть сгенерировано сообщение фатальной ошибки «bad_record_mac».

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

Алгоритму записи требуется алгоритм генерации ключа, который необходим для функционирования протокола в рабочем состоянии соединения (см. Прил. А. 6). Сам ключ генерируется из параметров безопасности, предоставляемых протоколом рукопожатия[21].

Основной секрет (англ. master secret) преобразуется в последовательность защищенных байтов, которая затем разделяется на:

  • client write MAC key, server write MAC key (ключи аутентификации данных, записанных клиентом и сервером, соответственно);

  • client write encryption key, server write encryption key (ключи шифрования данных, записанных клиентом и сервером, соответственно).

Каждый из ключей генерируется из байтовой последовательности в указанном порядке. Неиспользуемые значения отбрасываются. Некоторые шифры AEAD могут дополнительно требовать client write IV и server write IV (векторы инициализации данных, записанных клиентом и сервером, соответственно) (см. п. 6.2.3.3).

После генерации ключей и ключей MAC главный секрет используется как источник энтропии[22].

Вычисление ключевого материала[23] (англ. key material) происходит с использованием следующей псевдослучайной функции (PRF) до того момента, пока не будет вычислен достаточный объем данных:

key_block = PRF(SecurityParameters.master_secret,
                      "key expansion",
                      SecurityParameters.server_random +
                      SecurityParameters.client_random);

[24]После чего key_block делится на части в следующем порядке:

      client_write_MAC_key[SecurityParameters.mac_key_length]
      server_write_MAC_key[SecurityParameters.mac_key_length]
      client_write_key[SecurityParameters.enc_key_length]
      server_write_key[SecurityParameters.enc_key_length]
      client_write_IV[SecurityParameters.fixed_iv_length]
      server_write_IV[SecurityParameters.fixed_iv_length]

На данный момент client_write_IV и server_write_IV вычисляются только при использовании методики скрытого nonce, описанной в п. 3.2.1 [AEAD] (см. тж. п. 6.2.3.3).

Примечание для реализации: На момент написания стандарта криптонабором, требующим наибольшего размера для значения key_block, является набор AES_256_CBC_SHA256. Он требует 2 x 32 байт для ключей и 2 x 32 байт для ключей MAC, что в общей сложности составляет 128 байт.


[1] MAC – Message Authentification Code. В русскоязычной литературе также может применяться термин «имитовставка».

[2] Протокол изменения параметров шифрования (Прим. перев.).

[3] Параметры безопасности TLS предоставляются протоколом рукопожатия (англ. Handshake protocol) (см. тж. Прил. А.6 стандарта) (Прим. перев.).

[4] Канальное шифрование (англ. bulk cipher) определено в Приложении B данного стандарта как: алгоритм симметричного шифрования, используемый для шифрования больших объемов данных.

[5] О неявном и явном задании векторов инициализации см. п. 6.2.3.3. (Прим. перев.).

[6] Вектор инициализации определен в Приложении B данного стандарта как: элемент, который в CBC-режиме блочного шифрования складывается по модулю 2 с первым блоком незашифрованного текста. О CBC-режиме см. прим. 13 (Прим. перев.).

[7] Однократно используемый параметр, одноразовый параметр (англ. nonce) – аббревиатура от англ. «number that can only be used once». Случайное или псевдослучайное число, однократно выбранное системой при создании параметров сетевого соединения (Прим. перев.).

[8] Таким образом, параметр version задает значения для полей типизированной константы ProtocolVersion. Значение полей этой константы: major = 3, значение поля minor = 3. (см. тж. п. 4. 8 данного стандарта) (Прим. перев.).

[9] Фрагмент незашифрованного сообщения (Прим. перев.).

[10] Hollenbeck, S., "Transport Layer Security Protocol Compression Methods", RFC 3749, May 2004.

[11] В феврале 2015 года вышел документ RFC 7465, запрещающий использование шифра RC4 в криптонаборах протоколов TLS всех версий (Прим. перев.).

[12] Определение состояния шифрования приведено в п. 6.1. Для потокового шифра его состояние шифрования задается параметрами генератора псевдослучайных чисел (ГПСЧ), выдающего гамму (тж. ключевой поток данных, keystream). Гамма складывается по модулю 2 с текстом сообщения (англ. XORed), что дает шифротекст. В этом случае состояние шифрования меняется функцией состояния потокового шифра, задающей новые параметры для ГПСЧ. (Прим. перев.).

[13] CBC, cipher block chaining в приложении B данного стандарта определен как: режим, в котором каждый блок незашифрованного текста складывается по модулю 2 (англ. exclusive-Ored) с предыдущим зашифрованным блоком (либо с вектором инициализации, если этот блок идет первым в последовательности). Для расшифровки каждый блок шифротекста сначала расшифровывается, затем складывается по модулю 2 с предыдущим блоком шифротекста (либо с вектором инициализации).

[14] Moeller, B., "Security of CBC Ciphersuites in SSL/TLS: Problems and Countermeasures", http://www.openssl.org/~bodo/tls-cbc.txt.

[15] Раздел ошибок стандарта содержит указание на неподтвержденную ошибку (ID 6244) в которой говорится, что в блоке SecurityParameters есть параметр block_length, но нет параметра block_size (см. Разд. 6.1.) (Прим. перев.).

[16] Еще один байт данных добавляется для поля padding_length (Прим. перев.).

[17] Canvel, B., Hiltgen, A., Vaudenay, S., and M. Vuagnoux, "Password Interception in a SSL/TLS Channel", Advances in Cryptology -- CRYPTO 2003, LNCS vol. 2729, 2003.

[18] McGrew, D., "An Interface and Algorithms for Authenticated Encryption", RFC 5116, January 2008.

[19] "NIST Special Publication 800-38C: The CCM Mode for Authentication and Confidentiality", https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38c.pdf

[20] Dworkin, M., NIST Special Publication 800-38D, "Recommendation for Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC", November 2007.

[21] Сами параметры безопасности перечислены в Разд. 6.1 (Прим. перев.).

[22] Энтропия – неопределенность в системе. В данном случае под источником энтропии подразумевается достаточно неопределенное для предсказания значение, которое можно использовать, например, как начальное число (затравка) в генераторе псевдослучайных чисел и т. п. (Прим. перев.).

[23] Прил. C данного стандарта определяет ключевой материал как число байт значения key_block, необходимое для генерации ключей записи (write key). В данном определении ключевой материал не включает в себя векторы инициализации (IV). Как видно, здесь термин «ключевой материал» включает в себя и векторы инициализации. (Прим. перев.).

[24] Раздел 5 стандарта определяет PRF как PRF(secret, label, seed). Таким образом, SecurityParameters.master_secret = secret, SecurityParameters.server_random + SecurityParameters.client_random = seed (начальное значение). А строка «key expansion» является меткой (label). Подробнее о PRF стандарта TLS см. Разд. 5. (Прим. перев.).

Источник: https://habr.com/ru/post/574424/


Интересные статьи

Интересные статьи

Финансовый сектор уже давно взял курс на цифровизацию, в том числе и в традиционно консервативных областях – ипотечном кредитовании и регистрации сделок с недвижимостью. Полный переход на электронные ...
Всем привет! Это будет очень маленькая статья. Наша задача тут: подключиться к локальному серверу FTP (я выбрала FileZilla) и отправить туда чего-нибудь используя (очевидно) FTP протокол....
В предыдущей части были описаны подходы, примененные при написании парсера для схемы MTProto. Статья получилась чуть более общей, чем я рассчитывал, на этот раз я постараюсь рассказать бо...
В этой статье мы расскажем, как оптимизировать крупный проект в «Битрикс24» и увеличить его производительность в 3 раза, изменяя настройки MySQL и режим питания CPU. Дано Корпоративн...
Каждый лишний элемент на сайте — это кнопка «Не купить», каждая непонятность или трудность, с которой сталкивается клиент — это крестик, закрывающий в браузере вкладку с вашим интернет-магазином.