что такое протокол безопасности tls | reg.ru

Криптосистема rsa

RSA – самая массовая криптосистема с открытым ключом (асимметричная криптосистема). Повсеместно используется для подписи в составе TLS-сертификатов. Долгое время RSA являлась, фактически, единственной криптосистемой TLS-сертификатов. Лишь несколько лет назад (в 2022 году)

наряду с RSA в сертификатах стала заметна доля ECDSA. Логика построения RSA напоминает протокол Диффи-Хеллмана, однако математические объекты используются другие: отличаются свойства однонаправленной функции. В RSA однонаправленная функция имеет “лазейку” или “чёрный ход”, знание которого позволяет легко обратить функцию, вычислить аргумент по значению.

RSA основана на возведении в степень по модулю (то есть, “взятие остатка”), а стойкость этой криптосистемы связана с задачей разложения числа на простые множители. Можно считать, что секретом в RSA является именно разложение “ключа” на простые множители.

Параметрами криптосистемы RSA являются модуль (это всегда составное число) и открытая (часто её называют “шифрующей”) экспонента – то есть, показатель степени, в которую возводится числовое значение сообщения. Сообщение, в рамках RSA, это целое число, записываемое в виде последовательности байтов.

Модуль в RSA является составным числом: N = pq, где p и q – достаточно большие простые числа, именно их и нужно держать в секрете. (Строго говоря, успехи криптоанализа RSA накладывают на p и q немало дополнительных требований, которые мы не рассматриваем, так как для понимания принципа работы криптосистемы это не важно.)

Знание разложения N = pq позволяет построить “лазейку”, с помощью которой можно обратить однонаправленную функцию, лежащую в основе RSA. “Лазейка” состоит в том, что для шифрующей экспоненты вычисляется обратный элемент – расшифровывающая экспонента. Быстро вычислить обратный элемент позволяет знание разложения модуля ключа на простые множители.

Итак, помимо модуля, для использования RSA с целью генерирования электронной подписи и расшифрования сообщений, необходимо сгенерировать секретный ключ. Секретным ключом как раз и является экспонента, обратная к шифрующей (расшифровывающая). В случае TLS, сервер публикует модуль N и шифрующую экспоненту e, а в секрете сохраняется соответствующая e расшифровывающая экспонента d = e-1 по модулю (p-1)(q-1) (нередко в состав представления секретного ключа входит и разложение модуля – числа p и q; это позволяет ускорить вычислительные операции; конечно, зная открытую и секретную экспоненты – несложно факторизовать и модуль, но данная операция потребует дополнительных затрат).

Похожее:  Как работает сервис подтверждения личности пользователей Tinkoff ID

Таким образом, открытый ключ состоит из модуля N и экспоненты e, а закрытый – из N,p,q,d – модуля, разложения модуля (p,q) и секретной экспоненты. Так как шифрующая экспонента это публичный параметр, то повсеместно используются типовые значения, например, 65537 (или 0x010001).

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

RSA позволяет зашифровать сообщение, выступая в роли асимметричного шифра. Учебный пример зашифрования состоит в возведении сообщения, представленного в виде числа, в шифрующую степень и вычислении остатка по модулю N (заданному в составе ключа). C = me mod N, где C – шифротекст, а m – открытый текст.

Соответственно, зная расшифровывающую экспоненту, можно расшифровать C: m = Cd mod N. Это соотношение можно проиллюстрировать следующим нестрогим рассуждением, используя тот факт, что e = d-1 (mod (p-1)(q-1)), поэтому:

Cd = (me)d = me*d = me*e-1 = m1 = m. В рамках данной статьи не рассматривается несложный математический аппарат RSA и не приводится доказательство корректности операций (доказательство, основанное на малой теореме Ферма, нетрудно найти в тематической литературе).

Из-за возможности проведения эффективной атаки, RSA нельзя использовать подобным способом, непосредственно зашифровывая сообщение. Допустимым вариантом является, например, зашифрование RSA случайного секрета, дополненного специальным образом до разрядности модуля, с последующим вычислением ключа симметричного шифра при помощи хеш-функции от переданного секрета – именно эта схема входит в спецификации TLS (однако использование RSA для обмена сессионными секретами в настоящее время считается устаревшим методом).

Генерация ключей RSA начинается с генерации пары простых чисел, которые составят модуль. Знание p и q позволяет легко определить обратную к шифрующей экспоненту. Однако задача разложения числа на простые множители является вычислительно сложной. Фактически, для достаточно больших чисел (1024 бит и более), сейчас не известно алгоритмов, позволяющих находить разложение произвольных чисел за “разумное время” с использованием любых технологически мыслимых вычислительных мощностей.

Существует, – пока сугубо теоретическая, но отлично обоснованная, – возможность быстрой факторизации при помощи алгоритма Шора на квантовом компьютере достаточной разрядности (под вопросом находится сама возможность создания подходящего компьютера).

“Квантовая атака” касается не только RSA, но также и описанных выше вариантов DH, и криптосистемы электронной подписи ECDSA. Так как применимость квантового компьютера зависит от его доступной разрядности – от количества рабочих кубитов, – то, например, ECDSA будет взломана раньше RSA, так как ECDSA использует числа существенно меньшей разрядности (типичные значения: 256 бит против 4096 у RSA).

При использовании для создания и проверки электронной подписи RSA работает следующим образом. Сторона, генерирующая подпись, вычисляет значение хеш-функции от подписываемого сообщения M, а именно – H = Hash(M), приводит это значение к разрядности используемого модуля N и вычисляет значение подписи при помощи секретной (расшифровывающей) экспоненты:

S = Hd mod N. То есть, с арифметической точки зрения, происходит следующее: значение H, рассматриваемое как двоичная запись натурального числа, возводится в степень с показателем d, а для полученного значения вычисляется остаток от деления на N.

Для проверки подписи требуется знать открытую часть ключа: модуль и шифрующую экспоненту e. Значение подписи возводится в степень e, а получившееся значение сравнивается с вычисленным значением H хеш-функции сообщения: Se (mod N) == H. Если значения совпали, то подпись верна.

Для вычисления корректной подписи (подделки), соответствующей заданному сообщению, третьей стороне необходимо знать секретную экспоненту d. Защиту обеспечивает следующий факт: для быстрого определения d по известным параметрам e и N потребуется найти разложение N на простые множители, а это вычислительно трудно.

Механизм электронной подписи RSA (как и ECDSA) используется для удостоверения параметров протокола Диффи-Хеллмана, переданных сервером в сообщении ServerKeyExchange. Подпись S, передаваемая в составе сообщения TLS, является целым числом, имеющим разрядность, соответствующую разрядности модуля ключа.

Модуль ключа N содержится в сертификате, передаваемом сервером. Так, если модуль имеет разрядность 2048 бит, то для записи подписи потребуется 256 байтов (256*8 = 2048). Подпись, как отмечено выше, вычисляется от значения хеш-функции для объединения параметров DH (в них входит и серверная часть), кроме того, в TLS 1.

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

Получившееся зашифрованное сообщение передаётся в ClientKeyExchange (как описано выше). Сервер, которому известно значение секретной экспоненты, расшифровывает полученное сообщение. Предполагается, что если в ход установления соединения вмешалась третья сторона, подменившая сервер, то этой стороне не удастся корректно расшифровать переданный клиентом секрет, соответственно, стороны не смогут прийти к общему набору сеансовых ключей.

Интересно, что для обхода данного ограничения перехватывающей стороне не требуется строго сам секретный ключ, значение которого нигде не участвует, а достаточно, чтобы была возможность расшифровать данные, например, отправив запрос серверу. Такая схема иногда используется при делегировании полномочий по инспекции TLS-трафика третьей стороне, без передачи самого секретного ключа (однако в отношении RSA схема вовсе не является полностью безопасной: можно заметить, что операции с секретной экспонентой эквивалентны генерированию RSA-подписи). Сейчас (2021) данный метод получения сеансового секрета использовать не рекомендуется.

Другое историческое применение RSA, как асимметричного шифра в TLS, возможно при выборе сервером варианта протокола установления соединения, использующего временные ключи RSA. В таком случае сервер передаёт модуль и значение открытой экспоненты в составе сообщения ServerKeyExchange.

Клиент использует полученный открытый ключ RSA для того, чтобы зашифровать случайные байты ClientKeyExchange, которые послужат для генерации симметричных ключей. Эта экзотическая схема была актуальна для “экспортных” вариантов протокола, когда от реализации требовалось, чтобы для защиты сессии не применялись ключи RSA длиннее 512 бит: сервер использовал “длинный” ключ из сертификата для подписывания “короткого” временного ключа из ServerKeyExchange. Сейчас RSA в TLS не следует использовать в качестве асимметричного шифра, это небезопасно (тем более, с коротким ключом).

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

Для RSA предложено большое количество теоретико-числовых атак. Часть этих атак можно эффективно применить к дефектам и ошибкам в той или иной реализации RSA, что делает атаки не только практическими, но и весьма быстрыми. Сейчас (2021) криптосистема RSA считается устаревшей в целом, что, впрочем, не мешает ей оставаться очень популярной.

Рассмотрим фрагмент трафика установления TLS-соединения, в котором узлы договорились использовать шифронабор с передачей сеансового секрета с помощью шифрования RSA (а именно: TLS_RSA_WITH_AES_128_CBC_SHA). Сертификат, представленный сервером, содержит открытый ключ длиной 2048 бит.

Этот ключ используется клиентом для зашифрования. О том, что клиент прислал именно зашифрованный RSA секрет – сервер знает потому, что RSA указана в шифронаборе, соответственно, рассматриваемое сообщение ClientKeyExchange не содержит никакого указания на то, что используется именно RSA, с тем или иным ключом.

Логика tls

TLS работает с записями (records). Записи находятся в фундаменте протокола. Это нижний транспортный уровень TLS. Сообщения TLS, относящиеся к верхним уровням, могут быть разбиты на несколько записей. Это достаточно важный момент: в некоторых случаях TLS-сообщения требуют сборки из нескольких записей, что существенно влияет на логику обработки состояний протокола.

Если рассматривать сеанс TLS на уровне условного сокета (TCP), то каждая передаваемая TLS-запись представляет собой блок, состоящий из короткого заголовка и, собственно, самих данных. Обратите внимание, что в TLS используется сетевой порядок байтов (старший байт идёт первым, слева направо – “тупоконечное” представление). Разберём заголовок TLS-записи. Заголовок имеет длину 5 байтов, и следующий формат:

00	Тип (1 байт)
01	Версия протокола (2 байта)
03	Длина данных	(2 байта)

Тип – это тип записи (фактически, тип определяет то, как будет интерпретироваться содержимое записи). Определено четыре типа: 20 (0x14) – сообщение Change Cipher Spec (CCS), в версии 1.3 данное сообщение передаётся только как “фиктивное”, и не имеет логической роли в самом протоколе; в более ранних версиях – CCS играет важную роль, обозначая момент перехода к защищённому обмену сообщениями; 21 (0x15)

– сообщение Alert (это не обязательно предупреждение, есть вполне “фатальные alert-ы”); 22 (0x16) – сообщение Handshake (установление соединения); 23 (0x17) – Application Data (запись содержит данные приложения – то есть, полезную нагрузку); трактовка типа Application Data существенно различается в версии 1.3 и предыдущих версиях.

При передаче информации, основные преобразования с шифрами и кодами аутентификации как раз происходят в блоке данных записи с типом 23 (0x17) Application Data, в TLS 1.3 зашифрование информации узлами начинается существенно раньше, чем в младших версиях: зашифрованы уже сообщения Handshake (тип 0x16). До версии 1.

Версия протокола – это версия, записанная в двух байтах, как указано выше: 03 00 – это SSLv3, 03 01 – TLS 1.0; 03 02 – TLS 1.1; 03 03 – TLS 1.2; TLS 1.3 в этом поле предписывает использовать значение 03 03, то есть, версию 1.2, само поле при этом игнорируется.

Длина данных – количество байтов, содержащих данные (сами байты данных следуют после заголовка). Так как используется сетевой порядок байтов, для определения длины нужно значение первого слева байта (h) умножить на 28 и прибавить значение второго (младшего, l) байта, вот так: h * 256 l.


Пример заголовка записи TLS 1.1 (значения байтов – в шестнадцатеричной записи):

16 03 02 03 FE

Раскодируем: это сообщение Handshake (0x16); версия 3.2 (0x03,0x02)- то есть TLS 1.1; длина данных – 0x03FE байтов (1022 байта).

Заголовок всегда передаётся в открытом виде. В том числе, и при использовании TLS 1.3. Однако в TLS 1.3 предусмотрено сокрытие реального типа записи (для защищённых записей) – подробнее этот момент разобран в отдельном подразделе.

За заголовком должно следовать определённое число байтов (>=0), которые представляют собой содержимое данной записи. Максимальное значение в версиях до 1.3 – 18432 байта. 18432 = 16384 2048. То есть, 16 килобайт два раза по килобайту.

Такое значение может показаться странным. Действительно, “базовая” версия записи, описанная в спецификации, предполагает блок данных в 214 байтов, то есть 16 килобайт. Но такой размер относится только к записям, содержащим открытый текст (TLSPlaintext). Например, к сообщениям, управляющим установлением соединения (Handshake). Здесь, действительно, максимальная длина – 16К.

Для защищённых записей ситуация меняется. Во-первых, в TLS до версии 1.3 было возможно использование сжатия данных. Собственно, спецификация предписывала, что сжиматься должны все данные защищённой записи. Но на практике это довольно давно означает не совсем то, о чём можно подумать (для TLS это нередкая ситуация): на практике, сжатие не используется (или, если хотите, используется только “тривиальное сжатие”).

Дело в том, что TLS всех версий среди перечня алгоритмов сжатия содержит алгоритм null, означающий, что никакого сжатия в реальности не производится. Этот алгоритм служит вариантом по умолчанию (раньше можно было встретить алгоритм DEFLATE, но он давно относится к нерекомендованным из-за обнаруженных уязвимостей).

Тем не менее, реально сжатые данные могут, в ряде случаев, оказаться длиннее, из-за особенностей алгоритма сжатия (это выглядит контринтуитивным, но для любого алгоритма сжатия можно подобрать входные данные таким образом, что результат кодирования “со сжатием” окажется длиннее исходных данных).

Во-вторых, для проверки целостности зашифрованных данных к ним приписывается код аутентификации сообщения (MAC) и дополнительная информация (вроде векторов инициализации шифров) – на это в TLS старых версий отводится ещё 1024 байта. Итого – 2048, хотя данный момент и вносит некоторую сумятицу в организацию протокола.

В TLS 1.3 ситуацию упростили: для защищённых данных дополнительно допускается только 256 байтов для кода аутентификации (MAC), сжатие запрещено. То есть, максимальный размер: 16384 256 = 16640. При этом в 16384 байта входят байты дополнения (record padding) – байты со значением 0, которые могут приписываться в конец блока защищаемых данных для того, чтобы скрыть их длину, а также для выравнивания размера записи.

Код аутентификации сообщения – важнейший элемент защиты информации в TLS. В версиях до 1.3 обычно используется HMAC, с той или иной хеш-функцией. Типичный выбор: SHA-1 или SHA-256. Код аутентификации приписывается к блоку данных. Один из архитектурных дефектов версий TLS до 1.

3 состоит в том, что соответствующие спецификации предписывают сперва вычислять MAC, а потом зашифровывать сообщение. То есть, вычисленный код аутентификации присоединяется к открытому тексту сообщения, а потом все вместе зашифровывается. При этом принимающая сторона должна сперва расшифровать полученные данные, а потом – проверить MAC.

Хорошо известно, что такой метод легко приводит к возникновению “криптографических оракулов”, на использовании которых основано несколько эффективных атак против TLS (эти атаки подробно рассмотрены в специальном разделе). Современный подход: код аутентификации добавляется после зашифрования открытого текста, то есть MAC вычисляется для уже зашифрованного сообщения и прикрепляется к нему (“сперва шифр, потом – MAC”).

Для внедрения современного подхода в спецификации добавлено специальное расширение, позволяющее клиенту и серверу договориться о том, в какой последовательности они генерируют коды аутентификации – RFC 7366. Современная версия TLS 1.3 использует шифры только в режиме аутентифицированного шифрования (а именно – AEAD).

Этот режим не нуждается в отдельном MAC, так как целостность данных гарантирует сам алгоритм шифрования (подробное описание дано ниже, в разделе, посвящённом шифрам). Пример: AES в режиме GCM, этот вариант является предпочтительным, поддерживается всем современным ПО, и имеет большое распространение.

Используемые криптосистемы в TLS объединяются в типовые шифронаборы (Cipher Suites, иногда используется русскоязычный термин “криптонаборы”). Чтобы начать обмен информацией по защищённому каналу, клиент и сервер должны согласовать используемый шифронабор.

Очевидно, что параметры шифров и обмена сопутствующей информацией должны быть совместимы между собой. Согласование проводится на этапе установления соединения (Handshake). Композиции шифронаборов существенно отличаются в TLS 1.3 и в предшествующих версиях. Так, в TLS 1.2 и младше в шифронабор входят:

  • криптосистема, используемая для аутентификации (аутентифицируются сервер и сеансовый секрет);
  • шифр, который послужит для защиты передаваемых данных в симметричном режиме;
  • хеш-функция, являющаяся основой для HMAC.

В TLS 1.3 криптосистемы, служащие для аутентификации узлов и получения общего секрета, отделены от, собственно, шифров, что потребовало изменения организации реестра и механизма нумерации шифронаборов (а каждый из них обозначается двухбайтовым индексом). Кроме этих индексов, существуют стандартные обозначения (символьные имена) для шифронаборов. Например, выбор в TLS 1.1 типового шифронабора TLS_RSA_WITH_AES_128_CBC_SHA означает, что будет использована криптосистема RSA для передачи сеансового ключа, AES со 128-битным ключом в режиме CBC в качестве симметричного шифра (то есть, защищаемые данные приложения будут зашифрованы симметричным шифром AES), SHA-1 в качестве хеш-функции HMAC. Для TLS 1.3 ситуация отличается. Шифронаборов здесь меньше, а их имена, соответственно, содержат только указания на шифр и хеш-функцию, например: TLS_AES_256_GCM_SHA384 – шифр AES в режиме GCM и хеш-функция SHA-384. Шифронаборы строго фиксированы, состав закреплён в RFC, каждому приписан свой индекс, а

Шифронаборы имеют важнейшее значение для безопасности TLS. Выбор нестойкой комбинации означает, что достаточной защиты конкретная реализация TLS не обеспечивает. Поэтому, в TLS 1.3 число допустимых шифронаборов резко сокращено – рекомендовано только четыре (2022).

Применительно к вебу: браузеры используют встроенный комплект шифронаборов, обычно это 10-15 вариантов, которые могут использоваться с разными версиями TLS; на сервере поддерживаемые шифронаборы настраиваются администратором. Реестр IANA в настоящий момент содержит свыше 300 (трёх сотен, да) шифронаборов (в число которых входят и так называемые псевдошифры, которые используются в качестве сигналов).

Среди шифронаборов встречается экзотика вроде TLS_KRB5_WITH_RC4_128_SHA и безнадёжно устаревшие варианты, например – TLS_RSA_EXPORT_WITH_RC4_40_MD5. Современные серверы и клиенты не должны использовать подобного. Наличие того или иного шифронабора в реестре IANA означает, что этому шифронабору присвоен индекс (номер) и обозначение, не более того: нужно понимать, что данный реестр не имеет никакого отношения к тому, какие шифры и криптосистемы рекомендованы или не рекомендованы для использования.

В 2022 году добротным вариантом считается, как минимум, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA256, допустимый для TLS 1.2: то есть, генерация общего секрета проводится по протоколу Диффи-Хеллмана на эллиптических кривых, для аутентификации данных на этапе установления соединения используется криптосистема электронной подписи ECDSA (тоже работающая на эллиптических кривых), полезная нагрузка зашифровывается AES с 256-битным ключом в режиме GCM, а в качестве хеш-функции служит SHA-256 (здесь используется при генерации сеансовых ключей).

Протокол диффи-хеллмана

Современный метод генерации общего сеансового секрета – это протокол Диффи-Хеллмана (DH). Использование DH, прежде всего, позволяет добиться прогрессивной секретности (Perfect Forward Secrecy, PFS), когда раскрытие серверного ключа асимметричной криптосистемы (RSA или ECDSA) не приводит автоматически к раскрытию ранее записанного трафика.

Протокол Диффи-Хеллмана – важнейший элемент современных реализаций TLS, также этот протокол имеет огромное значение для множества других защищённых протоколов Интернета, и для прикладной криптографии в целом. Протокол не является шифром или алгоритмом электронной подписи.

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

Задача Диффи-Хеллмана, лежащая в основе классической версии протокола, прямо связана с алгебраической задачей дискретного логарифмирования в конечной группе ― на вычислительной сложности этой задачи и построена защита протокола от перехвата секретного ключа.

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

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

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

Самое интересное, что именно эта идея используется в самых современных криптосистемах, предлагаемых в качестве замены классическим в постквантовую эпоху. Обобщение схемы Диффи-Хеллмана позволяет строить криптосистемы, обладающие стойкостью к взлому с использованием (гипотетического) универсального квантового компьютера.

Такие криптосистемы относятся к постквантовой криптографии. То есть, несмотря на то, что используемые сейчас варианты DH уязвимы для атак с помощью квантового компьютера, ту же самую математическую схему можно реализовать в варианте, обладающем постквантовой стойкостью, перенеся без изменений на другие математические объекты.

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

Вернёмся к использованию DH в TLS. Сейчас (2022 год) распространены два варианта протокола. В классическом случае, DH работает на “обычной” конечной группе, задаваемой простым числом P, которое называется модулем. “Обычная” – довольно условное определение: имеется в виду, что классический DH работает в арифметике остатков, где числа берутся по модулю некоторого достаточно большого простого числа.

Такие операции более привычны, чем второй вариант DH, который использует группу точек эллиптической кривой. (Под “группой” понимается алгебраическая структура – множество с бинарной операцией, подчиняющейся некоторому набору аксиом. Конечная группа – это группа с конечным числом элементов.)

Рассмотрим подробнее классический вариант DH. Здесь группа, в которой будут проводиться операции вычисления общего секрета TLS, задаётся единственным числом – модулем. Это обязательно большое простое число. Большое – означает, что разрядность его записи превышает 1000 бит, а современная рекомендация для классического варианта – не менее 2048 бит. В TLS 1.

2 сервер передаёт это число (значение модуля) в составе сообщения ServerKeyExchange, если используется классический алгоритм DH. Модуль полностью определяет группу, поэтому каких-то дополнительных параметров передавать не нужно. На практике веб-серверы используют ту или иную типовую группу (заданную типовым модулем).

Модуль не является секретным – он передаётся в открытом виде. Таким образом, известны группы, используемые большинством веб-серверов, поддерживающих DH. Вообще говоря, уникальные группы DH рекомендуется генерировать при начальной настройке TLS, это несложно сделать стандартными утилитами.

Тем не менее, не так давно наиболее распространённая типовая группа имела разрядность в 1024-бита, что не слишком много. Вместе с задающим группу модулем, сервер передаёт другой открытый параметр – генератор (см. ниже), – а также свою часть обмена Диффи-Хеллмана – открытый ключ (принцип его вычисления рассмотрен ниже).

Второй вариант протокола Диффи-Хеллмана – «эллиптический», он основан на свойствах эллиптических кривых. (Элементарный обзор некоторых основ практического математического аппарата, который стоит за криптографией на эллиптических кривых, дан в “Приложении А”.

Базовые операции эллиптического DH мы рассмотрим чуть раньше.) Математические операции протокола DH в обоих случаях эквивалентны, отличие кроется в используемых группах: «эллиптический» вариант работает на группе точек эллиптической кривой. Такая группа может быть построена при помощи заданной на кривой операции, называемой сложением точек.

Следует понимать, что здесь важно не название, а свойства операции, с таким же успехом её можно было назвать умножением точек. Собственно, различают два эквивалентных подхода к обозначению групповых операций: мультипликативный (умножение) и аддитивный (сложение).

Обычно, применительно к TLS (и прикладной криптографии), в случае классического протокола DH – используют мультипликативный вариант и говорят об умножении и возведении в степень (экспонента); в случае “эллиптического” – аддитивный, и говорят о сложении точек и нахождении кратного (умножение на скаляр). Это чисто терминологическое отличие, никак не связанное со стойкостью и другими особенностями протокола.

Итак, операция сложения точек ставит в соответствие двум точкам кривой – третью, называемую их суммой. На этой операции строится алгоритм удвоения точки и умножения на скаляр (целое положительное число, не являющееся, соответственно, точкой на кривой).

Также вводится нейтральный элемент – в его роли выступает бесконечно удалённая точка. Эллиптическая кривая, в общем смысле, обладает непрерывностью, но в случае с протоколом Диффи-Хеллмана она рассматривается только в “целых” точках, множество которых задано определённым образом.

Прикладная особенность группы точек эллиптической кривой состоит в том, что решение задачи дискретного логарифмирования (обратной задачи для основы протокола DH) здесь сложнее, чем в “обычной” группе, это позволяет использовать ключи меньшей разрядности.

Протокол DH на “обычной” группе работает следующим образом. Для того чтобы получить общий секретный ключ, стороны сначала выбирают общие параметры Диффи-Хеллмана ― это модуль, задающий группу (простое число), а также некоторый элемент этой группы, называемый генератором – соответственно:

P и G (то есть, два целых числа). Параметры DH открыты и считаются известными третьей стороне. На следующем шаге каждая из сторон выбирает собственное секретное целое число a (и, соответственно, b) и вычисляет значение A = Ga mod P (соответственно, B = Gb mod P).

То есть, все операции проводятся по модулю P (“взятие остатка”), что, собственно, и отображает их результаты в элементы группы. Далее стороны обмениваются по открытому каналу значениями A, B и вычисляют Ab mod P и Ba mod P, соответственно.

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

В случае TLS, сервер передаёт в сторону клиента параметры Диффи-Хеллмана и свой открытый ключ (A), удостоверяя эти значения собственной электронной подписью (либо RSA, либо ECDSA). Подпись вычисляется от ключа, открытая часть которого указана в сертификате сервера.

Прослушивающая канал сторона знает значения P, G, A и B. Но для того, чтобы определить значение секретного ключа, необходимо вычислить a или b, решив относительно x уравнение вида A = Gx mod P. Стоящая за решением этого уравнения классическая задача и называется задачей дискретного логарифмирования в конечной группе.

Фундаментальная причина сложности данной операции сходна с общими проблемами деления (или вычитания, тут всё зависит от используемой терминологии) в группах: грубо говоря, деление представляет собой операцию поиска среди элементов группы такого, который при умножении на известный делитель давал бы делимое (поиск обратного элемента).

Ситуация эквивалентна привычному делению из курса начальной школы: чтобы разделить 15 на 3 нужно найти такое число, которое при умножении на 3 давало бы 15. Если известны некоторые свойства группы, позволяющие построить её арифметическую структуру; или группу удаётся рассмотреть в составе “большей” структуры (некоторого кольца), то операцию деления можно оптимизировать, используя тот или иной “быстрый” пошаговый алгоритм, отбрасывающий из перебора заведомо неподходящие элементы.

Хорошо известным примером такой оптимизации является школьное “деление столбиком”. Именно поэтому в случае с современными вариантами DH работает квантовый алгоритм Шора, использующий квантовое представление структуры группы (кольца, если говорить строго), измерение которого даёт результат, позволяющий уже классическим методом очень быстро выполнить дискретное логарифмирование.

Практическая применимость протокола Диффи-Хеллмана основывается на том, что знание секретного значения позволяет быстро вычислить нужную экспоненту. Действительно, предположим, что требуется вычислить A = Gm. На первый взгляд, для этого необходимо умножить G на себя m-1 раз: G*G*…*G.

Казалось бы, атакующая сторона тут оказывается в таком же положении, как и стороны, использующие протокол: атакующий может начать умножать G (это открытый параметр) и продолжать вычисления до тех пор, пока не получит искомое значение A (которое перехватил).

Таким образом можно определить значение m. Однако реальная ситуация отличается. Дело в том, что зная секретный параметр m, вычислить G можно гораздо быстрее. Простейший пример: предположим, что нам нужно вычислить G5, показатель 5 заранее известен.

G5 = G*G*G*G*G. Это четыре операции умножения, но c другой стороны, значение G2 можно записать, и использовать несколько раз. Получаем: G2*G2*G, а это уже только три умножения (учитывая G*G). То есть, зная значение показателя, можно применить быстрые алгоритмы (Монтгомери и др.) и получить огромный выигрыш в числе операций, по сравнению с атакующим, который должен проверить все показатели.

Для протокола DH, работающего на эллиптической кривой, вместо модуля P задаётся сама кривая (с дополнительными параметрами); вместо возведения в степень – используется умножение на скаляр (то есть, вычисляется кратное для точки: если мы умножаем точку A на значение 5, это означает, что на кривой вычисляется точка 5A = A A A A A).

В TLS используются именованные кривые, параметры которых заранее известны сторонам. Генератором, в эллиптическом случае, является точка кривой. Однако логика протокола от этих особенностей не зависит. Операции DH на эллиптической кривой просто будут записаны в аддитивной форме: Ab = (Ga)b = Ba = (Gb)a = Gab.

Обратите внимание на скобки в предыдущем выражении: они указывают на “ассоциативность”, обобщение которой и позволяет перенести схему Диффи-Хеллмана на другие математические объекты, если для них такая “ассоциативность” выполняется. Конечно, должен работать и описанный в предыдущем абзаце механизм ускорения вычислений при известном секрете. Для группы точек эллиптической кривой он работает, сводя основную часть вычислений к некоторому количеству удвоений точки.

Итак, практическая полезность DH строится на сложности задачи дискретного логарифмирования в конечной группе. Известно, что при наличии больших, но вполне доступных, вычислительных мощностей (не квантовых), для 1024-битной “классической” (не “эллиптической”) группы можно уже сейчас предвычислить арифметическую структуру, потратив пару лет работы суперкомпьютера и сохранив результаты в специальных таблицах.

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

Дело в том, что сеансовый ключ, если вы умеете отыскивать дискретный логарифм, элементарно вычисляется из ключа DH, который передаётся в открытом виде. Предвычислить нужную структуру можно только для заранее известной группы, поэтому для атакующего важно, чтобы TLS-серверы использовали типовые параметры.

При этом, для тех, у кого ресурсов мало (кто не является специализированным агентством, например), группа остаётся вполне стойкой. (Для групп точек эллиптической кривой подобных алгоритмов быстрого дискретного логарифмирования на настоящий момент в открытой печати не опубликовано.

С фундаментальной точки зрения это, скорее всего, обусловлено тем, что для произвольных эллиптических кривых не удаётся найти некоторых аналогов простых чисел, которые помогли бы доступным, в плане вычислений, способом вложить группу кривой в другое множество с дополнительной структурой, где значение логарифма отыскать проще.

Разновидность DH на группе точек эллиптической кривой называется ECDH. Это рекомендуемый сейчас вариант алгоритма, он получает всё большее распространение в современных реализациях TLS. Так как отыскание дискретного логарифма в группе точек эллиптической кривой вычислительно сложнее, можно использовать ключи с меньшей разрядностью.

Высокую секретность, согласно современным представлениям, обеспечивает группа эллиптической кривой с разрядностью 192 и более бит. Также алгоритм позволяет безопасно использовать общую кривую, а не генерировать новую для каждого сервера. По крайней мере, современная ситуация такова, что рекомендовано использовать хорошо известные кривые из утверждённого списка (в TLS 1.2, 1.

1 возможно использование собственных параметров, они будут передаваться в сообщениях Handshake; в TLS 1.3 – набор зафиксирован спецификацией). Распространённый случай – кривая secp256r1, предлагающая разрядность 256 бит. Если группу классического DH в TLS легко поменять – модуль и генератор непосредственно передаются в сообщении сервера и могут быть любыми, – то для типовых эллиптических кривых всё сильно сложнее: все параметры здесь фиксированы заранее, клиент и сервер могут договориться только выборе кривой из ограниченного списка.

В TLS версий до 1.3 параметры DH всегда задавал сервер. Эти параметры, как сказано выше, подписываются серверным ключом, что необходимо для того, чтобы параметры не могли быть заменены в момент передачи. Хотя сообщение Finished защищает весь обмен Handshake, активный атакующий мог бы подменить параметры DH на свои собственные, перехватив соединение и, в дальнейшем, сгенерировав для клиента и сервера разные, но корректные сообщения Finished – протокол DH сам по себе не защищён от атаки типа человек посередине (схема, сходная с только что описанной, применяется в атаке Logjam).

Поэтому подпись на данных параметрах крайне важна. В зависимости от типа сертификата, в качестве криптосистемы подписи может использоваться либо ECDSA (современный вариант), либо RSA, а устаревший алгоритм DSA сейчас не встречается. В TLS 1.3 протокол DH используется уже в начальной фазе установления соединения, поэтому параметры подписываются в составе прочих сообщений, а подпись передаётся сервером в сообщении CertificateVerify.

Другое важное отличие 1.3 в том, что здесь параметры DH согласуются узлами, причём, инициатива принадлежит клиенту: он передаёт список поддерживаемых групп (а это и эллиптические, и “мультипликативные”, классические варианты) в расширении ClientHello, так же, в другом расширении, передаются и открытые ключи клиента. Сервер выбирает подходящие параметры.

Широко используются аббревиатуры ECDHE и DHE, то есть, варианты записи, оканчивающиеся буквой E. Эта буква обозначает то, что протокол DH используется для выработки временного сеансового ключа, от английского ephemeral (“эфемерный”). То есть, E – подчёркивает то, что ключ не является постоянным (однако, как уже отмечено выше, не следует использовать для обозначения этого свойства прямой русский перевод – “эфемерный”: в русскоязычном варианте ключ называется “временным” или “сеансовым”).

Почему потребовалось отдельно выделять “временные ключи”? Причина в том, что в TLS определены варианты соединений, использующих постоянный серверный открытый ключ DH, заданный в сертификате. Сейчас такие схемы на практике не встречаются, поэтому ключ, полученный в результате обмена сообщениями DH, всегда будет временным.

Это, однако, не означает, что данный ключ каким-либо образом автоматически исчезает после закрытия соединения: во-первых, ключ может не удаляться из памяти сервера или направляться в долговременное хранилище, по тем или иным причинам; во-вторых, ключ можно восстановить из записи трафика, при условии, что третьей стороне известен (или она может вычислить) соответствующий секретный параметр Диффи-Хеллмана.


Пример серверного сообщения ServerKeyExchange, содержащего параметры DH (в “классическом” варианте) и подпись на этих параметрах. (Вариант на эллиптической кривой рассматривался в анализе дампа трафика выше.)

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *