RFC: 2246
Оригинал: The TLS Protocol Version 1.0
Другие версии: RFC 4346
Категория: Предложенный стандарт
Дата публикации:
Авторы: ,
Перевод: Семенов Юрий Алексеевич

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

Протокол записей требует алгоритма для генерации ключей, IV и секретных кодов MAC из параметров безопасности, поставляемых протоколом диалога.

Мастерный секретный код (master secret) хэшируется в последовательность байтов, которая присваивается секретным кодам MAC, ключам и IV, требуемых текущим состоянием соединения (смотри приложение A.6). CipherSpecs требует чтобы клиент записал секретный код MAC, чтобы сервер записал секретный код MAC, клиент и сервер записали ключ и IV, которые сформированы из мастерного секретного кода в указанном порядке. Не использованные значения остаются пустыми.

Для генерации ключей вычисляется

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

до тех пор пока не будет сформирован выход. Затем key_block позиционируется следующим образом:

client_write_MAC_secret[SecurityParameters.hash_size]
server_write_MAC_secret[SecurityParameters.hash_size]
client_write_key[SecurityParameters.key_material_length]
server_write_key[SecurityParameters.key_material_length]
client_write_IV[SecurityParameters.IV_size]
server_write_IV[SecurityParameters.IV_size]

Значения client_write_IV и server_write_IV генерируются только для не экспортных блочных шифров. Для экспортируемых блочных шифров, векторы инициализации генерируются позже, как это описано ниже. Любой лишний материал key_block отбрасывается.

Implementation note: Спецификация шифра, которая определена в данном документе, требует 2 x 24 байтовых ключей, 2 x 20 байтовых секретных кодов MAC, и 2 x 8 байтов IV, для 104 байтов материала ключей.

Алгоритмы экспортируемого шифрования (для которого CipherSpec.is_exportable равно 'истинно') требуют дополнительной обработки для получения ключей записи, как это показано ниже:

final_client_write_key =
PRF(SecurityParameters.client_write_key,
                           "client write key",
                           SecurityParameters.client_random +
                           SecurityParameters.server_random);
final_server_write_key =
PRF(SecurityParameters.server_write_key,
                           "server write key",
                           SecurityParameters.client_random +
                           SecurityParameters.server_random);

Алгоритмы экспортируемого шифрования получают свои IV исключительно из случайных кодов сообщений hello:

iv_block = PRF("", "IV block", SecurityParameters.client_random +
               SecurityParameters.server_random);

Блок iv_block делится на два инициализационных векторов, как это делалось выше для key_block:

client_write_IV[SecurityParameters.IV_size]
server_write_IV[SecurityParameters.IV_size]

Заметим, что PRF используется в этом случае без секретного кода: это означает, что секретный код имеет длину нуль байт и не вносит ничего в хэширование PRF.

6.3.1. Пример генерации экспортного ключа

TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 требует пяти случайных байт для каждого из двух ключей шифрования и 16 байт для каждого ключа MAC, что составляет 42 байта ключевого материала. Выход PRF запоминается в key_block. Блок key_block делится, а ключи записи запоминаются, так как это алгоритм экспортного шифрования.

key_block               = PRF(master_secret,
                              "key expansion",
                              server_random +
                              client_random)[0..41]
client_write_MAC_secret = key_block[0..15]
server_write_MAC_secret = key_block[16..31]
client_write_key        = key_block[32..36]
server_write_key        = key_block[37..41]

final_client_write_key  = PRF(client_write_key,
                              "client write key",
                              client_random +
                              server_random)[0..15]
final_server_write_key  = PRF(server_write_key,
                              "server write key",
                              client_random +
                              server_random)[0..15]

iv_block                = PRF("", "IV block", client_random +
                              server_random)[0..15]
client_write_IV = iv_block[0..7]
server_write_IV = iv_block[8..15]
2007 - 2017 © Русские переводы RFC, IETF, ISOC.