Вычисление ключа
Протокол записей требует алгоритма для генерации ключей, 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 отбрасывается.
Спецификация шифра, которая определена в данном документе, требует 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.