Основная функция протокола
Протокол
Перечислим задачи протокола
Протокол состоит из двух уровней. Нижним уровнем, расположенным выше
некоторого надежного протокола (а именно, протокола ТСР) является
Одно из преимуществ
Определены четыре криптографические операции: цифровая подпись,
поточное шифрование,
В операции цифровой подписи входом в алгоритм подписи является результат применения односторонней хэш-функции к подписываемым данным. Длина входа определяется алгоритмом подписи.
При использовании алгоритма RSA подписывается 36-байтная структура, состоящая из конкатенации 20 байтов хэш-кода SHA-1 и 16 байтов хэш-кода MD5.
При использовании DSS 20 байтов хэш-кода SHA-1 подаются на вход алгоритму DSA без дополнительного хэширования. При этом создается два значения: r и s.
При поточном шифровании для незашифрованного текста выполняется операция XOR с тем же количеством значений, созданных криптографически безопасным (с ключом) генератором псевдослучайных чисел.
При блочном шифровании каждый блок незашифрованного текста шифруется, в результате чего создается блок зашифрованного текста. Все алгоритмы блочного шифрования выполняются в режиме СВС, и длина всех шифруемых элементов должна быть кратна длине блока алгоритма шифрования.
При шифровании с открытым ключом используется алгоритм открытого ключа, при этом данные могут быть дешифрованы только с помощью соответствующего закрытого ключа.
Для получения МАС используется НМАС, поэтому если не знать секрета МАС, подделать МАС невозможно.
НМАС может использоваться с различными хэш-алгоритмами. HMAC_MD5 (secret, data) и HMAC_SHA (secret, data). Могут быть
определены дополнительные хэш-алгоритмы, но в настоящей версии
используются только MD5 и SHA-1.
В алгоритме определена функция, которая расширяет секрет до нужной
длины для создания всех необходимых ключей. Такая псевдослучайная
функция, , получает в качестве входа секрет, "зерно" (seed –
значение, которое с одной стороны является случайным, а с другой
стороны не является секретным, т.е. может стать известно оппоненту) и
идентификационную метку, и создает выход требуемой длины.
Для того чтобы сделать как можно более безопасной, используются
два безопасных хэш-алгоритма.
Во-первых, определяется 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) + ...
Где
+ – обозначает конкатенацию.
А () – определяется следующим образом:
А (0) = seed
A (i) = HMAC_hash (secret, A (i – 1))
P_hash может иметь столько итераций, сколько необходимо для создания
требуемого количества данных. Например, если P_SHA-1 используется для
создания 64 байтов данных, то количество итераций должно быть равно
4, при этом будет создано 80 байтов данных; последние 16 байтов
заключительной итерации будут отброшены, чтобы оставить только 64
байта выходных данных.
создается путем расщепления секрета на две половины, одна
половина используется для создания данных с помощью P_MD5, а другая –
для создания данных с помощью P_SHA-1, после чего оба выхода этих
функций складываются по модулю 2.
определяется как результат сложения по модулю 2 этих двух
псевдослучайных значений.
Label является фиксированной текстовой строкой.
Заметим, что поскольку MD5 создает 16-байтные значения, а SHA-1
создает 20-байтные значения, то границы внутренних итераций не будут
совпадать. Например, для создания 80-байтного значения необходимо
выполнить 5 итераций P_MD5 и 4 итерации P_SHA-1.
Выше
Параметры безопасности для состояний чтения и записи устанавливаются с помощью следующих значений (см. таб. 21.1).
Уровень записи использует параметры безопасности для создания следующих шести элементов:
client write MAC secret
server write MAC secret
client write key
server write key
client write IV – только для блочных алгоритмов
server write IV – только для блочных алгоритмов
Параметры client write используются сервером, когда он получает
сообщения и клиентом, когда тот посылает их. Параметры server write
применяются сервером, когда он посылает сообщения и клиентом, когда
он получает их. После того как параметры безопасности установлены и
ключи созданы, ожидаемые
| Конец соединения | Каждый участник является либо "клиентом", либо "сервером" |
| Алгоритм симметричного шифрования | Алгоритм, используемый для симметричного шифрования. Данное описание включает размер ключа алгоритма, тип алгоритма (блочный или поточный), размер блока алгоритма и информацию о том, является ли он "экспортируемым" |
| МАС алгоритм | Алгоритм, используемый для проверки целостности сообщения. Это описание включает размер хэша, который возвращается МАС-алгоритмом |
| Алгоритм сжатия | Алгоритм, используемый для сжатия данных. Данное описание включает всю информацию, необходимую алгоритму сжатия |
| Мастер-секрет | 48-байтный секрет, разделяемый обоими участниками соединения |
| Случайное число клиента | 32-байтное значение, создаваемое клиентом |
| Случайное число сервера | 32-байтное значение, создаваемое сервером |
| Алгоритм МАС | МАС-секрет |
| Последовательный номер | Каждое |
Уровень Записи получает данные от более высоких уровней в блоках произвольной длины.
Уровень Записи фрагментирует блоки в записи TLSPlaintext, поддерживая
цепочки данных длиной не более 214 байт. ContentType
могут быть размещены в одной записи TLSPlaintext или единственное
сообщение может быть фрагментировано в несколько записей.
Все записи сжимаются с использованием алгоритма сжатия, определенного
в текущем состоянии сессии. Первоначально он определяется как CompressionMethod.null. Алгоритм сжатия преобразует TLSPlaintext -структуру в TLSCompressed -структуру.
Если функция декомпрессии определяет, что длина декомпрессированного фрагмента превышает 214 байтов, возникает фатальная ошибка декомпрессии.
struct {
ContentType type;
/* same as TLSPlaintext.type */
ProtocolVersion version;
/* same as TLSPlaintext.version */
uint16 length;
opaque fragment[TLSCompressed.length];
} TLSCompressed;
length – длина (в байтах) следующего TLSCompressed.fragment.
fragment – сжатая форма TLSPlaintext.fragment.
Функции шифрования и МАС преобразуют TLSCompressed -структуру в TLSCiphertext. Функции дешифрования выполняют обратные
преобразования. Применение МАС включает последовательный номер,
поэтому потерю или повтор сообщений всегда можно обнаружить.
struct {
ContentType type;
ProtocolVersion version;
uint16 length;
select (CipherSpec.cipher_type) {
case stream: GenericStreamCipher;
case block: GenericBlockCipher;
} fragment;
} TLSCiphertext;
МАС выполняется перед шифрованием. Потоковый шифратор шифрует весь
блок, включая МАС. Если CipherSuite есть TLS_NULL_WITH_NULL_NULL, то
шифрование состоит из тождественной операции, т.е. данные не
шифруются и МАС не используется. TLSCiphertext.length есть сумма TLSCompressed.length и CipherSpec.hash_size.
Для блочных алгоритмов функции шифрования и МАС преобразуют TLSCompressed.fragment -структуру из блоков TLSCiphertext.fragment -структур.
Длина зашифрованных данных ( TLSCiphertext.length ) есть сумма TLSCompressed.length, CipherSpec.hash_size и padding_length.
Рассмотрим пример: если длина содержимого ( TLSCompressed.length )
равна 62 байтам и длина МАС равна 20 байтам, то длина перед
добавлением равна 82 байтам. Таким образом, если длина блока равна 8
байтам, то длина добавления должна быть равна 6, чтобы общая длина
была кратна 8. Длина добавления может быть 6, 14, 22 и т.д. до 254.
Если добавление было сделано минимально необходимым, то добавляется 6
байтов, каждый из которых содержит значение 6.
Для блочных алгоритмов для первой записи при определении параметров безопасности создается инициализационный вектор (IV). IV для следующих записей является последним зашифрованным блоком предыдущей записи.
Из мастер-секрета с использованием хэш-функций создается
последовательность байтов, которая представляет собой МАС-секреты,
ключи и инициализационные вектора: client write MAC secret, server
write MAC secret, client write key, server write key, client write IV
и server write 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 сбрасывается.
Для экспортируемых алгоритмов шифрования (для которых CipherSpec.is_exportable есть true ) требуется дополнительное
вычисление ключей записи:
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_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]
Заметим, что в данном случае используется без секрета: это
означает, что секрет имеет нулевую длину и на результат вычисления не влияет.
В результате выполнения
Протокол состоит из единственного сообщения, которое зашифровано и
сжато, как определено в текущем (не ожидаемом)
| Произвольная последовательность байтов, выбираемая сервером для идентификации активного или возобновляемого состояния сессии | |
| Сертификат участника | Х.509 v3 сертификат участника. Этот элемент может быть нулевым |
| Метод сжатия | Алгоритм, используемый для сжатия данных перед шифрованием |
| Набор алгоритмов | Алгоритм симметричного шифрования данных (такой как
null, DES и т.д.), МАС-алгоритм (такой как MD5 или SHA)
и различные криптографические атрибуты, такие как hash_size |
| Мастер-секрет | 48-байтный секрет, разделямый клиентом и сервером |
| Возобновляемо | Флаг, определяющий, может ли данная сессия использоваться для создания нового соединения |
Сообщение об изменении шифрования может посылаться как клиентом, так
и сервером для уведомления получающей стороны о том, что следующие
записи будут защищены алгоритмами и ключами, о которых стороны только
что договорились. При поступлении данного сообщения получатель должен
информировать
Одним из протоколов, лежащих выше
Клиент и сервер должны оба узнать о том, что соединение завершается. Каждый участник может инициировать обмен сообщениями закрытия.
Сообщение close_notify уведомляет получателя о том, что отправитель
не будет больше посылать никаких сообщений по данному соединению.
Сессия становится невозобновляемой, если хотя бы одно соединение
завершено без соответствующего предупреждающего сообщения close_notify.
Каждый участник может инициировать закрытие посылкой сообщения Alert
типа close_notify. Любые данные, отправленные после Alert-закрытия,
игнорируются.
Требуется, чтобы каждый участник посылал close_notify Alert перед
закрытием стороны записи соединения. Это означает, что при получении
ответа другого участника с Alert типа close_notify соединение
немедленно закрывается и все ожидаемые состояния сбрасываются.
Инициатору закрытия не обязательно ждать ответного close_notify Alert
перед закрытием стороны чтения соединения.
Если прикладной протокол, использующий close_notify перед тем как сообщать прикладному
уровню, что соединение close_notify. В стандарте
Замечание: предполагается, что при закрытии соединения ожидающие доставки данные надежно доставляются перед разрушением транспорта.
Ошибки обрабатываются в
Для всех ошибок, у которых уровень Alert явно не задан, посылающая сторона сама может определять, является ошибка фатальной или нет. Если получен Alert с уровнем предупреждения, получающая сторона может решать, интерпретировать ли сообщение как фатальное.
Unexpected_message |
Получено неожидаемое сообщение. Этот Alert всегда фатальный и никогда не должен возникать во взаимодействии корректных реализаций |
Bad_record_mac |
Данный Alert возвращается, если полученная запись имеет некорректный МАС. Данное сообщение всегда фатально |
Decryption_failed |
TLSCiphertext дешифрован недопустимым
способом: некратная длина блока или недопустимые добавленные значения. Данное сообщение всегда фатально |
Record_overflow |
Полученная TLSCiphertext запись имеет длину больше 214 + 2048 байт, или дешифрованная
TLSCompressed запись имеет длину больше 214 + 1024 байт. Данное сообщение всегда фатально |
Decompression_failure |
Функция декомпрессии получила неправильные входные данные. Данное сообщение всегда фатально |
Handshake_failure |
Получение сообщения handshake_failure
Alert говорит о том, что отправитель не смог договориться о приемлемом наборе параметров
безопасности. Данное сообщение всегда фатально |
Bad_certificate |
Сертификат испорчен, например содержит некорректную подпись |
Unsupported_certificate |
Сертификат неподдерживаемого типа |
Certificate_revoked |
Сертификат отменен тем, кто его подписал |
Certificate_expired |
Срок действия сертификата истек и в настоящее время он недействителен |
Certificate_unknown |
Другой результат (неопределенный), полученный в результате обработки сертификата, сертификат не принимается |
Illegal_parameter |
Некоторое поле находится вне диапазона или не согласуется с другими полями. Данное сообщение всегда фатально |
Unknown_ca |
Получена цепочка законных сертификатов или некоторая часть цепочки, но сертификат не принимается, потому что сертификат СА не соответствует известному СА, с которым установлены доверительные отношения. Данное сообщение всегда фатально |
Access_denied |
Получен законный сертификат, но при применении контроля доступа отправитель решил не продолжать переговоры. Данное сообщение всегда фатально |
Decode_error |
Сообщение не может быть декодировано, потому что некоторое поле находится вне специфицированного диапазона или некорректна длина сообщения. Данное сообщение всегда фатально |
Decrypt_error |
Не выполнена криптографическая операция Рукопожатия, которая включает проверку подписи, дешифрование обмена ключа и проверку правильности завершающего сообщения |
Export_restriction |
Переговоры не выполнены из-за экспортных
ограничений; например, попытка передать
1024-битный ключ RSA для метода Рукопожатия RSA_EXPORT. Данное сообщение всегда фатально |
Protocol_version |
Версия протокола, с которой клиент пытается вести переговоры, распознана, но не поддерживается. Например, старая версия протокола не должна использоваться по причинам безопасности. Данное сообщение всегда фатально |
Insufficient_security |
Возвращается вместо handshake_failure,
когда переговоры прекращаются из-за того, что
сервер требует более безопасных алгоритмов, чем
предложены клиентом. Данное сообщение всегда
фатально |
Internal_error |
Внутренняя ошибка, не относящаяся к участникам, но делающая невозможным дальнейшее ведение переговоров (например, невозможность распределения памяти). Данное сообщение всегда фатально |
User_canceled |
Данное Рукопожатие прервано по некоторой причине, не относящейся к падению протокола. Если
пользователь прервал операцию после завершения Рукопожатия, то для закрытия соединения
больше подходит сообщение close_notify.
Данное сообщение обычно является предупреждающим |
No_renegotiation |
Посылается клиентом в ответ на запрос Hello
или сервером в ответ на Hello клиента после начала Рукопожатия. Это приводит к
невозможности вести новые переговоры; в этой точке тот, кто
осуществил первоначальный запрос, может решить продолжать ли использовать данное
соединение. Одним из случаев, который может соответствовать данной ситуации, может быть
порождение сервером нового процесса для удовлетворения запроса; процесс должен при старте получить
параметры безопасности (длину ключа, аутентификацию и т.д.), и возможности внести
изменения в параметры после этой точки быть не должно. Данное сообщение всегда является предупреждающим |
Криптографические параметры состояния сессии создаются
Hello для согласования алгоритмов, обмен
случайными значениями и проверка возобновляемости сессии.Заметим, что протоколы более высокого уровня всегда должны считать,
что
Данные цели достигаются Client
Hello, на которое сервер должен ответить сообщением Server Hello или
фатальной ошибкой и прерыванием соединения. Client Hello и Server
Hello используются для определения максимального уровня безопасности
между клиентом и сервером. Client Hello и Server Hello устанавливают
следующие атрибуты: Protocol Version, Session ID, Cipher Suite и Compression Method. Дополнительно создаются и передаются два
случайных значения: ClientHello.random и ServerHello.random.
Аутентификация и обмен общим секретом осуществляются в четырех сообщениях: сертификат сервера, обмен ключа сервера, сертификат клиента и обмен ключа клиента. Общий секрет должен быть достаточно большим; текущие методы распределения ключа обмениваются секретами, длина которых находится в диапазоне от 48 до 126 байт.
После сообщений Hello сервер посылает сертификат для аутентификации.
Дополнительно может быть послано сообщение обмена ключа сервера, если
сервер не имеет сертификата или его сертификат служит только для
подписи. Если сервер аутентифицирован, он может запросить сертификат
клиента, если того требует установленная политика безопасности.
Теперь сервер посылает сообщение Server Hello Done, указывающее на
то, что фаза Hello -сообщений Рукопожатия завершена. Затем сервер ждет
ответа клиента. Если сервер послал сообщение запроса сертификата,
клиент должен послать сообщение Certificate. После этого посылается
сообщение обмена ключа клиента, содержимое этого сообщения зависит от
выбранного алгоритма открытого ключа в сообщениях Client Hello и Server Hello. Если клиент имеет сертификат для подписывания, то
посылается сообщение цифровой подписи для явной проверки всех
сообщений Рукопожатия.
В данной точке клиентом посылается сообщение об изменении состояния, и клиент копирует ожидаемое состояние в текущее состояние. После этого клиент посылает заключительное сообщение с использованием новых алгоритмом, ключей и секретов. В ответ сервер посылает свое сообщение об изменении состояния, преобразует ожидаемое состояние в текущее состояние и посылает заключительное сообщение с использованием новых алгоритмов и ключей. После этого Рукопожатие считается выполненным, и клиент и сервер могут начинать обмен данными прикладного уровня.
Замечание: для того чтобы избежать остановок, ChangeCipherSpec
реализован как независимый тип протокола и частью
Когда клиент и сервер решают возобновить предыдущую сессию или дублировать существующую (вместо того чтобы вести новые переговоры о параметрах безопасности), поток сообщений передается следующим образом.
Клиент посылает ClientHello, используя Session ID возобновляемой
сессии. Сервер ищет соответствующий ServerHello с тем
же самым значением Session ID. В этой точке и клиент, и сервер должны
послать сообщения об изменении состояния, после чего сразу послать
завершающие сообщения. После этого клиент и сервер начинают обмен
данными прикладного уровня. Если соответствующий Session ID не
найден, сервер создает новый ID сессии, и клиент и сервер выполняют
полное Рукопожатие.
Поток сообщений при сокращенном Рукопожатии
Рассмотрим в деталях каждое сообщение
Последовательность сообщений при полном Рукопожатии
| Клиент | Сервер | |
|---|---|---|
| ClientHello | $$\Rightarrow$$ | |
| ServerHello | ||
| Certificate * | ||
| ServerKeyExchange * | ||
| CertificateRequest * | ||
| $$\Leftarrow$$ | ServerHelloDone | |
| Certificate * | ||
| ClientKeyExchange | ||
| CertificateVerify * | ||
| [ ChangeCipherSpec ] | ||
| Finished | $$\Rightarrow$$ | |
| [ChangeCipherSpec ] | ||
| $$\Leftarrow$$ | Finished | |
| Прикладные данные | $$\Leftrightarrow$$ | Прикладные данные |
TLSPlaintext, которые обрабатываются и передаются, как определено
текущим активным состоянием сессии.
Сообщения Cеrtificate используется дважды при Рукопожатии
(от сервера к клиенту, затем от клиента к серверу), но описано оно
только один раз. Единственным сообщением, которое не связано данными
правилами упорядоченности, является сообщение Hello Request. Оно
может быть послано в любое время, но должно игнорироваться клиентом,
если поступает в середине Рукопожатия.
| Клиент | Сервер | |
|---|---|---|
| ClientHello | $$\Rightarrow$$ | |
| ServerHello | ||
| [ ChangeCipherSpec ] | ||
| $$\Leftarrow$$ | Finished | |
| [ ChangeCipherSpec ] | ||
| Finished | $$\Rightarrow$$ | |
| Прикладные данные | $$\Leftrightarrow$$ | Прикладные данные |
Сообщения фазы Hello используются для обмена возможностями
установления безопасного соединения между клиентом и сервером. Когда
начинается новая сессия, алгоритмы шифрования, хэширования и сжатия null.
Параметры текущего
Hello Request
Сообщение Hello Request может быть послано сервером в любое время.
Hello Request является просто уведомлением о том, что клиент должен
начать процесс переговоров заново посылкой сообщения Hello. Данное
сообщение будет игнорироваться клиентом, если он находится в
состоянии переговоров. Данное сообщение может игнорироваться
клиентом, если он не хочет вести новые переговоры, при этом клиент
может ответить no_renegotiation Alert. Если сервер посылает Hello
Request, но не получает в ответ Client Hello, он может закрыть
соединение с фатальным Alert.
После посылки Hello Request сервер не должен повторять запрос до тех
пор, пока последующие переговоры Рукопожатия не будут завершены.
Замечание: данное сообщение никогда не должно включаться в хэши сообщений, которые вычисляются при Рукопожатии и используются в завершающих сообщениях и сообщении проверки сертификата.
Client Hello
Данное сообщение посылается, когда клиент в первый раз соединяется с
сервером. В качестве первого сообщения требуется посылать Client
Hello. Клиент также может послать Client Hello в ответ на Hello
Request или по собственной инициативе, чтобы начать новые переговоры
о параметрах безопасности для существующего соединения.
Сообщение Client Hello содержит случайные числа, которые используются
при создании мастер-секрета.
Сообщение Client Hello может включать SessionID может
использоваться после того, как Finished -сообщениями и сохраняется до тех пор, пока не будет
удален или не произойдет фатальная ошибка в соединении, связанном с
данной сессией.
Следует заметить, что, так как SessionID передается без шифрования и
МАС- защиты, серверы не должны помещать конфиденциальную информацию в
SessionID, защищено Finished -сообщениями,
которыми участники обмениваются в конце Рукопожатия.
Список CipherSuite, передаваемый от клиента серверу в сообщении Client Hello, содержит комбинации криптографических алгоритмов,
поддерживаемых клиентом, упорядоченные согласно предпочтениям
клиента. Каждый CipherSuite определяет алгоритм обмена ключа,
алгоритм основного шифрования (включая длину секретного ключа) и
алгоритм МАС. Сервер будет выбирать набор шифрования или, если
приемлемый выбор невозможен, возвратит Alert падения Рукопожатия и
закроет соединение.
Сlient Hello включает также список алгоритмов сжатия, поддерживаемых
клиентом, упорядоченный согласно предпочтениям клиента.
После посылки сообщения Client Hello клиент ждет сообщения Server
Hello. Любое другое сообщение, возвращаемое сервером, за исключением Hello Request, трактуется как фатальная ошибка.
Замечание о совместимости: в интересах совместимости с последующими
реализациями допускается в сообщение Client Hello включать внешние
данные после методов сжатия. Эти данные должны быть включены в
вычисление хэшей Рукопожатия, но в других отношениях они должны
игнорироваться. Это возможно только для сообщения Рукопожатия; для
всех других сообщений количество данных в сообщении должно точно
соответствовать описанию сообщения.
Server Hello
Сервер посылает данное сообщение в ответ на сообщение Client Hello,
для того чтобы выбрать конкретный набор алгоритмов. Если он не может
сделать такой выбор, он отвечает handshake failure Alert.
Сервер должен посылать сертификат, если метод обмена ключей не
является анонимным. Данное сообщение всегда следует сразу за
сообщением Server Hello.
Тип сертификата должен соответствовать выбранному алгоритму обмена ключа. Обычно это сертификат X.509v3. Он должен содержать ключ, который соответствует методу обмена ключа. Если не указано иное, то алгоритм подписывания должен быть тем же самым, что и алгоритм для обмена ключа. Если не указано иное, то открытый ключ может иметь произвольную длину.
Все профили сертификатов, ключи и криптографические форматы
определены рабочей группой IETF PKIX. Если допускается различное
использование ключа, то должен быть установлен бит digitalSignature
для ключа, который может применяться для подписывания, и должен быть
установлен бит keyEncipherment для ключа, которым можно шифровать.
Бит keyAgreement должен быть установлен для сертификатов
Диффи-Хеллмана.
Могут быть определены новые методы обмена ключа. Они должны иметь соответствующий формат сертификата и информации о ключе.
Предполагается, что сертификатами являются
Точно такое же сообщение используется для ответа клиента при запросе его сертификата. Клиент может не посылать сертификата, если он его не имеет.
Данное сообщение посылается непосредственно после сообщения Server
Certificate (или сообщения Server Hello, если переговоры анонимные).
Сообщение сервера обмена ключа посылается сервером только тогда,
когда сообщение Server Certificate (если оно послано) не содержит
достаточно данных, чтобы клиент мог осуществить обмен
премастер-секретом. Это верно для следующих методов обмена ключа:
Данное сообщение передает криптографическую информацию, которая позволяет клиенту передавать премастер-секрет: премастер-секрет шифруется либо открытым ключом RSA, либо открытым ключом Диффи-Хеллмана, с помощью которого клиент может завершить обмен ключа.
Таким образом, сообщение сервера обмена ключа будет послано тогда и только тогда, когда тип сертификата, связанный с алгоритмом обмена ключа, не предоставляет достаточно информации клиенту для обмена премастер-секретом.
Неанонимный сервер может дополнительно запросить сертификат клиента,
если это Server Key
Exchange, если оно послано; в противном случае – за сообщением Server
Certificate.
Следует помнить, что запрос идентификации клиента от анонимного
сервера является фатальным handshake_failure Alert.
Сообщение Server Hello Done посылается сервером для обозначения
окончания фазы Server Hello и связанных с ней сообщений. После
посылки данного сообщения сервер ждет ответа клиента.
Данное сообщение означает, что сервер завершил отправку сообщений, поддерживающих обмен ключа.
| Алгоритм обмена ключа | Тип ключа сертификата |
| RSA | Открытый ключ RSA; сертификат должен позволять задействовать ключ для шифрования |
| RSA_EXPORT | Учтены экспортные ограничения, т.е. открытый ключ RSA
длиной больше 512 бит может использоваться для подписывания, ключ 512 бит и короче может использоваться как для
подписи, так и для шифрования. В первом случае следующим
сообщением должно быть ServerKeyExchange, в котором
этим ключом будут подписаны открытые ключи Диффи-Хеллмана или другой открытый ключ RSA |
| DH_DSS | Открытый ключ DSS. Обмен ключа осуществляется по алгоритму Диффи-Хеллмана |
| DH_RSA | Открытый ключ RSA, который может использоваться для подписывания. Обмен ключа осуществляется по алгоритму Диффи-Хеллмана |
При получении сообщения Server Hello Done клиент должен убедиться,
что сервер предоставил законный сертификат и что Hello параметры
сервера приемлемы для клиента.
Это первое сообщение, которое клиент посылает после получения
сообщения Server Hello Done. Оно посылается только в том случае, если
сервер требует сертификат. Если подходящий сертификат недоступен,
клиент должен послать сообщение Certificate, не содержащее
сертификатов. Если сервер требует аутентификации клиента для
продолжения Рукопожатия, он может ответить фатальным handshake
failure Alert. Структура сертификатов клиента такая же, как и
сервера.
Если применяется метод обмена ключа, основанный на алгоритме
Диффи-Хеллмана ( DH_DSS или DH_RSA ) и требуется аутентификация
клиента, то группа и генератор Диффи-Хеллмана, содержащиеся в
сертификате клиента, должны соответствовать параметрам
Диффи-Хеллмана, определенным для сервера, если параметры клиента
используются для обмена ключа.
Данное сообщение посылается клиентом всегда. Оно следует сразу за
сообщением Client Certificate, если таковое посылается. В противном
случае это первое сообщение, посланное клиентом после получения
сообщения Server Hello Done.
В данном сообщении устанавливается премастер-секрет, который
передается либо с помощью RSA шифрования, либо с использованием
DH_RSA
или DH_DSS и сертификат клиента запрашивается, клиент может ответить
сертификатом, содержащим открытый ключ Диффи-Хеллмана, чьи параметры
(группа и генератор) должны соответствовать тем, которые
специфицированы в сертификате сервера. Никаких других данных это
сообщение не содержит.
Структура сообщения зависит от выбранного метода обмена ключа.
Если для согласования общего секрета и аутентификации используется
RSA, клиент создает 48-байтный премастер-секрет, шифрует его с
использованием открытого ключа из сертификата сервера или временного
ключа RSA, полученного в сообщении Server Key Exchange.
Данное сообщение используется для обеспечения явной проверки
целостности сообщений Рукопожатия с помощью сертификата клиента. Оно
посылается только в том случае, если сертификат клиента имеет
возможность подписывания (т.е. все сертификаты, за исключением тех,
которые используют Client Key Exchange.
Здесь handshake_messages означает все сообщения Рукопожатия,
посланные или полученные во время Рукопожатия, начиная с Client
Hello, но не включая данное сообщение. Включаются поля типа и длины
сообщений Рукопожатия. Хэш вычисляется от конкатенации всех структур,
посланных и полученных в сообщениях Рукопожатия.
Сообщение Finished всегда посылается непосредственно после сообщения Сhange Сipher Spec для проверки успешного выполнения обмена ключа и
процессов аутентификации. Причем сообщение Change Cipher Spec должно
быть получено после остальных сообщений Рукопожатия и перед Finished -сообщением.
Finished -сообщение является первым сообщением, защищенным с помощью
только что обговоренных алгоритмов, ключей и секретов. Получатели Finished -сообщения должны убедиться, что его содержимое корректно.
После того как одна сторона послала свое Finished -сообщение, получила
и проверила Finished сообщение другой стороны, она может начинать
посылать и получать прикладные данные по этому соединению.
Возникает фатальная ошибка, если сообщению Finished не предшествует
сообщение Change Cipher Spec.
Хэш, содержащийся в сообщениях Finished, посылается сервером в Sender.server и клиентом – в Sender.client. Значение handshake_message включает все сообщения Рукопожатия, начиная от Client Hello, но не включая данное Finished -сообщение. Это может
отличаться от handshake_message, которые включают сообщение проверки
сертификата (если он посылается). Также handshake_message в сообщении Finished, посылаемом сервером, отличается от сообщения Finished,
посылаемом клиентом, потому что сервер посылает его вторым, включая
предшествующее сообщение.
Напомним, что сообщения о смене шифратора, Alerts и другие типы
записей не являются сообщениями Рукопожатия и в вычисление хэша не
включаются. Сообщения Hello Request в хэшах Рукопожатия также
опущены.
Независимо от методов обмена ключа используется следующий алгоритм для преобразования премастер-секрета в мастер-секрет. Премастер секрет должен быть сброшен после того, как вычислен мастер-секрет.
master_secret = PRF(pre_master_secret,
"master secret",
ClientHello.random + ServerHello.random)
[0..47];
Длина мастер-секрета всегда равна 48 байтам. Длина премастер-секрета изменяется в зависимости от метода обмена ключа.
RSA
Когда для аутентификации сервера и обмена ключа используется RSA, клиентом создается 48-байтный премастер-секрет, зашифрованный открытым ключом сервера, и посылается серверу. Сервер использует свой закрытый ключ для дешифрования премастер-секрета. Затем оба участника преобразуют премастер-секрет в мастер-секрет, как описано выше.
Диффи-Хеллман
Выполняются обычные вычисления Диффи-Хеллмана. Полученный ключ используется в качестве премастер-секрета для преобразования в мастер-секрет, как описано выше.
Рассмотрим расширения, которые могут использоваться для добавления
функциональности в Hello клиента и сервера, так и конкретные расширения,
используемые этими механизмами.
Сейчас
Беспроводные окружения часто имеют ряд ограничений, обычно отсутствующих в других окружениях. Эти окружения могут иметь ограничения на ширину полосы пропускания, на вычислительные мощности, на память, на срок жизни батарейки.
Описываемые здесь расширения предназначены для расширения
функциональности, предоставляемой форматами сообщений протокола
Данные расширения предназначены для обеспечения следующих возможностей:
Для того чтобы поддерживать перечисленные выше расширения, вводятся
дополнительные механизмы для сообщений Hello клиента и сервера.
Описываемые расширения могут использоваться клиентами
Обратная совместимость достигается следующим образом.
Client Hello, описанного ниже. Client Hello, даже если они
не понимают расширения.Однако заметим, что хотя обратная совместимость поддерживается, некоторые клиенты из-за своих ограниченных возможностей могут не устанавливать соединения с серверами, которые не поддерживают расширения.
Рассмотрим дополнительные функциональности в следующем порядке.
Сначала опишем общие механизмы расширений для сообщений Рукопожатия Client Hello и Server Hello. Далее опишем конкретные расширения для
Рассмотрим общие механизмы расширений для сообщений Рукопожатия Client Hello и Server Hello.
Эти общие механизмы расширений необходимы для того, чтобы клиенты и серверы имели возможность вести переговоры об использовании конкретных расширений.
Сначала опишем формат расширенного сообщения Client Hello, затем
формат расширенного сообщения Server Hello и формат реально
используемого расширения.
Клиент может запросить расширенную функциональность от сервера,
посылая расширенный формат сообщения Client Hello вместо обычного
формата сообщения Client Hello. Расширенный формат сообщения Client
Hello следующий:
struct {
ProtocolVersion client_version;
Random random;
SessionID session_id;
CipherSuite cipher_suites<2..2^16-1>;
CompressionMethod
compression_methods<1..2^8-1>;
Extension
client_hello_extension_list<0..2^16-1>;
} ClientHello;
Здесь новое поле client_hello_extension_list содержит список
расширений.
Если клиент запросил дополнительную функциональность, используя
расширенный Client Hello, и данная функциональность не поддерживается
сервером, клиент может прервать Рукопожатие.
Заметим, что Client Hello. Таким образом, использование расширенного Client Hello
не должно приводить к разрыву соединения с существующими серверами
Сервер, который поддерживает механизм расширений, должен принимать
как исходный формат, так и расширенный формат Client Hello, и (как и
для всех остальных сообщений) проверять, соответствует ли количество
данных в сообщении одному из этих форматов; если это не так, он
должен послать фатальный Alert decode_error.
Расширенный формат сообщения Server Hello может быть послан вместо
сообщения Server Hello, когда клиент запросил дополнительную
функциональность с помощью расширенного сообщения Server Hello.
Расширенный формат сообщения Server Hello следующий:
struct {
ProtocolVersion server_version;
Random random;
SessionID session_id;
CipherSuite cipher_suite;
CompressionMethod compression_method;
Extension
server_hello_extension_list<0..2^16-1>;
} ServerHello;
Здесь новое поле server_hello_extension_list содержит список
расширений. Реальный формат расширения будет определен ниже.
Заметим, что расширенное сообщение Server Hello посылается только в
ответ на расширенное сообщение Client Hello. Это позволит избежать
ситуации, при которой расширенное сообщение Server Hello не даст
установить соединение с существующими клиентами
Формат расширения для Client Hello и Server Hello следующий:
struct {
ExtensionType extension_type;
opaque extension_data<0..2^16-1>;
} Extension;
Где:
extension_type определяет конкретный тип расширения;extension_data содержит информацию, относящуюся к конкретному типу расширения.
Определены следующие типы расширений:enum {
server_name(0), max_fragment_length(1),
client_certificate_url(2),
trusted_ca_keys(3), truncated_hmac(4),
status_request(5), (65535)
} ExtensionType;
Заметим, что для всех типов расширений (включая и те, которые будут
определены в дальнейшем) тип расширения не должен появляться в
расширенном Server Hello, пока не появится в соответствующем Client
Hello. Таким образом, клиенты должны прерывать Рукопожатия, если
получили расширенный тип в расширенном Server Hello, который не был
запрошен в соответствующем Client Hello.
Расширения, инициируемые сервером (server initiated), могут присутствовать в будущем в рамках данного протокола, при этом требуется, чтобы клиент первым посылал пустое расширение, указывая тем самым, что он готов принимать подобное расширение.
Если в расширенном Client Hello или расширенном Server Hello
присутствует несколько расширений различных типов, они могут
появляться в произвольном порядке. Не должно быть более одного
расширения каждого типа.
Наконец, заметим, что все расширения, определенные в настоящий
момент, относятся только к инициализации сессии. Однако клиент,
который послал запрос на возобновление сессии, не знает, будет ли
принят данный запрос, и, следовательно, должен послать расширенный Client Hello, если это необходимо для новой сессии. Если запрос на
возобновление отвергнут, будут вестись переговоры о новом множестве
расширений. Если, с другой стороны, старая сессия возобновляется, то
сервер должен игнорировать расширения, появившиеся в Client Hello, и
послать Server Hello, не содержащий расширений. В этом случае
используется расширение, о котором участники договорились при
инициализации исходной сессии, возобновлением которой является данная
сессия.
Поддерживается использование двух новых сообщений Рукопожатия: CertificateURL и CertificateStatus. Новая структура сообщения
рукопожатия:
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), certificate_url(21),
certificate_status(22), (255)
} HandshakeType;
struct {
HandshakeType msg_type;
/* handshake type */
uint24 length;
/* bytes in message */
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;
case certificate_url: CertificateURL;
case certificate_status: CertificateStatus;
} body;
} Handshake;
Рассмотрим используемые расширения
Заметим, что любые сообщения, соответствующие этим расширениям,
посылаются при Рукопожатии и должны включаться в вычисления хэша в
сообщение Finished.
Сначала рассмотрим расширение, позволяющее клиенту указать сервер, с
которым он соединяется. Затем опишем расширение для указания
максимальной длины фрагмента. Далее опишем расширение, которое
позволяет клиенту указать URLs сертификатов, и расширение,
позволяющее указать ключи корневых СА. Наконец, опишем расширение,
которое позволяет задействовать урезанный HMAC, и расширение,
поддерживающее интеграцию сообщения с информацией о статусе
сертификата в Рукопожатие
Исходный протокол не предоставляет механизма, который позволял бы клиенту указать имя сервера, с которым он хочет соединиться. Однако это может требоваться для обеспечения безопасного соединения с хостами, у которых имеется несколько виртуальных серверов на одном сетевом адресе.
Для того чтобы указать имя сервера, клиент может включить расширение
типа server_name в Client Hello. Поле extension_data должно содержать ServerNameList:
struct {
NameType name_type;
select (name_type) {
case host_name: HostName;
} name;
} ServerName;
enum {
host_name(0), (255)
} NameType;
opaque HostName<1..2^16-1>;
struct {
ServerName server_name_list<1..2^16-1>
} ServerNameList;
На сегодня в качестве имени сервера поддерживается только DNS
hostname. Это не означает какой-либо зависимости
HostName содержит полностью определенное DNS hostname сервера. Hostname является байтовой строкой, представленной с использованием
UTF-8.
Сервер, который получил сообщение Client Hello, содержащее расширение server_name, может использовать данную информацию для выбора
сертификата, возвращаемого клиенту, либо для каких-то других аспектов
безопасности. В данном случае сервер должен включить расширение типа
server_name в расширенное Server Hello. Поле extension_date данного
расширения должно быть пустым.
Если сервер понимает расширение Client Hello, но не смог распознать
имя сервера, он должен послать unrecognized_name Alert (который может
быть фатальным).
Если приложение провело переговоры об имени сервера с использованием
протокола приложения, а затем после модификации server_name, то расширение должно содержать то же самое
имя, о котором участники договорились в прикладном протоколе. Если server_name установлено при Рукопожатии
Прежняя версия
Для этого клиент может указать расширение типа max_fragment_length в Client Hello. Поле extension_data данного расширения должно
содержать:
enum{
2^9(1), 2^10(2), 2^11(3), 2^12(4), (255)
} MaxFragmentLength;
значение которого является требуемой максимальной длиной фрагмента. Допустимыми значениями для данного поля являются: 29, 210, 211 и 212.
Сервер, получивший расширенный Client Hello с расширением max_fragment_length, может принять эту длину, включая расширение типа max_fragment_length в Server Hello. Поле extension_data данного
расширения должно содержать MaxFragmentLength, которое является тем
же самым, что и запрошенная максимальная длина фрагмента.
Если запрошена недопустимая длина фрагмента, сервер должен прервать
Рукопожатие с Alert illegal_parameter. Аналогично, если клиент
получил ответ с максимальной длиной фрагмента, отличной от
запрошенной, он также должен прервать Рукопожатие с Alert illegal_parameter.
После того, как стороны успешно договорились о максимальной длине
фрагмента, отличной от 214, клиент и сервер должны немедленно начать
фрагментировать сообщения (включая сообщения Рукопожатия), чтобы
гарантировать, что не посылаются сегменты большей длины, чем та, о
которой договорились. Заметим, что
Новая длина применяется для продолжения сессии, включая возобновляющиеся сессии.
Для ведения переговоров о посылке серверу URLs сертификата клиенты
могут включать расширение типа client_certificate_url в Client Hello.
Поле extension_data данного расширения должно быть пустым.
Заметим, что необходимо вести переговоры об использовании URLs
сертификатов клиента, чтобы существующие серверы
Сервер, получивший расширенный Client Hello, содержащий расширение client_certificate_url, может указать, что имеет возможность
принимать URLs сертификата, указывая расширение типа client_certificate_url в Server Hello. Поле extension_data данного
расширения должно быть пустым.
После успешного завершения переговоров об использовании URLs
сертификата клиента клиент может посылать сообщение CertificateURL
вместо сообщения Certificate:
enum {
individual_certs(0), pkipath(1), (255)
} CertChainType;
enum {
false(0), true(1)
} Boolean;
struct {
CertChainType type;
URLAndOptionalHash
url_and_hash_list<1..2^16-1>;
} CertificateURL;
struct {
opaque url<1..2^16-1>;
Boolean hash_present;
select (hash_present) {
case false: struct {};
case true: SHA1Hash;
} hash;
} URLAndOptionalHash;
opaque SHA1Hash[20];
Здесь url_and_hash_list содержит последовательность URLs и хэши
(необязательно).
При использовании сертификатов Х.509 существует две возможности:
Certificate.type есть individual_certs, то каждый URL
ссылается на единственный сертификат Х.509v3 в Certificate.type есть PkiPath, то список содержит единственный
URL, ссылающийся на цепочку сертификатов в представлении PkiPath, описанный ниже.При использовании любого другого формата спецификация, описывающая применение этого формата, должна определять формат представления сертификатов или цепочки сертификатов и различные ограничения их последовательности.
Хэш, соответствующий каждому URL, либо не присутствует, либо является
SHA-1 хэшем сертификата или цепочки сертификатов (в случае
сертификатов Х.509 PkiPath ).
Заметим, что когда используется список URLs для сертификатов Х.509,
упорядоченность URLs является той же самой, что и в сообщении Certificate, в противоположность упорядоченности, в которой
сертификаты представлены в PkiPath. В любом случае самоподписанный
корневой сертификат в цепочке может быть опущен, в предположении, что
сервер уже проверил его действительность.
При получении CertificateURL сервер должен пытаться получить цепочку
сертификатов клиента из URLs и затем обработать ее обычным образом.
Может использоваться кэшированная копия содержимого любого URL из
цепочки, проверяя, что SHA-1 хэш присутствует и соответствует хэшу
кэшированной копии.
Серверы, которые поддерживают данное расширение, должны поддерживать http:URL схему для URLs сертификатов и могут поддерживать другие
схемы.
Если протокол, используемый для получения сертификатов или цепочки
сертификатов, возвращает MIME форматированный ответ (как делает
НТТР), то должен применяться следующий MIME Content-Type: при
возврате единственного сертификата Х.509v3 Content-Type есть application/pkix-cert, при возврате цепочки сертификатов Х.509v3
Content-Type есть application/pkix-pkipath.
Если для URL присутствует SHA-1 хэш, то сервер должен убедиться, что
SHA-1 хэш содержимого объекта, полученного из URL (после
декодирования произвольного MIME Content-Transfer-Encoding),
соответствует данному хэшу. Если полученный объект не имеет
корректного SHA-1 хэша, сервер должен прервать Рукопожатие с Alert bad_certificate_hash_value.
Заметим, что клиент может выбрать либо посылку Certificate, либо
посылку CertificateURL после успешных переговоров о посылке URLs
сертификатов. Опция посылки сертификата обеспечивает клиенту гибкость
при обработке нескольких сертификатов.
Если сервер столкнулся с непредвиденной задержкой при получении
сертификатов по указанному CertificateURL, он должен при истечении
таймаута создать Alert ошибки certificate_unobtainable.
Клиенты, которые имеют ограниченную память, обладают только небольшим количеством ключей корневого СА и им может потребоваться указать серверу, какими корневыми ключами они владеют, чтобы избежать падения Рукопожатия.
Для этого клиенты могут включить расширение типа trusted_ca_keys в Client Hello. Поле extension_data данного расширения должно содержать TrustedAuthorities, где:
struct {
TrustedAuthority
trusted_authorities_list<0..2^16-1>;
} TrustedAuthorities;
struct {
IdentifierType identifier_type;
select (identifier_type) {
case pre_agreed: struct {};
case key_sha1_hash: SHA1Hash;
case x509_name: DistinguishedName;
case cert_sha1_hash: SHA1Hash;
} identifier;
} TrustedAuthority;
enum {
pre_agreed(0), key_sha1_hash(1),
x509_name(2), cert_sha1_hash(3), (255)
} IdentifierType;
opaque DistinguishedName<1..2^16-1>;
Здесь TrustedAuthorities содержит список идентификаторов ключей
корневых СА, которыми владеет клиент. Каждый ключ корневого СА
идентифицируется одним из следующих способов:
pre_agreed – не предоставляется никакой идентификации ключа
корневого СА.key_sha1_hash – содержит SHA-1 хэш ключа корневого СА. Для ключей
DSA и ECDSA это хэш значения subjectPublicKey. Для ключей RSA хэш
есть строка байтов модуля без начальных нулевых байтов (аналогично
форматам хэша ключа в других окружениях).х509_name – содержит cert_sha1_hash – содержит SHA-1 хэш Certificate,
содержащего ключ корневого СА.Заметим, что клиенты могут включать в данное расширение несколько или все ключи корневого СА, которыми они владеют, либо ни одного из них.
Также возможна ситуация, при которой хэш ключа или DN по отдельности
не идентифицируют выпускающего сертификат – например, если конкретный
СА имеет несколько пар ключей – однако здесь мы предполагаем, что в
Если данная опция включена, это позволяет клиентам сообщать о наличии у них некоторого предопределенного множества ключей корневого СА.
Сервер, который получил Client Hello с расширением trusted_ca_keys,
может использовать информацию, содержащуюся в расширении, в качестве
руководства по выбору цепочки сертификатов, возвращаемой клиенту. В
данном случае сервер должен включить расширение типа trusted_ca_keys
в Server Hello. Поле extension_data данного расширения должно быть
пустым.
В настоящий момент набор шифрования использует в качестве МАС НМАС
либо с MD5, либо с SHA-1 для аутентификации соединений уровня записи.
Весь выход хэш-функции используется в качестве тега МАС. Однако может
быть желательно в некоторых
Для того чтобы вести переговоры об использовании 80-битного
урезанного МАС, клиенты могут включить расширение типа truncated_hmac
в расширенный Client Hello. Поле extension_data данного расширения
должно быть пустым.
При получении расширенного Hello, содержащего расширение truncated_hmac, сервер может согласиться использовать урезанный МАС
путем включения расширения типа truncated_hmac с пустым extension_data в расширенный Server Hello.
Заметим, что если добавлен новый набор алгоритмов шифрования, который не использует НМАС, и при переговорах выбран один из этих наборов, то данное расширение ни на что не влияет. Рекомендуется, чтобы все новые наборы алгоритмов шифрования, использующие другие МАСs, рассматривали размер МАС как составную часть определения набора шифрования, имея в виду как безопасность, так и ограничения ширины полосы пропускания.
Если переговоры об урезанном МАС успешно завершены, клиент и сервер
передают эту информацию на уровень записи в качестве параметров
безопасности. Далее в данной сессии клиент и сервер должны
использовать урезанный НМАС, соответствующим образом вычисляя его.
Это означает, что CipherSpec.hash_size есть 10 байтов, и только
первые 10 байтов выхода НМАС передаются и проверяются. Заметим, что
данное расширение не влияет на вычисление на часть получения
ключа.
Размер урезанного МАС применяется к сессиям, в том числе возобновляемым.
Клиенты, имеющие ограничения, могут захотеть использовать протокол
Для указания возможности получения информации о status_request в Client Hello. Поле extension_data должно содержать CertificateStatusRequest, где:
struct {
CertificateStatusType status_type;
select (status_type) {
case ocsp: OCSPStatusRequest;
} request;
} CertificateStatusRequest;
enum {ocsp(1), (255)} CertificateStatusType;
struct {
ResponderID responder_id_list<0..2^16-1>;
Extensions request_extensions;
} OCSPStatusRequest;
opaque ResponderID<1..2^16-1>;
opaque Extensions<0..2^16-1>;
В OCSPStatusRequest ResponderIDs указывает список отвечающих responder_id_list нулевой
длины имеет специальное значение, указывающее, что отвечающие неявно
известны серверу, например предварительно согласованы. Extensions
являются
Оба типа ResponderID и Extensions определены в Extensions взято
из PKI. Значение request_extension нулевой длины означает, что
никаких расширений нет.
Сервер, получивший Client Hello с расширением status_request, может
вернуть соответствующий статус сертификата вместе со своим
сертификатом. При запросе request_extensions в запрос
Сервер возвращает ответ сертификата вместе со своим сертификатом,
посылая сообщение CertificateStatus сразу после сообщения Certificate
(и перед любым из сообщений ServerKeyExchange или CertificateRequest ). Если сервер вернул сообщение CertificateStatus,
он должен включить расширение типа status_request с пустым extension_data в расширенный Server Hello.
struct {
CertificateStatusType status_type;
select (status_type) {
case ocsp: OCSPResponse;
} response;
} CertificateStatus;
opaque OCSPResponse<1..2^24-1>;
ocsp_response содержит полный
Сообщение CertificateStatus передается с использованием сообщения
Рукопожатия типа certificate_status.
Заметим, что сервер может решить не посылать сообщение CertificateStatus, даже если он получил расширение status_request в
сообщении Client Hello.
Наконец заметим, что сервер не должен посылать сообщение CertificateStatus, если он не получил расширение status_request в
сообщении Client Hello.
Клиенты, запрашивающие CertificateStatus, должны проверять
В расширении протокола определены новые Alerts ошибок, использующиеся
вместе с данными расширениями
Во избежание нарушения работы существующих клиентов и серверов эти
Alerts не должны посылаться до тех пор, пока отправляющий их участник
не получит расширенное сообщение Hello от другого участника.
unsupported_extension – данный Alert посылается клиентом, который
получил расширенный Server Hello, содержащий расширение, которое он
не указывал в соответствующем Client Hello. Данное сообщение всегда
фатально.unrecognized_name – данный Alert посылается сервером, который
получил запрос с расширением server_name, но не распознал имя
сервера. Данное сообщение может быть фатальным.certificate_unobtainable – данный Alert посылается сервером,
который не может получить цепочку сертификатов из URL,
предоставленного клиентом. Данное сообщение может быть фатальным –
например, если серверу требуется аутентификация клиента для
продолжения Рукопожатия и сервер не может восстановить цепочку
сертификатов, он может послать фатальный Alert.bad_certificate_status_response – данный Alert посылается клиентом,
который получил ответ с недействительным bad_certificate_hash_value – данный Alert посылается сервером, если
хэш сертификата не соответствует предоставленному клиентом certificate_hash. Данное сообщение всегда фатально.Традиционно IANA руководит определением новых значений, RFCs обычно определяют процедуру, используемую IANA. Однако могут возникнуть трудности при взаимодействии в данном протоколе между новыми и существующими возможностями, что может привести к снижению общей безопасности.
Следовательно, запросы на определение новых расширений должны утверждаться стандартными действиями IETF.
При определении новых расширений следует помнить:
Часто бывает достаточно того, что Finished. Всегда следует помнить, что
пока Рукопожатие не аутентифицировано,
Проанализируем безопасность для каждого расширения, определенного в данном документе.
Если единственный сервер обслуживает несколько доменов, то очевидно, что владельцу каждого домена необходимо гарантировать, что все соответствует его требованиям безопасности.
Обязательно нужно гарантировать, что не происходит переполнения
буфера, независимо от значения поля длины в server_name.
Хотя в настоящий момент неконкретизировано представление для
интернационализации hostnames в расширении server_name, это не
связано с проблемами безопасности, сопряженными с использованием
интернационализированных hostnames – в частности, "выдуманными"
именами, которые неотличимы от другого имени при просмотре или
печати. Рекомендуется, чтобы сертификаты сервера не выпускались для
интернационализированных hostnames, если существует риск выдуманных
имен.
Максимальная длина фрагмента должна учитываться уже сообщениями Рукопожатия. Однако это не приводит к каким-то дополнительным проблемам безопасности, так как существует требование, чтобы реализации имели возможность фрагментировать сообщения Рукопожатия.
Реальная максимальная длина фрагмента зависит от набора алгоритмов шифрования и метода сжатия. Это должно учитываться и при определении размера буферов и проверки буфера на предмет переполнения.
Для данного расширения существует две проблемы.
Первая проблема связана с тем, что необходимо определить, должен ли клиент включать хэши сертификатов при посылке URLs сертификатов.
Если в аутентификации клиента используется *without* в расширении client_certificate_url, цепочка сертификатов клиента охватывается
хэшем сообщения Finished. Цель включения хэшей и проверки их при
получении цепочки сертификатов состоит в том, чтобы гарантировать,
что определенное свойство, указанное в данном расширении,
используется, например, что вся информация в цепочке сертификатов,
полученная сервером, соответствует той, что посылал клиент.
С другой стороны, у клиента могут быть ежедневно выпускаемые сертификаты, которые хранятся по фиксированному URL, и нет необходимости предоставлять их клиенту. Клиенты, которые решили опускать хэши сертификатов, должны учитывать возможность атак, при которых злоумышленник посылает действительный сертификат ключа клиента, отличный от сертификата, который предоставляет клиент.
Вторая проблема состоит в том, что для client_certificate_url сервер
начинает действовать от имени клиента. Таким образом сервер
становится источником проблем, связанных с безопасностью, как и
клиент для схемы с URL. Кроме того, следует помнить, что клиент может
попытаться заставить сервер соединяться с некоторым, возможно
несуществующим, URL.
В общем случае это означает, что атакующий может использовать сервер для непрямых атак на другой хост, который уязвим в отношении определенного потока. Также возникает возможность DoS-атак, при которых атакующий создает много соединений с сервером, каждое из которых является результатом попытки сервера соединиться с целью, определенной атакующим.
Заметим, что сервер может быть расположен за firewall или иметь возможность доступа к хостам, которые не имеют прямого выхода в Internet. Это может обострить потенциальные проблемы безопасности и проблемы, связанные с отказом сервиса, при существовании внутренних хостов, от которых требуется получать подтверждение и которые могут быть недоступны.
Таким образом, рекомендуется, чтобы необходимость расширения client_certificate_url указывалась администратором сервера, а не по
умолчанию.
URLs, которые указывают порты, отличные от заданных по умолчанию, могут иметь различные проблемы, так же, как и очень длинные URLs (что может быть связано с переполнением буфера).
Кроме того, следует заметить, что в Internet часто используются НТТР кэширующие proxy, и некоторые из них не проверяют самую последнюю версию. Если запрос, использующий НТТР (или другой кэширующий протокол), сконфигурирован неправильно или прерван proxy, proxy сервер может возвратить ответ, не соответствующий текущему запросу.
В некоторых случаях ключи корневых СА, которые предоставил клиент, могут рассматриваться как конфиденциальная информация. Следовательно, ключ корневого СА в расширении должен применяться с осторожностью.
Использование в качестве альтернативы SHA-1 хэшей сертификатов гарантирует недвусмысленность каждого сертификата.
Очевидно, что урезанные МАСs в целом являются более слабыми, чем полные МАСs. Тем не менее, на сегодня неизвестны особенно уязвимые места для НМАС как с MD5, так и с SHA-1, урезанных до 80 бит.
Заметим, что длина выхода НМАС не должна быть такой же, как длина
ключа симметричного шифрования, так как подделка значений МАС не
может быть выполнена off-line: в
Если клиент запросил ответы
Использование расширения запроса
Основная функция протокола
Протокол
Перечислим задачи протокола
Протокол состоит из двух уровней. Нижним уровнем, расположенным выше
некоторого надежного протокола (а именно, протокола ТСР) является
Одно из преимуществ
Определены четыре криптографические операции: цифровая подпись,
поточное шифрование,
В операции цифровой подписи входом в алгоритм подписи является результат применения односторонней хэш-функции к подписываемым данным. Длина входа определяется алгоритмом подписи.
При использовании алгоритма RSA подписывается 36-байтная структура, состоящая из конкатенации 20 байтов хэш-кода SHA-1 и 16 байтов хэш-кода MD5.
При использовании DSS 20 байтов хэш-кода SHA-1 подаются на вход алгоритму DSA без дополнительного хэширования. При этом создается два значения: r и s.
При поточном шифровании для незашифрованного текста выполняется операция XOR с тем же количеством значений, созданных криптографически безопасным (с ключом) генератором псевдослучайных чисел.
При блочном шифровании каждый блок незашифрованного текста шифруется, в результате чего создается блок зашифрованного текста. Все алгоритмы блочного шифрования выполняются в режиме СВС, и длина всех шифруемых элементов должна быть кратна длине блока алгоритма шифрования.
При шифровании с открытым ключом используется алгоритм открытого ключа, при этом данные могут быть дешифрованы только с помощью соответствующего закрытого ключа.
Для получения МАС используется НМАС, поэтому если не знать секрета МАС, подделать МАС невозможно.
НМАС может использоваться с различными хэш-алгоритмами. HMAC_MD5 (secret, data) и HMAC_SHA (secret, data). Могут быть
определены дополнительные хэш-алгоритмы, но в настоящей версии
используются только MD5 и SHA-1.
В алгоритме определена функция, которая расширяет секрет до нужной
длины для создания всех необходимых ключей. Такая псевдослучайная
функция, , получает в качестве входа секрет, "зерно" (seed –
значение, которое с одной стороны является случайным, а с другой
стороны не является секретным, т.е. может стать известно оппоненту) и
идентификационную метку, и создает выход требуемой длины.
Для того чтобы сделать как можно более безопасной, используются
два безопасных хэш-алгоритма.
Во-первых, определяется 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) + ...
Где
+ – обозначает конкатенацию.
А () – определяется следующим образом:
А (0) = seed
A (i) = HMAC_hash (secret, A (i – 1))
P_hash может иметь столько итераций, сколько необходимо для создания
требуемого количества данных. Например, если P_SHA-1 используется для
создания 64 байтов данных, то количество итераций должно быть равно
4, при этом будет создано 80 байтов данных; последние 16 байтов
заключительной итерации будут отброшены, чтобы оставить только 64
байта выходных данных.
создается путем расщепления секрета на две половины, одна
половина используется для создания данных с помощью P_MD5, а другая –
для создания данных с помощью P_SHA-1, после чего оба выхода этих
функций складываются по модулю 2.
определяется как результат сложения по модулю 2 этих двух
псевдослучайных значений.
Label является фиксированной текстовой строкой.
Заметим, что поскольку MD5 создает 16-байтные значения, а SHA-1
создает 20-байтные значения, то границы внутренних итераций не будут
совпадать. Например, для создания 80-байтного значения необходимо
выполнить 5 итераций P_MD5 и 4 итерации P_SHA-1.
Выше
Параметры безопасности для состояний чтения и записи устанавливаются с помощью следующих значений (см. таб. 21.1).
Уровень записи использует параметры безопасности для создания следующих шести элементов:
client write MAC secret
server write MAC secret
client write key
server write key
client write IV – только для блочных алгоритмов
server write IV – только для блочных алгоритмов
Параметры client write используются сервером, когда он получает
сообщения и клиентом, когда тот посылает их. Параметры server write
применяются сервером, когда он посылает сообщения и клиентом, когда
он получает их. После того как параметры безопасности установлены и
ключи созданы, ожидаемые
| Конец соединения | Каждый участник является либо "клиентом", либо "сервером" |
| Алгоритм симметричного шифрования | Алгоритм, используемый для симметричного шифрования. Данное описание включает размер ключа алгоритма, тип алгоритма (блочный или поточный), размер блока алгоритма и информацию о том, является ли он "экспортируемым" |
| МАС алгоритм | Алгоритм, используемый для проверки целостности сообщения. Это описание включает размер хэша, который возвращается МАС-алгоритмом |
| Алгоритм сжатия | Алгоритм, используемый для сжатия данных. Данное описание включает всю информацию, необходимую алгоритму сжатия |
| Мастер-секрет | 48-байтный секрет, разделяемый обоими участниками соединения |
| Случайное число клиента | 32-байтное значение, создаваемое клиентом |
| Случайное число сервера | 32-байтное значение, создаваемое сервером |
| Алгоритм МАС | МАС-секрет |
| Последовательный номер | Каждое |
Уровень Записи получает данные от более высоких уровней в блоках произвольной длины.
Уровень Записи фрагментирует блоки в записи TLSPlaintext, поддерживая
цепочки данных длиной не более 214 байт. ContentType
могут быть размещены в одной записи TLSPlaintext или единственное
сообщение может быть фрагментировано в несколько записей.
Все записи сжимаются с использованием алгоритма сжатия, определенного
в текущем состоянии сессии. Первоначально он определяется как CompressionMethod.null. Алгоритм сжатия преобразует TLSPlaintext -структуру в TLSCompressed -структуру.
Если функция декомпрессии определяет, что длина декомпрессированного фрагмента превышает 214 байтов, возникает фатальная ошибка декомпрессии.
struct {
ContentType type;
/* same as TLSPlaintext.type */
ProtocolVersion version;
/* same as TLSPlaintext.version */
uint16 length;
opaque fragment[TLSCompressed.length];
} TLSCompressed;
length – длина (в байтах) следующего TLSCompressed.fragment.
fragment – сжатая форма TLSPlaintext.fragment.
Функции шифрования и МАС преобразуют TLSCompressed -структуру в TLSCiphertext. Функции дешифрования выполняют обратные
преобразования. Применение МАС включает последовательный номер,
поэтому потерю или повтор сообщений всегда можно обнаружить.
struct {
ContentType type;
ProtocolVersion version;
uint16 length;
select (CipherSpec.cipher_type) {
case stream: GenericStreamCipher;
case block: GenericBlockCipher;
} fragment;
} TLSCiphertext;
МАС выполняется перед шифрованием. Потоковый шифратор шифрует весь
блок, включая МАС. Если CipherSuite есть TLS_NULL_WITH_NULL_NULL, то
шифрование состоит из тождественной операции, т.е. данные не
шифруются и МАС не используется. TLSCiphertext.length есть сумма TLSCompressed.length и CipherSpec.hash_size.
Для блочных алгоритмов функции шифрования и МАС преобразуют TLSCompressed.fragment -структуру из блоков TLSCiphertext.fragment -структур.
Длина зашифрованных данных ( TLSCiphertext.length ) есть сумма TLSCompressed.length, CipherSpec.hash_size и padding_length.
Рассмотрим пример: если длина содержимого ( TLSCompressed.length )
равна 62 байтам и длина МАС равна 20 байтам, то длина перед
добавлением равна 82 байтам. Таким образом, если длина блока равна 8
байтам, то длина добавления должна быть равна 6, чтобы общая длина
была кратна 8. Длина добавления может быть 6, 14, 22 и т.д. до 254.
Если добавление было сделано минимально необходимым, то добавляется 6
байтов, каждый из которых содержит значение 6.
Для блочных алгоритмов для первой записи при определении параметров безопасности создается инициализационный вектор (IV). IV для следующих записей является последним зашифрованным блоком предыдущей записи.
Из мастер-секрета с использованием хэш-функций создается
последовательность байтов, которая представляет собой МАС-секреты,
ключи и инициализационные вектора: client write MAC secret, server
write MAC secret, client write key, server write key, client write IV
и server write 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 сбрасывается.
Для экспортируемых алгоритмов шифрования (для которых CipherSpec.is_exportable есть true ) требуется дополнительное
вычисление ключей записи:
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_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]
Заметим, что в данном случае используется без секрета: это
означает, что секрет имеет нулевую длину и на результат вычисления не влияет.
В результате выполнения
Протокол состоит из единственного сообщения, которое зашифровано и
сжато, как определено в текущем (не ожидаемом)
| Произвольная последовательность байтов, выбираемая сервером для идентификации активного или возобновляемого состояния сессии | |
| Сертификат участника | Х.509 v3 сертификат участника. Этот элемент может быть нулевым |
| Метод сжатия | Алгоритм, используемый для сжатия данных перед шифрованием |
| Набор алгоритмов | Алгоритм симметричного шифрования данных (такой как
null, DES и т.д.), МАС-алгоритм (такой как MD5 или SHA)
и различные криптографические атрибуты, такие как hash_size |
| Мастер-секрет | 48-байтный секрет, разделямый клиентом и сервером |
| Возобновляемо | Флаг, определяющий, может ли данная сессия использоваться для создания нового соединения |
Сообщение об изменении шифрования может посылаться как клиентом, так
и сервером для уведомления получающей стороны о том, что следующие
записи будут защищены алгоритмами и ключами, о которых стороны только
что договорились. При поступлении данного сообщения получатель должен
информировать
Одним из протоколов, лежащих выше
Клиент и сервер должны оба узнать о том, что соединение завершается. Каждый участник может инициировать обмен сообщениями закрытия.
Сообщение close_notify уведомляет получателя о том, что отправитель
не будет больше посылать никаких сообщений по данному соединению.
Сессия становится невозобновляемой, если хотя бы одно соединение
завершено без соответствующего предупреждающего сообщения close_notify.
Каждый участник может инициировать закрытие посылкой сообщения Alert
типа close_notify. Любые данные, отправленные после Alert-закрытия,
игнорируются.
Требуется, чтобы каждый участник посылал close_notify Alert перед
закрытием стороны записи соединения. Это означает, что при получении
ответа другого участника с Alert типа close_notify соединение
немедленно закрывается и все ожидаемые состояния сбрасываются.
Инициатору закрытия не обязательно ждать ответного close_notify Alert
перед закрытием стороны чтения соединения.
Если прикладной протокол, использующий close_notify перед тем как сообщать прикладному
уровню, что соединение close_notify. В стандарте
Замечание: предполагается, что при закрытии соединения ожидающие доставки данные надежно доставляются перед разрушением транспорта.
Ошибки обрабатываются в
Для всех ошибок, у которых уровень Alert явно не задан, посылающая сторона сама может определять, является ошибка фатальной или нет. Если получен Alert с уровнем предупреждения, получающая сторона может решать, интерпретировать ли сообщение как фатальное.
Unexpected_message |
Получено неожидаемое сообщение. Этот Alert всегда фатальный и никогда не должен возникать во взаимодействии корректных реализаций |
Bad_record_mac |
Данный Alert возвращается, если полученная запись имеет некорректный МАС. Данное сообщение всегда фатально |
Decryption_failed |
TLSCiphertext дешифрован недопустимым
способом: некратная длина блока или недопустимые добавленные значения. Данное сообщение всегда фатально |
Record_overflow |
Полученная TLSCiphertext запись имеет длину больше 214 + 2048 байт, или дешифрованная
TLSCompressed запись имеет длину больше 214 + 1024 байт. Данное сообщение всегда фатально |
Decompression_failure |
Функция декомпрессии получила неправильные входные данные. Данное сообщение всегда фатально |
Handshake_failure |
Получение сообщения handshake_failure
Alert говорит о том, что отправитель не смог договориться о приемлемом наборе параметров
безопасности. Данное сообщение всегда фатально |
Bad_certificate |
Сертификат испорчен, например содержит некорректную подпись |
Unsupported_certificate |
Сертификат неподдерживаемого типа |
Certificate_revoked |
Сертификат отменен тем, кто его подписал |
Certificate_expired |
Срок действия сертификата истек и в настоящее время он недействителен |
Certificate_unknown |
Другой результат (неопределенный), полученный в результате обработки сертификата, сертификат не принимается |
Illegal_parameter |
Некоторое поле находится вне диапазона или не согласуется с другими полями. Данное сообщение всегда фатально |
Unknown_ca |
Получена цепочка законных сертификатов или некоторая часть цепочки, но сертификат не принимается, потому что сертификат СА не соответствует известному СА, с которым установлены доверительные отношения. Данное сообщение всегда фатально |
Access_denied |
Получен законный сертификат, но при применении контроля доступа отправитель решил не продолжать переговоры. Данное сообщение всегда фатально |
Decode_error |
Сообщение не может быть декодировано, потому что некоторое поле находится вне специфицированного диапазона или некорректна длина сообщения. Данное сообщение всегда фатально |
Decrypt_error |
Не выполнена криптографическая операция Рукопожатия, которая включает проверку подписи, дешифрование обмена ключа и проверку правильности завершающего сообщения |
Export_restriction |
Переговоры не выполнены из-за экспортных
ограничений; например, попытка передать
1024-битный ключ RSA для метода Рукопожатия RSA_EXPORT. Данное сообщение всегда фатально |
Protocol_version |
Версия протокола, с которой клиент пытается вести переговоры, распознана, но не поддерживается. Например, старая версия протокола не должна использоваться по причинам безопасности. Данное сообщение всегда фатально |
Insufficient_security |
Возвращается вместо handshake_failure,
когда переговоры прекращаются из-за того, что
сервер требует более безопасных алгоритмов, чем
предложены клиентом. Данное сообщение всегда
фатально |
Internal_error |
Внутренняя ошибка, не относящаяся к участникам, но делающая невозможным дальнейшее ведение переговоров (например, невозможность распределения памяти). Данное сообщение всегда фатально |
User_canceled |
Данное Рукопожатие прервано по некоторой причине, не относящейся к падению протокола. Если
пользователь прервал операцию после завершения Рукопожатия, то для закрытия соединения
больше подходит сообщение close_notify.
Данное сообщение обычно является предупреждающим |
No_renegotiation |
Посылается клиентом в ответ на запрос Hello
или сервером в ответ на Hello клиента после начала Рукопожатия. Это приводит к
невозможности вести новые переговоры; в этой точке тот, кто
осуществил первоначальный запрос, может решить продолжать ли использовать данное
соединение. Одним из случаев, который может соответствовать данной ситуации, может быть
порождение сервером нового процесса для удовлетворения запроса; процесс должен при старте получить
параметры безопасности (длину ключа, аутентификацию и т.д.), и возможности внести
изменения в параметры после этой точки быть не должно. Данное сообщение всегда является предупреждающим |
Криптографические параметры состояния сессии создаются
Hello для согласования алгоритмов, обмен
случайными значениями и проверка возобновляемости сессии.Заметим, что протоколы более высокого уровня всегда должны считать,
что
Данные цели достигаются Client
Hello, на которое сервер должен ответить сообщением Server Hello или
фатальной ошибкой и прерыванием соединения. Client Hello и Server
Hello используются для определения максимального уровня безопасности
между клиентом и сервером. Client Hello и Server Hello устанавливают
следующие атрибуты: Protocol Version, Session ID, Cipher Suite и Compression Method. Дополнительно создаются и передаются два
случайных значения: ClientHello.random и ServerHello.random.
Аутентификация и обмен общим секретом осуществляются в четырех сообщениях: сертификат сервера, обмен ключа сервера, сертификат клиента и обмен ключа клиента. Общий секрет должен быть достаточно большим; текущие методы распределения ключа обмениваются секретами, длина которых находится в диапазоне от 48 до 126 байт.
После сообщений Hello сервер посылает сертификат для аутентификации.
Дополнительно может быть послано сообщение обмена ключа сервера, если
сервер не имеет сертификата или его сертификат служит только для
подписи. Если сервер аутентифицирован, он может запросить сертификат
клиента, если того требует установленная политика безопасности.
Теперь сервер посылает сообщение Server Hello Done, указывающее на
то, что фаза Hello -сообщений Рукопожатия завершена. Затем сервер ждет
ответа клиента. Если сервер послал сообщение запроса сертификата,
клиент должен послать сообщение Certificate. После этого посылается
сообщение обмена ключа клиента, содержимое этого сообщения зависит от
выбранного алгоритма открытого ключа в сообщениях Client Hello и Server Hello. Если клиент имеет сертификат для подписывания, то
посылается сообщение цифровой подписи для явной проверки всех
сообщений Рукопожатия.
В данной точке клиентом посылается сообщение об изменении состояния, и клиент копирует ожидаемое состояние в текущее состояние. После этого клиент посылает заключительное сообщение с использованием новых алгоритмом, ключей и секретов. В ответ сервер посылает свое сообщение об изменении состояния, преобразует ожидаемое состояние в текущее состояние и посылает заключительное сообщение с использованием новых алгоритмов и ключей. После этого Рукопожатие считается выполненным, и клиент и сервер могут начинать обмен данными прикладного уровня.
Замечание: для того чтобы избежать остановок, ChangeCipherSpec
реализован как независимый тип протокола и частью
Когда клиент и сервер решают возобновить предыдущую сессию или дублировать существующую (вместо того чтобы вести новые переговоры о параметрах безопасности), поток сообщений передается следующим образом.
Клиент посылает ClientHello, используя Session ID возобновляемой
сессии. Сервер ищет соответствующий ServerHello с тем
же самым значением Session ID. В этой точке и клиент, и сервер должны
послать сообщения об изменении состояния, после чего сразу послать
завершающие сообщения. После этого клиент и сервер начинают обмен
данными прикладного уровня. Если соответствующий Session ID не
найден, сервер создает новый ID сессии, и клиент и сервер выполняют
полное Рукопожатие.
Поток сообщений при сокращенном Рукопожатии
Рассмотрим в деталях каждое сообщение
Последовательность сообщений при полном Рукопожатии
| Клиент | Сервер | |
|---|---|---|
| ClientHello | $$\Rightarrow$$ | |
| ServerHello | ||
| Certificate * | ||
| ServerKeyExchange * | ||
| CertificateRequest * | ||
| $$\Leftarrow$$ | ServerHelloDone | |
| Certificate * | ||
| ClientKeyExchange | ||
| CertificateVerify * | ||
| [ ChangeCipherSpec ] | ||
| Finished | $$\Rightarrow$$ | |
| [ChangeCipherSpec ] | ||
| $$\Leftarrow$$ | Finished | |
| Прикладные данные | $$\Leftrightarrow$$ | Прикладные данные |
TLSPlaintext, которые обрабатываются и передаются, как определено
текущим активным состоянием сессии.
Сообщения Cеrtificate используется дважды при Рукопожатии
(от сервера к клиенту, затем от клиента к серверу), но описано оно
только один раз. Единственным сообщением, которое не связано данными
правилами упорядоченности, является сообщение Hello Request. Оно
может быть послано в любое время, но должно игнорироваться клиентом,
если поступает в середине Рукопожатия.
| Клиент | Сервер | |
|---|---|---|
| ClientHello | $$\Rightarrow$$ | |
| ServerHello | ||
| [ ChangeCipherSpec ] | ||
| $$\Leftarrow$$ | Finished | |
| [ ChangeCipherSpec ] | ||
| Finished | $$\Rightarrow$$ | |
| Прикладные данные | $$\Leftrightarrow$$ | Прикладные данные |
Сообщения фазы Hello используются для обмена возможностями
установления безопасного соединения между клиентом и сервером. Когда
начинается новая сессия, алгоритмы шифрования, хэширования и сжатия null.
Параметры текущего
Hello Request
Сообщение Hello Request может быть послано сервером в любое время.
Hello Request является просто уведомлением о том, что клиент должен
начать процесс переговоров заново посылкой сообщения Hello. Данное
сообщение будет игнорироваться клиентом, если он находится в
состоянии переговоров. Данное сообщение может игнорироваться
клиентом, если он не хочет вести новые переговоры, при этом клиент
может ответить no_renegotiation Alert. Если сервер посылает Hello
Request, но не получает в ответ Client Hello, он может закрыть
соединение с фатальным Alert.
После посылки Hello Request сервер не должен повторять запрос до тех
пор, пока последующие переговоры Рукопожатия не будут завершены.
Замечание: данное сообщение никогда не должно включаться в хэши сообщений, которые вычисляются при Рукопожатии и используются в завершающих сообщениях и сообщении проверки сертификата.
Client Hello
Данное сообщение посылается, когда клиент в первый раз соединяется с
сервером. В качестве первого сообщения требуется посылать Client
Hello. Клиент также может послать Client Hello в ответ на Hello
Request или по собственной инициативе, чтобы начать новые переговоры
о параметрах безопасности для существующего соединения.
Сообщение Client Hello содержит случайные числа, которые используются
при создании мастер-секрета.
Сообщение Client Hello может включать SessionID может
использоваться после того, как Finished -сообщениями и сохраняется до тех пор, пока не будет
удален или не произойдет фатальная ошибка в соединении, связанном с
данной сессией.
Следует заметить, что, так как SessionID передается без шифрования и
МАС- защиты, серверы не должны помещать конфиденциальную информацию в
SessionID, защищено Finished -сообщениями,
которыми участники обмениваются в конце Рукопожатия.
Список CipherSuite, передаваемый от клиента серверу в сообщении Client Hello, содержит комбинации криптографических алгоритмов,
поддерживаемых клиентом, упорядоченные согласно предпочтениям
клиента. Каждый CipherSuite определяет алгоритм обмена ключа,
алгоритм основного шифрования (включая длину секретного ключа) и
алгоритм МАС. Сервер будет выбирать набор шифрования или, если
приемлемый выбор невозможен, возвратит Alert падения Рукопожатия и
закроет соединение.
Сlient Hello включает также список алгоритмов сжатия, поддерживаемых
клиентом, упорядоченный согласно предпочтениям клиента.
После посылки сообщения Client Hello клиент ждет сообщения Server
Hello. Любое другое сообщение, возвращаемое сервером, за исключением Hello Request, трактуется как фатальная ошибка.
Замечание о совместимости: в интересах совместимости с последующими
реализациями допускается в сообщение Client Hello включать внешние
данные после методов сжатия. Эти данные должны быть включены в
вычисление хэшей Рукопожатия, но в других отношениях они должны
игнорироваться. Это возможно только для сообщения Рукопожатия; для
всех других сообщений количество данных в сообщении должно точно
соответствовать описанию сообщения.
Server Hello
Сервер посылает данное сообщение в ответ на сообщение Client Hello,
для того чтобы выбрать конкретный набор алгоритмов. Если он не может
сделать такой выбор, он отвечает handshake failure Alert.
Сервер должен посылать сертификат, если метод обмена ключей не
является анонимным. Данное сообщение всегда следует сразу за
сообщением Server Hello.
Тип сертификата должен соответствовать выбранному алгоритму обмена ключа. Обычно это сертификат X.509v3. Он должен содержать ключ, который соответствует методу обмена ключа. Если не указано иное, то алгоритм подписывания должен быть тем же самым, что и алгоритм для обмена ключа. Если не указано иное, то открытый ключ может иметь произвольную длину.
Все профили сертификатов, ключи и криптографические форматы
определены рабочей группой IETF PKIX. Если допускается различное
использование ключа, то должен быть установлен бит digitalSignature
для ключа, который может применяться для подписывания, и должен быть
установлен бит keyEncipherment для ключа, которым можно шифровать.
Бит keyAgreement должен быть установлен для сертификатов
Диффи-Хеллмана.
Могут быть определены новые методы обмена ключа. Они должны иметь соответствующий формат сертификата и информации о ключе.
Предполагается, что сертификатами являются
Точно такое же сообщение используется для ответа клиента при запросе его сертификата. Клиент может не посылать сертификата, если он его не имеет.
Данное сообщение посылается непосредственно после сообщения Server
Certificate (или сообщения Server Hello, если переговоры анонимные).
Сообщение сервера обмена ключа посылается сервером только тогда,
когда сообщение Server Certificate (если оно послано) не содержит
достаточно данных, чтобы клиент мог осуществить обмен
премастер-секретом. Это верно для следующих методов обмена ключа:
Данное сообщение передает криптографическую информацию, которая позволяет клиенту передавать премастер-секрет: премастер-секрет шифруется либо открытым ключом RSA, либо открытым ключом Диффи-Хеллмана, с помощью которого клиент может завершить обмен ключа.
Таким образом, сообщение сервера обмена ключа будет послано тогда и только тогда, когда тип сертификата, связанный с алгоритмом обмена ключа, не предоставляет достаточно информации клиенту для обмена премастер-секретом.
Неанонимный сервер может дополнительно запросить сертификат клиента,
если это Server Key
Exchange, если оно послано; в противном случае – за сообщением Server
Certificate.
Следует помнить, что запрос идентификации клиента от анонимного
сервера является фатальным handshake_failure Alert.
Сообщение Server Hello Done посылается сервером для обозначения
окончания фазы Server Hello и связанных с ней сообщений. После
посылки данного сообщения сервер ждет ответа клиента.
Данное сообщение означает, что сервер завершил отправку сообщений, поддерживающих обмен ключа.
| Алгоритм обмена ключа | Тип ключа сертификата |
| RSA | Открытый ключ RSA; сертификат должен позволять задействовать ключ для шифрования |
| RSA_EXPORT | Учтены экспортные ограничения, т.е. открытый ключ RSA
длиной больше 512 бит может использоваться для подписывания, ключ 512 бит и короче может использоваться как для
подписи, так и для шифрования. В первом случае следующим
сообщением должно быть ServerKeyExchange, в котором
этим ключом будут подписаны открытые ключи Диффи-Хеллмана или другой открытый ключ RSA |
| DH_DSS | Открытый ключ DSS. Обмен ключа осуществляется по алгоритму Диффи-Хеллмана |
| DH_RSA | Открытый ключ RSA, который может использоваться для подписывания. Обмен ключа осуществляется по алгоритму Диффи-Хеллмана |
При получении сообщения Server Hello Done клиент должен убедиться,
что сервер предоставил законный сертификат и что Hello параметры
сервера приемлемы для клиента.
Это первое сообщение, которое клиент посылает после получения
сообщения Server Hello Done. Оно посылается только в том случае, если
сервер требует сертификат. Если подходящий сертификат недоступен,
клиент должен послать сообщение Certificate, не содержащее
сертификатов. Если сервер требует аутентификации клиента для
продолжения Рукопожатия, он может ответить фатальным handshake
failure Alert. Структура сертификатов клиента такая же, как и
сервера.
Если применяется метод обмена ключа, основанный на алгоритме
Диффи-Хеллмана ( DH_DSS или DH_RSA ) и требуется аутентификация
клиента, то группа и генератор Диффи-Хеллмана, содержащиеся в
сертификате клиента, должны соответствовать параметрам
Диффи-Хеллмана, определенным для сервера, если параметры клиента
используются для обмена ключа.
Данное сообщение посылается клиентом всегда. Оно следует сразу за
сообщением Client Certificate, если таковое посылается. В противном
случае это первое сообщение, посланное клиентом после получения
сообщения Server Hello Done.
В данном сообщении устанавливается премастер-секрет, который
передается либо с помощью RSA шифрования, либо с использованием
DH_RSA
или DH_DSS и сертификат клиента запрашивается, клиент может ответить
сертификатом, содержащим открытый ключ Диффи-Хеллмана, чьи параметры
(группа и генератор) должны соответствовать тем, которые
специфицированы в сертификате сервера. Никаких других данных это
сообщение не содержит.
Структура сообщения зависит от выбранного метода обмена ключа.
Если для согласования общего секрета и аутентификации используется
RSA, клиент создает 48-байтный премастер-секрет, шифрует его с
использованием открытого ключа из сертификата сервера или временного
ключа RSA, полученного в сообщении Server Key Exchange.
Данное сообщение используется для обеспечения явной проверки
целостности сообщений Рукопожатия с помощью сертификата клиента. Оно
посылается только в том случае, если сертификат клиента имеет
возможность подписывания (т.е. все сертификаты, за исключением тех,
которые используют Client Key Exchange.
Здесь handshake_messages означает все сообщения Рукопожатия,
посланные или полученные во время Рукопожатия, начиная с Client
Hello, но не включая данное сообщение. Включаются поля типа и длины
сообщений Рукопожатия. Хэш вычисляется от конкатенации всех структур,
посланных и полученных в сообщениях Рукопожатия.
Сообщение Finished всегда посылается непосредственно после сообщения Сhange Сipher Spec для проверки успешного выполнения обмена ключа и
процессов аутентификации. Причем сообщение Change Cipher Spec должно
быть получено после остальных сообщений Рукопожатия и перед Finished -сообщением.
Finished -сообщение является первым сообщением, защищенным с помощью
только что обговоренных алгоритмов, ключей и секретов. Получатели Finished -сообщения должны убедиться, что его содержимое корректно.
После того как одна сторона послала свое Finished -сообщение, получила
и проверила Finished сообщение другой стороны, она может начинать
посылать и получать прикладные данные по этому соединению.
Возникает фатальная ошибка, если сообщению Finished не предшествует
сообщение Change Cipher Spec.
Хэш, содержащийся в сообщениях Finished, посылается сервером в Sender.server и клиентом – в Sender.client. Значение handshake_message включает все сообщения Рукопожатия, начиная от Client Hello, но не включая данное Finished -сообщение. Это может
отличаться от handshake_message, которые включают сообщение проверки
сертификата (если он посылается). Также handshake_message в сообщении Finished, посылаемом сервером, отличается от сообщения Finished,
посылаемом клиентом, потому что сервер посылает его вторым, включая
предшествующее сообщение.
Напомним, что сообщения о смене шифратора, Alerts и другие типы
записей не являются сообщениями Рукопожатия и в вычисление хэша не
включаются. Сообщения Hello Request в хэшах Рукопожатия также
опущены.
Независимо от методов обмена ключа используется следующий алгоритм для преобразования премастер-секрета в мастер-секрет. Премастер секрет должен быть сброшен после того, как вычислен мастер-секрет.
master_secret = PRF(pre_master_secret,
"master secret",
ClientHello.random + ServerHello.random)
[0..47];
Длина мастер-секрета всегда равна 48 байтам. Длина премастер-секрета изменяется в зависимости от метода обмена ключа.
RSA
Когда для аутентификации сервера и обмена ключа используется RSA, клиентом создается 48-байтный премастер-секрет, зашифрованный открытым ключом сервера, и посылается серверу. Сервер использует свой закрытый ключ для дешифрования премастер-секрета. Затем оба участника преобразуют премастер-секрет в мастер-секрет, как описано выше.
Диффи-Хеллман
Выполняются обычные вычисления Диффи-Хеллмана. Полученный ключ используется в качестве премастер-секрета для преобразования в мастер-секрет, как описано выше.
Рассмотрим расширения, которые могут использоваться для добавления
функциональности в Hello клиента и сервера, так и конкретные расширения,
используемые этими механизмами.
Сейчас
Беспроводные окружения часто имеют ряд ограничений, обычно отсутствующих в других окружениях. Эти окружения могут иметь ограничения на ширину полосы пропускания, на вычислительные мощности, на память, на срок жизни батарейки.
Описываемые здесь расширения предназначены для расширения
функциональности, предоставляемой форматами сообщений протокола
Данные расширения предназначены для обеспечения следующих возможностей:
Для того чтобы поддерживать перечисленные выше расширения, вводятся
дополнительные механизмы для сообщений Hello клиента и сервера.
Описываемые расширения могут использоваться клиентами
Обратная совместимость достигается следующим образом.
Client Hello, описанного ниже. Client Hello, даже если они
не понимают расширения.Однако заметим, что хотя обратная совместимость поддерживается, некоторые клиенты из-за своих ограниченных возможностей могут не устанавливать соединения с серверами, которые не поддерживают расширения.
Рассмотрим дополнительные функциональности в следующем порядке.
Сначала опишем общие механизмы расширений для сообщений Рукопожатия Client Hello и Server Hello. Далее опишем конкретные расширения для
Рассмотрим общие механизмы расширений для сообщений Рукопожатия Client Hello и Server Hello.
Эти общие механизмы расширений необходимы для того, чтобы клиенты и серверы имели возможность вести переговоры об использовании конкретных расширений.
Сначала опишем формат расширенного сообщения Client Hello, затем
формат расширенного сообщения Server Hello и формат реально
используемого расширения.
Клиент может запросить расширенную функциональность от сервера,
посылая расширенный формат сообщения Client Hello вместо обычного
формата сообщения Client Hello. Расширенный формат сообщения Client
Hello следующий:
struct {
ProtocolVersion client_version;
Random random;
SessionID session_id;
CipherSuite cipher_suites<2..2^16-1>;
CompressionMethod
compression_methods<1..2^8-1>;
Extension
client_hello_extension_list<0..2^16-1>;
} ClientHello;
Здесь новое поле client_hello_extension_list содержит список
расширений.
Если клиент запросил дополнительную функциональность, используя
расширенный Client Hello, и данная функциональность не поддерживается
сервером, клиент может прервать Рукопожатие.
Заметим, что Client Hello. Таким образом, использование расширенного Client Hello
не должно приводить к разрыву соединения с существующими серверами
Сервер, который поддерживает механизм расширений, должен принимать
как исходный формат, так и расширенный формат Client Hello, и (как и
для всех остальных сообщений) проверять, соответствует ли количество
данных в сообщении одному из этих форматов; если это не так, он
должен послать фатальный Alert decode_error.
Расширенный формат сообщения Server Hello может быть послан вместо
сообщения Server Hello, когда клиент запросил дополнительную
функциональность с помощью расширенного сообщения Server Hello.
Расширенный формат сообщения Server Hello следующий:
struct {
ProtocolVersion server_version;
Random random;
SessionID session_id;
CipherSuite cipher_suite;
CompressionMethod compression_method;
Extension
server_hello_extension_list<0..2^16-1>;
} ServerHello;
Здесь новое поле server_hello_extension_list содержит список
расширений. Реальный формат расширения будет определен ниже.
Заметим, что расширенное сообщение Server Hello посылается только в
ответ на расширенное сообщение Client Hello. Это позволит избежать
ситуации, при которой расширенное сообщение Server Hello не даст
установить соединение с существующими клиентами
Формат расширения для Client Hello и Server Hello следующий:
struct {
ExtensionType extension_type;
opaque extension_data<0..2^16-1>;
} Extension;
Где:
extension_type определяет конкретный тип расширения;extension_data содержит информацию, относящуюся к конкретному типу расширения.
Определены следующие типы расширений:enum {
server_name(0), max_fragment_length(1),
client_certificate_url(2),
trusted_ca_keys(3), truncated_hmac(4),
status_request(5), (65535)
} ExtensionType;
Заметим, что для всех типов расширений (включая и те, которые будут
определены в дальнейшем) тип расширения не должен появляться в
расширенном Server Hello, пока не появится в соответствующем Client
Hello. Таким образом, клиенты должны прерывать Рукопожатия, если
получили расширенный тип в расширенном Server Hello, который не был
запрошен в соответствующем Client Hello.
Расширения, инициируемые сервером (server initiated), могут присутствовать в будущем в рамках данного протокола, при этом требуется, чтобы клиент первым посылал пустое расширение, указывая тем самым, что он готов принимать подобное расширение.
Если в расширенном Client Hello или расширенном Server Hello
присутствует несколько расширений различных типов, они могут
появляться в произвольном порядке. Не должно быть более одного
расширения каждого типа.
Наконец, заметим, что все расширения, определенные в настоящий
момент, относятся только к инициализации сессии. Однако клиент,
который послал запрос на возобновление сессии, не знает, будет ли
принят данный запрос, и, следовательно, должен послать расширенный Client Hello, если это необходимо для новой сессии. Если запрос на
возобновление отвергнут, будут вестись переговоры о новом множестве
расширений. Если, с другой стороны, старая сессия возобновляется, то
сервер должен игнорировать расширения, появившиеся в Client Hello, и
послать Server Hello, не содержащий расширений. В этом случае
используется расширение, о котором участники договорились при
инициализации исходной сессии, возобновлением которой является данная
сессия.
Поддерживается использование двух новых сообщений Рукопожатия: CertificateURL и CertificateStatus. Новая структура сообщения
рукопожатия:
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), certificate_url(21),
certificate_status(22), (255)
} HandshakeType;
struct {
HandshakeType msg_type;
/* handshake type */
uint24 length;
/* bytes in message */
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;
case certificate_url: CertificateURL;
case certificate_status: CertificateStatus;
} body;
} Handshake;
Рассмотрим используемые расширения
Заметим, что любые сообщения, соответствующие этим расширениям,
посылаются при Рукопожатии и должны включаться в вычисления хэша в
сообщение Finished.
Сначала рассмотрим расширение, позволяющее клиенту указать сервер, с
которым он соединяется. Затем опишем расширение для указания
максимальной длины фрагмента. Далее опишем расширение, которое
позволяет клиенту указать URLs сертификатов, и расширение,
позволяющее указать ключи корневых СА. Наконец, опишем расширение,
которое позволяет задействовать урезанный HMAC, и расширение,
поддерживающее интеграцию сообщения с информацией о статусе
сертификата в Рукопожатие
Исходный протокол не предоставляет механизма, который позволял бы клиенту указать имя сервера, с которым он хочет соединиться. Однако это может требоваться для обеспечения безопасного соединения с хостами, у которых имеется несколько виртуальных серверов на одном сетевом адресе.
Для того чтобы указать имя сервера, клиент может включить расширение
типа server_name в Client Hello. Поле extension_data должно содержать ServerNameList:
struct {
NameType name_type;
select (name_type) {
case host_name: HostName;
} name;
} ServerName;
enum {
host_name(0), (255)
} NameType;
opaque HostName<1..2^16-1>;
struct {
ServerName server_name_list<1..2^16-1>
} ServerNameList;
На сегодня в качестве имени сервера поддерживается только DNS
hostname. Это не означает какой-либо зависимости
HostName содержит полностью определенное DNS hostname сервера. Hostname является байтовой строкой, представленной с использованием
UTF-8.
Сервер, который получил сообщение Client Hello, содержащее расширение server_name, может использовать данную информацию для выбора
сертификата, возвращаемого клиенту, либо для каких-то других аспектов
безопасности. В данном случае сервер должен включить расширение типа
server_name в расширенное Server Hello. Поле extension_date данного
расширения должно быть пустым.
Если сервер понимает расширение Client Hello, но не смог распознать
имя сервера, он должен послать unrecognized_name Alert (который может
быть фатальным).
Если приложение провело переговоры об имени сервера с использованием
протокола приложения, а затем после модификации server_name, то расширение должно содержать то же самое
имя, о котором участники договорились в прикладном протоколе. Если server_name установлено при Рукопожатии
Прежняя версия
Для этого клиент может указать расширение типа max_fragment_length в Client Hello. Поле extension_data данного расширения должно
содержать:
enum{
2^9(1), 2^10(2), 2^11(3), 2^12(4), (255)
} MaxFragmentLength;
значение которого является требуемой максимальной длиной фрагмента. Допустимыми значениями для данного поля являются: 29, 210, 211 и 212.
Сервер, получивший расширенный Client Hello с расширением max_fragment_length, может принять эту длину, включая расширение типа max_fragment_length в Server Hello. Поле extension_data данного
расширения должно содержать MaxFragmentLength, которое является тем
же самым, что и запрошенная максимальная длина фрагмента.
Если запрошена недопустимая длина фрагмента, сервер должен прервать
Рукопожатие с Alert illegal_parameter. Аналогично, если клиент
получил ответ с максимальной длиной фрагмента, отличной от
запрошенной, он также должен прервать Рукопожатие с Alert illegal_parameter.
После того, как стороны успешно договорились о максимальной длине
фрагмента, отличной от 214, клиент и сервер должны немедленно начать
фрагментировать сообщения (включая сообщения Рукопожатия), чтобы
гарантировать, что не посылаются сегменты большей длины, чем та, о
которой договорились. Заметим, что
Новая длина применяется для продолжения сессии, включая возобновляющиеся сессии.
Для ведения переговоров о посылке серверу URLs сертификата клиенты
могут включать расширение типа client_certificate_url в Client Hello.
Поле extension_data данного расширения должно быть пустым.
Заметим, что необходимо вести переговоры об использовании URLs
сертификатов клиента, чтобы существующие серверы
Сервер, получивший расширенный Client Hello, содержащий расширение client_certificate_url, может указать, что имеет возможность
принимать URLs сертификата, указывая расширение типа client_certificate_url в Server Hello. Поле extension_data данного
расширения должно быть пустым.
После успешного завершения переговоров об использовании URLs
сертификата клиента клиент может посылать сообщение CertificateURL
вместо сообщения Certificate:
enum {
individual_certs(0), pkipath(1), (255)
} CertChainType;
enum {
false(0), true(1)
} Boolean;
struct {
CertChainType type;
URLAndOptionalHash
url_and_hash_list<1..2^16-1>;
} CertificateURL;
struct {
opaque url<1..2^16-1>;
Boolean hash_present;
select (hash_present) {
case false: struct {};
case true: SHA1Hash;
} hash;
} URLAndOptionalHash;
opaque SHA1Hash[20];
Здесь url_and_hash_list содержит последовательность URLs и хэши
(необязательно).
При использовании сертификатов Х.509 существует две возможности:
Certificate.type есть individual_certs, то каждый URL
ссылается на единственный сертификат Х.509v3 в Certificate.type есть PkiPath, то список содержит единственный
URL, ссылающийся на цепочку сертификатов в представлении PkiPath, описанный ниже.При использовании любого другого формата спецификация, описывающая применение этого формата, должна определять формат представления сертификатов или цепочки сертификатов и различные ограничения их последовательности.
Хэш, соответствующий каждому URL, либо не присутствует, либо является
SHA-1 хэшем сертификата или цепочки сертификатов (в случае
сертификатов Х.509 PkiPath ).
Заметим, что когда используется список URLs для сертификатов Х.509,
упорядоченность URLs является той же самой, что и в сообщении Certificate, в противоположность упорядоченности, в которой
сертификаты представлены в PkiPath. В любом случае самоподписанный
корневой сертификат в цепочке может быть опущен, в предположении, что
сервер уже проверил его действительность.
При получении CertificateURL сервер должен пытаться получить цепочку
сертификатов клиента из URLs и затем обработать ее обычным образом.
Может использоваться кэшированная копия содержимого любого URL из
цепочки, проверяя, что SHA-1 хэш присутствует и соответствует хэшу
кэшированной копии.
Серверы, которые поддерживают данное расширение, должны поддерживать http:URL схему для URLs сертификатов и могут поддерживать другие
схемы.
Если протокол, используемый для получения сертификатов или цепочки
сертификатов, возвращает MIME форматированный ответ (как делает
НТТР), то должен применяться следующий MIME Content-Type: при
возврате единственного сертификата Х.509v3 Content-Type есть application/pkix-cert, при возврате цепочки сертификатов Х.509v3
Content-Type есть application/pkix-pkipath.
Если для URL присутствует SHA-1 хэш, то сервер должен убедиться, что
SHA-1 хэш содержимого объекта, полученного из URL (после
декодирования произвольного MIME Content-Transfer-Encoding),
соответствует данному хэшу. Если полученный объект не имеет
корректного SHA-1 хэша, сервер должен прервать Рукопожатие с Alert bad_certificate_hash_value.
Заметим, что клиент может выбрать либо посылку Certificate, либо
посылку CertificateURL после успешных переговоров о посылке URLs
сертификатов. Опция посылки сертификата обеспечивает клиенту гибкость
при обработке нескольких сертификатов.
Если сервер столкнулся с непредвиденной задержкой при получении
сертификатов по указанному CertificateURL, он должен при истечении
таймаута создать Alert ошибки certificate_unobtainable.
Клиенты, которые имеют ограниченную память, обладают только небольшим количеством ключей корневого СА и им может потребоваться указать серверу, какими корневыми ключами они владеют, чтобы избежать падения Рукопожатия.
Для этого клиенты могут включить расширение типа trusted_ca_keys в Client Hello. Поле extension_data данного расширения должно содержать TrustedAuthorities, где:
struct {
TrustedAuthority
trusted_authorities_list<0..2^16-1>;
} TrustedAuthorities;
struct {
IdentifierType identifier_type;
select (identifier_type) {
case pre_agreed: struct {};
case key_sha1_hash: SHA1Hash;
case x509_name: DistinguishedName;
case cert_sha1_hash: SHA1Hash;
} identifier;
} TrustedAuthority;
enum {
pre_agreed(0), key_sha1_hash(1),
x509_name(2), cert_sha1_hash(3), (255)
} IdentifierType;
opaque DistinguishedName<1..2^16-1>;
Здесь TrustedAuthorities содержит список идентификаторов ключей
корневых СА, которыми владеет клиент. Каждый ключ корневого СА
идентифицируется одним из следующих способов:
pre_agreed – не предоставляется никакой идентификации ключа
корневого СА.key_sha1_hash – содержит SHA-1 хэш ключа корневого СА. Для ключей
DSA и ECDSA это хэш значения subjectPublicKey. Для ключей RSA хэш
есть строка байтов модуля без начальных нулевых байтов (аналогично
форматам хэша ключа в других окружениях).х509_name – содержит cert_sha1_hash – содержит SHA-1 хэш Certificate,
содержащего ключ корневого СА.Заметим, что клиенты могут включать в данное расширение несколько или все ключи корневого СА, которыми они владеют, либо ни одного из них.
Также возможна ситуация, при которой хэш ключа или DN по отдельности
не идентифицируют выпускающего сертификат – например, если конкретный
СА имеет несколько пар ключей – однако здесь мы предполагаем, что в
Если данная опция включена, это позволяет клиентам сообщать о наличии у них некоторого предопределенного множества ключей корневого СА.
Сервер, который получил Client Hello с расширением trusted_ca_keys,
может использовать информацию, содержащуюся в расширении, в качестве
руководства по выбору цепочки сертификатов, возвращаемой клиенту. В
данном случае сервер должен включить расширение типа trusted_ca_keys
в Server Hello. Поле extension_data данного расширения должно быть
пустым.
В настоящий момент набор шифрования использует в качестве МАС НМАС
либо с MD5, либо с SHA-1 для аутентификации соединений уровня записи.
Весь выход хэш-функции используется в качестве тега МАС. Однако может
быть желательно в некоторых
Для того чтобы вести переговоры об использовании 80-битного
урезанного МАС, клиенты могут включить расширение типа truncated_hmac
в расширенный Client Hello. Поле extension_data данного расширения
должно быть пустым.
При получении расширенного Hello, содержащего расширение truncated_hmac, сервер может согласиться использовать урезанный МАС
путем включения расширения типа truncated_hmac с пустым extension_data в расширенный Server Hello.
Заметим, что если добавлен новый набор алгоритмов шифрования, который не использует НМАС, и при переговорах выбран один из этих наборов, то данное расширение ни на что не влияет. Рекомендуется, чтобы все новые наборы алгоритмов шифрования, использующие другие МАСs, рассматривали размер МАС как составную часть определения набора шифрования, имея в виду как безопасность, так и ограничения ширины полосы пропускания.
Если переговоры об урезанном МАС успешно завершены, клиент и сервер
передают эту информацию на уровень записи в качестве параметров
безопасности. Далее в данной сессии клиент и сервер должны
использовать урезанный НМАС, соответствующим образом вычисляя его.
Это означает, что CipherSpec.hash_size есть 10 байтов, и только
первые 10 байтов выхода НМАС передаются и проверяются. Заметим, что
данное расширение не влияет на вычисление на часть получения
ключа.
Размер урезанного МАС применяется к сессиям, в том числе возобновляемым.
Клиенты, имеющие ограничения, могут захотеть использовать протокол
Для указания возможности получения информации о status_request в Client Hello. Поле extension_data должно содержать CertificateStatusRequest, где:
struct {
CertificateStatusType status_type;
select (status_type) {
case ocsp: OCSPStatusRequest;
} request;
} CertificateStatusRequest;
enum {ocsp(1), (255)} CertificateStatusType;
struct {
ResponderID responder_id_list<0..2^16-1>;
Extensions request_extensions;
} OCSPStatusRequest;
opaque ResponderID<1..2^16-1>;
opaque Extensions<0..2^16-1>;
В OCSPStatusRequest ResponderIDs указывает список отвечающих responder_id_list нулевой
длины имеет специальное значение, указывающее, что отвечающие неявно
известны серверу, например предварительно согласованы. Extensions
являются
Оба типа ResponderID и Extensions определены в Extensions взято
из PKI. Значение request_extension нулевой длины означает, что
никаких расширений нет.
Сервер, получивший Client Hello с расширением status_request, может
вернуть соответствующий статус сертификата вместе со своим
сертификатом. При запросе request_extensions в запрос
Сервер возвращает ответ сертификата вместе со своим сертификатом,
посылая сообщение CertificateStatus сразу после сообщения Certificate
(и перед любым из сообщений ServerKeyExchange или CertificateRequest ). Если сервер вернул сообщение CertificateStatus,
он должен включить расширение типа status_request с пустым extension_data в расширенный Server Hello.
struct {
CertificateStatusType status_type;
select (status_type) {
case ocsp: OCSPResponse;
} response;
} CertificateStatus;
opaque OCSPResponse<1..2^24-1>;
ocsp_response содержит полный
Сообщение CertificateStatus передается с использованием сообщения
Рукопожатия типа certificate_status.
Заметим, что сервер может решить не посылать сообщение CertificateStatus, даже если он получил расширение status_request в
сообщении Client Hello.
Наконец заметим, что сервер не должен посылать сообщение CertificateStatus, если он не получил расширение status_request в
сообщении Client Hello.
Клиенты, запрашивающие CertificateStatus, должны проверять
В расширении протокола определены новые Alerts ошибок, использующиеся
вместе с данными расширениями
Во избежание нарушения работы существующих клиентов и серверов эти
Alerts не должны посылаться до тех пор, пока отправляющий их участник
не получит расширенное сообщение Hello от другого участника.
unsupported_extension – данный Alert посылается клиентом, который
получил расширенный Server Hello, содержащий расширение, которое он
не указывал в соответствующем Client Hello. Данное сообщение всегда
фатально.unrecognized_name – данный Alert посылается сервером, который
получил запрос с расширением server_name, но не распознал имя
сервера. Данное сообщение может быть фатальным.certificate_unobtainable – данный Alert посылается сервером,
который не может получить цепочку сертификатов из URL,
предоставленного клиентом. Данное сообщение может быть фатальным –
например, если серверу требуется аутентификация клиента для
продолжения Рукопожатия и сервер не может восстановить цепочку
сертификатов, он может послать фатальный Alert.bad_certificate_status_response – данный Alert посылается клиентом,
который получил ответ с недействительным bad_certificate_hash_value – данный Alert посылается сервером, если
хэш сертификата не соответствует предоставленному клиентом certificate_hash. Данное сообщение всегда фатально.Традиционно IANA руководит определением новых значений, RFCs обычно определяют процедуру, используемую IANA. Однако могут возникнуть трудности при взаимодействии в данном протоколе между новыми и существующими возможностями, что может привести к снижению общей безопасности.
Следовательно, запросы на определение новых расширений должны утверждаться стандартными действиями IETF.
При определении новых расширений следует помнить:
Часто бывает достаточно того, что Finished. Всегда следует помнить, что
пока Рукопожатие не аутентифицировано,
Проанализируем безопасность для каждого расширения, определенного в данном документе.
Если единственный сервер обслуживает несколько доменов, то очевидно, что владельцу каждого домена необходимо гарантировать, что все соответствует его требованиям безопасности.
Обязательно нужно гарантировать, что не происходит переполнения
буфера, независимо от значения поля длины в server_name.
Хотя в настоящий момент неконкретизировано представление для
интернационализации hostnames в расширении server_name, это не
связано с проблемами безопасности, сопряженными с использованием
интернационализированных hostnames – в частности, "выдуманными"
именами, которые неотличимы от другого имени при просмотре или
печати. Рекомендуется, чтобы сертификаты сервера не выпускались для
интернационализированных hostnames, если существует риск выдуманных
имен.
Максимальная длина фрагмента должна учитываться уже сообщениями Рукопожатия. Однако это не приводит к каким-то дополнительным проблемам безопасности, так как существует требование, чтобы реализации имели возможность фрагментировать сообщения Рукопожатия.
Реальная максимальная длина фрагмента зависит от набора алгоритмов шифрования и метода сжатия. Это должно учитываться и при определении размера буферов и проверки буфера на предмет переполнения.
Для данного расширения существует две проблемы.
Первая проблема связана с тем, что необходимо определить, должен ли клиент включать хэши сертификатов при посылке URLs сертификатов.
Если в аутентификации клиента используется *without* в расширении client_certificate_url, цепочка сертификатов клиента охватывается
хэшем сообщения Finished. Цель включения хэшей и проверки их при
получении цепочки сертификатов состоит в том, чтобы гарантировать,
что определенное свойство, указанное в данном расширении,
используется, например, что вся информация в цепочке сертификатов,
полученная сервером, соответствует той, что посылал клиент.
С другой стороны, у клиента могут быть ежедневно выпускаемые сертификаты, которые хранятся по фиксированному URL, и нет необходимости предоставлять их клиенту. Клиенты, которые решили опускать хэши сертификатов, должны учитывать возможность атак, при которых злоумышленник посылает действительный сертификат ключа клиента, отличный от сертификата, который предоставляет клиент.
Вторая проблема состоит в том, что для client_certificate_url сервер
начинает действовать от имени клиента. Таким образом сервер
становится источником проблем, связанных с безопасностью, как и
клиент для схемы с URL. Кроме того, следует помнить, что клиент может
попытаться заставить сервер соединяться с некоторым, возможно
несуществующим, URL.
В общем случае это означает, что атакующий может использовать сервер для непрямых атак на другой хост, который уязвим в отношении определенного потока. Также возникает возможность DoS-атак, при которых атакующий создает много соединений с сервером, каждое из которых является результатом попытки сервера соединиться с целью, определенной атакующим.
Заметим, что сервер может быть расположен за firewall или иметь возможность доступа к хостам, которые не имеют прямого выхода в Internet. Это может обострить потенциальные проблемы безопасности и проблемы, связанные с отказом сервиса, при существовании внутренних хостов, от которых требуется получать подтверждение и которые могут быть недоступны.
Таким образом, рекомендуется, чтобы необходимость расширения client_certificate_url указывалась администратором сервера, а не по
умолчанию.
URLs, которые указывают порты, отличные от заданных по умолчанию, могут иметь различные проблемы, так же, как и очень длинные URLs (что может быть связано с переполнением буфера).
Кроме того, следует заметить, что в Internet часто используются НТТР кэширующие proxy, и некоторые из них не проверяют самую последнюю версию. Если запрос, использующий НТТР (или другой кэширующий протокол), сконфигурирован неправильно или прерван proxy, proxy сервер может возвратить ответ, не соответствующий текущему запросу.
В некоторых случаях ключи корневых СА, которые предоставил клиент, могут рассматриваться как конфиденциальная информация. Следовательно, ключ корневого СА в расширении должен применяться с осторожностью.
Использование в качестве альтернативы SHA-1 хэшей сертификатов гарантирует недвусмысленность каждого сертификата.
Очевидно, что урезанные МАСs в целом являются более слабыми, чем полные МАСs. Тем не менее, на сегодня неизвестны особенно уязвимые места для НМАС как с MD5, так и с SHA-1, урезанных до 80 бит.
Заметим, что длина выхода НМАС не должна быть такой же, как длина
ключа симметричного шифрования, так как подделка значений МАС не
может быть выполнена off-line: в
Если клиент запросил ответы
Использование расширения запроса
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.