Мы обсудили формально большую часть протокола ssl
Вид материала | Лекция |
СодержаниеФормула на доске. |
- Инфраструктура открытых ключей. Ssl, 56.57kb.
- Москву Песня «Сидят в обнимку ветераны», 446.6kb.
- Население страны за первую половину века возросло с 38 до 69 млн человек. Большую его, 201.48kb.
- Особенности государственного развития на Востоке, 219.31kb.
- Приднестровская Молдавская Республика и Республика Южная Осетия. Абхазия и Южная Осетия, 1452.37kb.
- Проблемы муниципалитетов обсудили на съезде всмс, 260.79kb.
- Актуальность проблемы. Калмыкия самый засушливый район на Европейской территории Российской, 144.18kb.
- Программа форума «служба протокола» день первый (02. 06. 2011г., четверг), 107.69kb.
- Программа форума «служба протокола» день первый (02. 06. 2011г., четверг), 114.5kb.
- Макарова Татьяна Викторовна Форма экспертного материала доклад, 135.72kb.
Лекция №4
10.03.2009
Гурьев
Мы обсудили формально большую часть протокола SSL.
И осталось самый сложный под протокол – Handshake протокол. Любой протокол установления защищенного соединения включает фазу установления, в процессе которой стороны договариваются о том, что стороны будут защищать, от чего, какими алгоритмами будут применять и согласовывают ключи. В SSL за это отвечает SSL Handshake Protocol.
Прежде всего, нужно рассмотреть какие характеристики нужно согласовывать в SSL.
Это довольно много данных, которые делятся на два подблока. Один подблок это параметры сеанса, а второй – параметры соединения. Дело в том, что в SSL, можно в рамках одного сеансе создавать несколько соединений. Тогда параметры сеанса у всех соединений будут одинаковыми.
Сначала параметры сеанса.
- Идентификатор сеанса – это произвольная строка байт. Назначается сервером. Используется только тогда когда предполагается открытие дополнительных соединений или продолжение, прекращение и обновление через некоторое время. Если этого нет, то никакой идентификатор не нужен, и тут будет пустая строка.
- Сертификат другой стороны. Его может и не быть
- Compression method. Код метода сжатия. 0. То есть тождественное преобразование.
- Cipher specs. Спецификация криптографических методов, используемых при обмене. Вообще-то это поле составное, состоит из нескольких полей
- algorithm. Алгоритм симметричного шифрования. Если 0 – null, тождественное преобразование. DES, 3DES, DES40 и пр.
- mac_algorithm, алгоритм при помощи чего вычисляется этот Message authentication Code, то есть обеспечивается подлинность передаваемых данных. Там всего три варианта: Null, md5, sha.
- cipher_type. Перечисление, которое имеет два варианта stream или block. Потоковый или блочный шифр. Почти всегда блочный.
- is_exportable это просто логическое значение, которое показывает, экспортируемый ли алгоритм или нет.
- hash_size – размер отклика хэш функции
- key_material – длина ключа алгоритма симметричного шифрования.
- iv_size – размер инициализационного вектора. Тоже определяется по типу алгоритма. Величина равна размеру блока.
- algorithm. Алгоритм симметричного шифрования. Если 0 – null, тождественное преобразование. DES, 3DES, DES40 и пр.
- MasterKey это строка байт, это основной общий секрет сеанса. Сам этот ключ ни для каких операций над данными не применяется, но на его основе ключи вырабатываются и применяются для операций с данными
- IsResumable булевское значение, которое показывает этот сеанс можно продолжить или нет. Если это значение истинно, то идентификатор сеанса должен быть не пустым. Тоже немного избыточная характеристика. А если не истина, то может быть и пустым. То есть этот параметр показывает, разрешено ли устанавливать дополнительные соединения. Одновременно с основным, или после, закрыть основной, а потом дополнительный.
Дальше параметры соединения
- ServerNumber
- ClientNumber это случайные числа которые клиент и сервер выбирают в начале сеанса и обмениваются ими друг с другом. Клиент и сервер знают оба эти значения. Сами по себе они не секретны, секрет держится не на них, но они добавляют определенное количество разнообразия и неопределенности. И таким образом, усложняют задачу вскрытия. То есть, несмотря на то, что они секретны, они существенно влияют на защитные свойства этого протокола.
- ServerMACSecret
- ClientMACSecret Это ключи, которые используются для формирования MAC. В одну сторону от сервера к клиенту используется один ключ, а в другую сторону от клиента к серверу другой. То есть если в одну сторону вскроют, то соединение в обратном направлении останется безопасным. Надежность увеличивается, надо оба вскрывать.
- ServerWriteKey
- ClientWriteKey ключи, которые используются для шифрования данных. Соответственно, сообщение, которое посылает сервер, сообщение которое посылает клиент. Размер этих ключей и тех и тех определяются значениями, которые были в конце параметров сеансов.
- ClientSequenceNumber, ServerSequenceNumber. 64-битное целое, номер, в обе стороны разный.
- ClientIV, ServerIV начальный вектор.
Задача Handshake протокола установить все эти параметры.
Теперь можно приступить к обсуждению протокола.
Наверное, я буду рассказывать сценарий и по ходу рассказывать о сообщениях, которые в нем применяются.
Протокол ассиметричный, разные роли у клиента и у сервера. Начинается все с того что клиент посылает сообщение ClientHello. Стоп. Начинаться-то оно начинается, то для того что бы RecordLayer все это передать у него уже должны быть какие-то параметры. Поэтому начинается все с состояния, когда уже установлены параметры сеанса, параметры соединения по умолчанию: алгоритм шифрования null, алгоритм формирования MAC кода null, алгоритм компрессии null, то есть все тождественно приравнивается.
Давайте мы немного отвлечемся и рассмотрим связь между этими параметрами. В принципе можно было эти вычисления рассматривать по ходу протокола, но может быть правильнее сейчас обсудить.
У нас генерируется блок данных по следующей формуле. Конечно, она довольно запутанная и немножко наивная, но должна работать
|| - конкатенация, объединение строк
MD5(MasterSecret || SHA(‘A’ || MasterSecret || ServerRandom|| ClientRandom)) || MD5(MasterSecret || SHA(‘BB’ || MasterSecret || ServerRandom || ClientRandom)) ||
MD5(MasterSecret || SHA(‘CCC’ || MasterSecret || ServerRandom || ClientRandom)) ||
MD5(MasterSecret || SHA(‘DDDD’ || MasterSecret || ServerRandom || ClientRandom)) || …
и так далее, пока не будет получена достаточно длинна строка байт. Совершенно случайная, причем зависящая от секрета, которого никакой злоумышленник не знает. А потом из этой здоровой строки по порядку нарезаются необходимые ключи. Сначала отрезаются необходимого размера ClientMACSecret и ServerMACSecret. Потом отрезаются необходимого размера ClientWriteKey и ServerWriteKey. Потом отрезаются необходимого размера ClientIV и ServerIV. Вот так и получаются все эти ключи, так они связаны. По сути, тут сложным образом смешиваются три параметра, MasterSecret, ServerRandom и ClientRandom, и из них генерируется достаточно длинная строка. Поскольку тут применяются односторонние функции, то компрометация любого из этих ключей не приводит к компрометации остальных и тем более к компрометации MasterSecret.
Ну а теперь вернемся к нашему протоколу.
Общая структура сообщения Handshake.
- Type, однобайтное поле, тип сообщения.
- Length, 2-байта, длина
- Data, данные, которые связаны с типом сообщения.
Конкретно сообщения handshake протокола имеют такую структуру
Сообщение ClientHello
- Тип (какое-то число мб 22)
- Длина
- Random, 32-байтное поле, это что потом ляжет в параметр ClientRandom. Рекомендуется, что бы в 4 байта входила текущая отметка времени, а остальные 28 случайно сгенерированные. Но, в общем, эта рекомендация не очень строгая (should, а не must).
- SessionID, переменной длины. Идентификатор сеанса. Применяется в тех случаях, когда это соединение устанавливается в рамках уже установленного сеанса. И если SessionID появляется в сообщении, значит, сторона пытается установить дополнительное соединение в рамках указанного сеанса. Когда устанавливается первоначальное соединение, то никакого SessionID нет, поскольку с сервером еще ни о чем не договорились, и это поле имеет длину 0, оно пустое. Это поле имеет структуру – сначала идет префикс длины (2 байта), а потом само поле.
- CipherSuite, переменной длины, тоже имеет структуру с указанием длины (2 байта). Некоторое количество двухбайтных кодов. Каждый такой код подразумевает комбинацию параметров. Фактически это попытка согласовать алгоритм, который будет применяться. Это
- алгоритм аутентификации сторон,
- алгоритм выработки общего секрета,
- алгоритм шифрования
- и формирования MAC.
- алгоритм аутентификации сторон,
Это такие четверки, Некоторые из которых перенумерованы и за ними закреплены определенные коды. Например,
- SSL_NULL_WITH_NULL_NULL = 0. Именно эта константа описывает состояние протокола в самом начале, когда они еще ни о чем не договорились.
- SSL_RSA_WITH_NULL_MD5 – аутентификация сторон и выработка общего секрета при помощи RSA, шифрования нет, MAC-код на основе функции MD5. Так тоже можно, шифровать не обязательно, смотря какие цели вы преследуете при этой передаче.
- SLL_DH_DSS_WITH_3DES_EDE_CBC_SHA. Аутентификация сторон при помощи алгоритма DSS, выработка общего секрета при помощи алгоритма Диффи-Хелмана, шифрование при помощи алгоритма 3DES в комбинации Encryption-Decription-Encription в режиме Cipher Block Chain, и для формирования MAC кода используется функция SHA.
И так не все различные комбинации так перечислены, но многие. Каждый компонент в этом поле представляет такую константу. И фактически, список этих компонент представляет собой список вариантов шифрования, на которые согласен или которые готов поддерживать клиент. Это предложение клиента по доступным ему алгоритмам защиты.
- CompressionMethods, Структурированное, 2-х байтный префикс длины, а потом список однобайтных компонентов, каждая из которых является кодом некоторого метода компрессии. Информация о том, какие виды компрессии клиент готов поддерживать. Реально есть только один метод компрессии.
Вот такое сообщение ClientHello.
И на это сообщение сервер должен ответить ServerHello.
- Тип
- Длина
- 32 байтное поле Random, которое потом в параметрах соединения попадет в поле ServerRandom.
- SessionID, Поле переменной длины, как и в случае этого поля клиента, это поле структурировано, сначала префикс длина, а потом просто строка байт. Сервер посылает непустой идентификатор сеанса, если сервер считает что этот сеанс может быть расширен на дополнительные соединения или продолжен после завершения основного соединения. Во всех остальных случаях этот SessionID ни за чем не нужен и сервер его не посылает.
- CipherSuite. 2-байтное поле. Это константа, под которой понимается четверка параметров
- алгоритм аутентификации сторон,
- алгоритм выработки общего секрета,
- алгоритм шифрования
- и алгоритм формирования MAC.
- алгоритм аутентификации сторон,
В отличие от сообщения ClientHello, тут только один вариант. Сервер должен из того что предлагал клиент выбрать один конкретный вариант и сообщить какой вариант он выбрал.
- CompressionMethods, 1байтное поле, аналогичное.
После этого, не дожидаясь никаких действий клиента сервер должен послать сообщение ServerCertificate.
- Тип
- Длина
- Цепочка сертификатов X.509. Эта цепочка поедставляет собой сертификационный путь. Этот путь должен закончится на сертификате УЦ, которому априори верит клиент. Как сервер такой путь построит – одному Богу известно, это остается за рамками протокола. На практике – последним оказывается самоподписаный сертификат и тут уже риск пользователя, верить или не верить.
Следующее сообщение (оно не обязательно посылается, бывает, что посылается оба, бывает, что посылается одно из этих сообщений) Server??? Сначала хороший случай. Сообщение ServerKeyExchange посылается в дополнение к сообщению ServerCertificate, если ключ, который лежит в этом сертификате не позволяет вырабатывать общий секрет. Например, тут лежит ключ DSS, им можно только подписывать. Тогда в этом сообщении ServerKeyExchange посылается дополнительный открытый ключ сервера, возможно, что только что сгенерированный, при помощи которого можно провести выработку общего секрета. Но если там RSA, то это сообщение не обязательно, но сервер все равно может его послать если он хочет что бы выработка общего секрета шла с помощью другого ключа.
- Тип
- Длина
- Если RSA
- Modal, поле переменной длины (с 2-байтным префиксом, который показывает эту длину)
- Exponental, Поле переменной длины.
- Вообще говоря, это n и e, и вместе они образуют пару (n, e) которая есть открытый ключ в смысле RSA.
- Modal, поле переменной длины (с 2-байтным префиксом, который показывает эту длину)
- Иначе если DH
- Три аналогичных поля, которые предполагаются алгоритмом Диффи-Хелмана. p, a, e = ax mod p. Эта штука является открытым ключом в смысле Диффи-Хелмана.
- И в том и в другом случае передается открытый ключ.
- Три аналогичных поля, которые предполагаются алгоритмом Диффи-Хелмана. p, a, e = ax mod p. Эта штука является открытым ключом в смысле Диффи-Хелмана.
- Подпись
- Если RSA, то
- Берется MD5 хеш от всего предыдущего сообщения и берется SHA хэш от всего предыдущего сообщения. MD5 это 16 байт, а SHA – 20. И все это шифруется при помощи RSA при помощи закрытого ключа, соответствующего парному открытому ключу из сообщения ServerCertificate. Таким образом, подпись можно проверить из ключа, который был в сертификате. Фактически это тоже сертификат, но нестандартного формата.
- Берется MD5 хеш от всего предыдущего сообщения и берется SHA хэш от всего предыдущего сообщения. MD5 это 16 байт, а SHA – 20. И все это шифруется при помощи RSA при помощи закрытого ключа, соответствующего парному открытому ключу из сообщения ServerCertificate. Таким образом, подпись можно проверить из ключа, который был в сертификате. Фактически это тоже сертификат, но нестандартного формата.
- Иначе если DSS
- Берется только SHA хэш. И подпись DSS. Проверяется точно так же.
- Берется только SHA хэш. И подпись DSS. Проверяется точно так же.
И наконец, самый неприятный вариант, когда это сообщение посылается, а подпись в нем отсутствует. И уже дело клиента продолжать с этим сервером работать или немедленно разорвать соединение. Консервативная политика это рвать соединение и не пытаться с ним связываться. Обратите внимание, что сервер по умолчанию посылает свой сертификат. Сервер обязан подтверждать свою подлинность, а клиент не обязан.
Следующее сообщение называется ServerHelloDone. Это обязательное сообщение. Это признак того, что сервер ничего больше не пошлет, сервер закончит рукопожатие со своей стороны.
Итак, на одно сообщение клиента сервер отвечает до 4х сообщений.
После этого, клиент обязан ответить сообщением ClientKeyExchange.
- Если RSA, то
- PreMasterSecret, поле переменой длины. Предварительный основной секрет. Это число просто выбирает клиент случайным образом. Согласование общего секрета по методу RSA – одна из сторон шифрует и посылает другой. Это шифровано по методу RSA открытым ключом сервера. То если либо тем, который пришел в этом сообщении, либо тем который был в сертификате. Таким образом, прочесть это значение может только сервер.
- Иначе если DH
- ay mod p, тоже поле переменной длины с префиксом, где y – число задуманное клиентом, закрытый ключ клиента, возможно одноразовый. А все вместе это открытый ключ клиента.
Вот в этот момент обе стороны синхронно производят криптографическое вычисление. Первое такое вычисление. Если RSA, то нет вопросов. Если DH, то вычисляется по формуле довольно естественной в этой ситуации (ex mod p)y mod p – это считает клиент. Оно же равно (ey mod p)x mod p – это считает сервер. Как следует из алгоритма DH, это должно быть одно и то же число. Итак, некий общий секрет у нас уже есть. Дальше из этого общего секрета образуется уже MasterSecret – параметр сеанса. Образуется он по формуле похожей на ту, которую мы уже рассматривали, только покороче.
Формула на доске.
Только три раза. MasterSecret будет ровно 48 байт. Хотя цель, конечно не выровнять количество байт, а защититься. Комбинация двух односторонних функций и трех случайных числе, из которых одно заведомо неизвестно злоумышленнику. Дальше на основе MasterSecret вырабатывается третий шаг – рабочие ключи для соединений. Ключ для MAC, ключ для шифрования, IV. В каждую сторону свои.
В этот момент проведены такие вычисления, после чего клиент посылает сообщение ChangeCipherSpec. Это сообщение к Handshake протоколу не принадлежит, это сообщение отдельного протокола. По этому сообщению на канале от клиента к серверу. Клиент в момент отправки, а сервер во время приема меняет все параметры шифрования с тех, которые у него были до того, на те, которые они только что согласовали. С этого момента устанавливается защищенное соединение, управляемое теми параметрами, которые они согласовывали. Потом клиент посылает сообщение Finished
После этого сервер посылает такое же сообщение ChangeCipherSpec клиенту и в этот момент наступают те же условия на встречном канале. Потом сервер посылает Finished.
По смыслу сообщение Finished содержит контрольные суммы по всей предыдущей транзакции. Но идет оно уже на новых параметрах шифрования. Поэтому если в процессе установления соединения кто-то вмешался, то это станет понятно, соединение будет считаться установленным неудачно и будет разорвано. Ну а детали что там такое в этом Finished, и какие проверки производятся, это мы с вами в следующий раз разберем.