Ресурсы: техническое описание TLS, LaTeX - в картинки (img), криптографическая библиотека Arduino, шифр "Кузнечик" на ассемблере AMD64/AVX и ARM64
Немного занимательной теории чисел, применительно к одной весьма экзотической особенности TLS (как известно, это основной защищённый протокол современного Интернета). Изучая настройки и параметры данного протокола, можно столкнуться с интересной формулой:
p = 2ⁿ – 2ⁿ⁻⁶⁴ + 2⁶⁴(⌊2ⁿ⁻¹³⁰e⌋ + x) – 1
Для чего она нужна и что обозначает?
В новой версии TLS 1.3 зафиксированы практически все криптографические параметры, которые только можно как-то зафиксировать. Так, зафиксированы группы для протокола Диффи-Хеллмана (DH), причём, даже группы для “классического” варианта (“классический” – это который в мультипликативной группе кольца вычетов; а если говорить проще, то тот вариант, который по модулю простого числа, с взятием остатков, а не эллиптический). С наперёд заданными параметрами криптосистем связаны опасения: а вдруг эти параметры специально выбраны с бэкдором? Поэтому существуют методы, позволяющие генерировать параметры некоторым проверяемым и, вместе с тем, “непредсказуемым” способом. Теперь переходим к формуле.
Это формула, по которой генерируются простые числа, задающие группу для DH в TLS. n – требуемая разрядность, e – основание натурального логарифма, x – переменная, принимающая целые положительные значения. То есть, можно сказать, эта формула извлекает из числа e подходящее целое простое число нужной разрядности (подходящее – потому что подходит не всякое, но это детали). Для получения именно простого числа – нужно подбирать значение x (используется минимальное подходящее). Механизм описан в RFC 7919 (но попробуйте “нагуглить” эту формулу).
Простыми словами: смысл данной магической операции в том, что нельзя выбрать в качестве задающего группу параметра произвольное число с нужными свойствами (с бэкдором), а приходится довольствоваться фрагментом записи числа e. Конечно, вооружившись “секретными теоремами“, можно предположить, что данная формула как раз и извлекает только нужные простые числа, потому что само e – это бесконечная сумма значений, связанных со всякими комбинаторными штуками. Но это уже была бы магия столь высокого градуса, что лучше о её существовании я рассуждать не стану, тем более, что в записи e заведомо можно найти любое простое число, соответственно, и число с бэкдором.
Впрочем, с фиксированными параметрами DH связаны и более простые рассуждения: стойкость DH базируется на сложности дискретного логарифмирования, но для классического варианта и заранее заданной группы (параметра, то есть) известно, что можно предвычислить некоторые алгебраические структуры, которые потом позволят вычислять логарифм быстро. Правда, такие вычисления требуют огромных мощностей и/или затрат времени. Но если вы теоретико-числовая служба специального агентства и заранее знаете, что набор из нескольких групп позволит раскрывать почти весь TLS-трафик, то можно и потратиться. Ключевой момент тут – нужно заранее знать группу, а универсальные методы неизвестны.
Comments Off on Формула для групп из TLS
Современные антивирусы нередко добавляют свой “особый” корневой сертификат в системное хранилище или в хранилище браузера (зависит от платформы), это делается для того, чтобы прозрачно и без предупреждений для пользователя инспектировать трафик, защищённый TLS (обычно – HTTPS). Антивирус проксирует соединения, генерируя в реальном времени подменные сертификаты для TLS-серверов, которые посещает пользователь. Подменные сертификаты подписаны от корневого сертификата антивируса. У такого решения есть ряд неприятных, с точки зрения безопасности, побочных эффектов. Так, при помощи ключа от этого корневого сертификата можно перехватывать TLS-соединения не только на компьютере пользователя, но и на других промежуточных узлах сети (при этом не обязательно, чтобы антивирус работал – достаточно, что его корневой сертификат находится в списке доверенных).
Естественно, антивирус должен бы при установке генерировать для добавляемого сертификата уникальный локальный ключ. В противном случае, всякий пользователь антивируса, который сумел извлечь ключ из своей копии программы, получает потенциальную возможность перехватывать трафик других пользователей. Но, во-первых, антивирус может полагать, что сгодится и одинаковый для всех установок ключ. Во-вторых, уже встречались ошибки (или условные “ошибки”) в реализациях аналогичных схем, приводившие к тому, что ключ везде получался один и тот же. В-третьих, генерировать локальный ключ можно таким способом, что, зная дополнительную информацию, его нетрудно быстро вычислить и использовать на перехватывающем узле.
Перехватывающему узлу, конечно, ещё необходимо определить, что у клиента, который пытается установить TLS-соединение, встроен корневой сертификат от данного антивируса. Дело в том, что список корневых сертификатов системы не передаётся наружу, а попытка подмены при неустановленном сертификате – вызовет предупреждение в браузере. Однако перехватывающий узел может распознать антивирус подходящей версии при помощи анализа пакетов, которыми этот антивирус обменивается с центральными серверами разработчика. При целевой атаке – определить антивирус можно, просто взглянув на интерфейс операционной системы. Ну, либо сами разработчики могут посмотреть в регистрационной БД. И нельзя исключать вариант, что подходящий антивирус установлен у подавляющего большинства пользователей.
С другой стороны, при таком проксировании, соединение с удалённым сервером устанавливает не браузер, а прокси антивируса. Реализация TLS в данном прокси может содержать уязвимости. В целом, следует ожидать добротной реализации TLS от браузера, а не от того или иного антивируса (либо другого TLS-прокси). Дело в том, что подобное проксирование на клиентской стороне находится в некотором противоречии уже с идеологией протокола TLS, поэтому ситуацию в любом случае не улучшает. TLS-прокси может не валидировать или некорректно валидировать серверные сертификаты, соответственно, отсутствие аутентификации сервера позволит перехватывать соединение третьей стороне. Более того, TLS-прокси антивируса может быть ошибочно (или даже намеренно, ничего нельзя исключать) настроен так, что в качестве сессионных используются нестойкие ключи, которые достаточно легко вычислить, наблюдая TLS-трафик (либо даже просто зная время соединения и параметры клиента), для этого даже не потребуется знать секретный ключ от сертификата и активно перехватывать соединение. При этом, браузер может быть современным, а браузерная/системная реализация TLS – надёжной, но так как ключи для внешней сессии генерирует проксирующий модуль антивируса, появляется дополнительная возможность для пассивной расшифровки трафика, которая никак от браузера не зависит.
Комментарии (2) »
1.
MitM – атака “Человек посередине”. Это атака уровня аутентификации, а не “шифрования”. Смысл атаки, в случае TLS (на клиентской стороне), состоит в том, что подменяется узел, с которым клиент пытается устанавливать соединение. А для того, чтобы клиент не догадался о подмене – используется сертификат, выпущенный для имени исходного узла. История с сертификатами в основном касается как раз TLS, для других протоколов ситуация может быть иной.
2.
Возьмём для примера HTTPS (работает на базе TLS), а также браузер в качестве клиента. Если подменный сертификат для удостоверяемого узла выпущен от корневого ключа, которого браузер не знает, то браузер выдаст предупреждение системы безопасности. (К сожалению, ситуация такова, что для многих пользователей такое предупреждение означает примерно следующее: “Нажмите “Продолжить” для получения доступа к вашему любимому сайту”. Соответственно, пользователи привычно игнорируют предупреждение.) Важный момент: если соответствующий корневой ключ, в составе корневого сертификата УЦ, будет штатным образом импортирован пользователем в браузер, то никаких предупреждений браузер больше выдавать не будет. Это штатное поведение – импорт сертификатов требуется в корпоративных средах, а также в ряде других случаев (скажем, вы хотите использовать собственный УЦ для собственных сайтов). После успешного импорта, работа по HTTPS снова станет прозрачной. Но это относится только к браузерам, да и то, в случае, если они не используют каких-то дополнительных мер по отслеживанию ключей (плагины и пр.).
3.
На уровне промежуточного провайдера доступа (интернет-провайдера) можно потребовать, чтобы для успешного соединения с сайтами по HTTPS использовался именно тот набор параметров (в этот набор входит подменный сертификат), который разрешается. Детектировать параметры нетрудно – в действующих версиях TLS достаточно признаков: например, сертификаты передаются в открытом виде, поэтому легко проверить, какая цепочка используется в данном соединении (можно также привязать сессии к отпечаткам открытых ключей перехватывающего узла). Соответственно, оборудование DPI сможет предотвращать попытки установления HTTPS-соединений с недопущенными для применения параметрами. Все эти схемы давно отработаны на практике в корпоративных сетях, а оборудование и программное обеспечение – есть готовое.
4.
Тем не менее, при устройстве тотального MitM – много чего сломается: например, перестанут работать сервисы, использующие клиентскую авторизацию; возникнут проблемы с различными VPN; перестанут работать решения, которые используют привязку к конкретным открытым ключам на стороне сервера (это относится к приложениям для смартфонов, к различным клиентам онлайн-сервисов, начиная от месcенджеров, интернет-телефонии, систем телеконференций и заканчивая клиентами онлайн-игр).
5.
Главная проблема с перехватом TLS при помощи MitM в том, что такое решение полностью уничтожает смысл аутентификации узлов на стороне клиента. Дело в том, что клиент больше не может проверять валидность сертификатов оконечного узла, с которым пытается установить соединение: клиент просто не видит этого подлинного узла и сертификатов – он обменивается данными с перехватывающим, подменным узлом и вынужден доверять ему. Если на пути от подменного узла до узла, соединение с которым перехватывается, что-то пошло не так, то обнаружить это “не так” должен перехватывающий узел. Однако, он может этого не делать: вообще, ситуация, когда перехватывающий узел просто не валидирует сертификаты перехватываемого – встречается нередко. Более того, не в интересах перехватывающего прокси заниматься такими проверками. Так, этот узел не может видеть всего контекста установления соединения (часть контекста – у клиента: например, только клиент знает, какие ключи и сертификаты он ожидает получить от сервера), а поэтому в принципе не может надёжно проверить подлинность соединения.
6.
Технически, выпускать подменные сертификаты может тот или иной хорошо известный УЦ, то есть, УЦ, корневые ключи которого включены в стандартный дистрибутив браузера. Однако попытка массово реализовать подобное для большого числа ничего не подозревающих пользователей – скорее всего приведёт к тому, что ключи УЦ будут отозваны из браузеров. Тем не менее, УЦ попадались на подобных штуках.
7.
Инфраструктура сертификатов и УЦ в современном Интернете развивается. Как раз в сторону повышения прозрачности. Соответственно, внедрение MitM будет быстро обнаружено. Для того, чтобы подтвердить факт MitM, тот или иной пользователь может просто опубликовать (отправить, скажем, в Google или в, условный, Facebook) подменный сертификат. Этот сертификат пользователю легко извлечь – в браузере, например, для этого есть функция экспорта. Подделать такой сертификат не выйдет (ну, если бы некий пользователь решил дезинформировать Google), потому что он обязательно содержит электронную подпись, которую можно проверить.
Комментарии (7) »
(Техничная записка из области популярной криптологии, которая, думаю, будет полезна и на dxdt.ru.)
Нередко можно услышать, что сеансовые ключи, полученные сторонами по протоколу Диффи-Хеллмана (DH), есть только у клиента и сервера, а больше нигде не сохраняются. Очевидно, что и сервер, и клиент сохраняют ключи у себя на некоторое время, как минимум, пока обмениваются данными в одном контексте. Ключи могут храниться дольше, потому что есть механизм возобновления TLS-сессии. Но существует и другой аспект, про который забывают. В TLS-трафике, которым обменивались клиент и сервер, вообще говоря, содержится представление сеансовых ключей. То есть, то, что в открытом виде эти ключи не передаются, не означает, что они совсем не связаны с трафиком. На самом деле – ключи в трафике есть, просто их трудно извлечь, потому что они представлены в форме, которую сложно обратить. Случай некоторым образом похож на ситуацию с удалением файлов в целом ряде файловых систем: удалённый файл – всё ещё на диске, просто, его трудно найти. Естественно, вычислить сеансовые ключи из трафика существенно сложнее, чем восстановить файл.
Если третья сторона записывает TLS-трафик, то вместе с ним сохраняются и данные, послужившие источником сеансовых ключей (в случае использования DH). Фактически, можно говорить о том, что эти ключи тоже сохраняются вместе с записанным трафиком. В этом и состоит тонкость, относящаяся к области различий между реально уничтоженными (или отсутствующими) и зашифрованными данными. Для восстановления ключей DH из записи трафика нужно обладать дополнительной информацией (либо уметь решать вычислительные задачи, которые сейчас считаются трудными). К такой дополнительной информации относится, скажем, состояние генератора псевдослучайных чисел, который использовался на стороне сервера (или клиента) при выработке сеансовых параметров DH.
Когда говорят о прогрессивной секретности (PFS), которой позволяет добиться использование DH, то имеется в виду вовсе не то, что ключи невозможно восстановить после того, как сессия завершилась, а лишь то, что утечка долговременного ключа не раскрывает сессионных ключей. Не более того. Обычно, долговременный ключ в TLS – это ключ, используемый для аутентификации сервера, при помощи электронной подписи. Если прогрессивная секретность отсутствует, то восстановление сеансовых ключей, если у вас есть долговременный секретный ключ (это будет, соответственно, RSA) оказывается тривиальной задачей – просто расшифровываем исходные данные из трафика.
Трафик приложений в TLS зашифровывается симметричным алгоритмом, который и использует сеансовые ключи. То есть, в принципе, для того, чтобы раскрыть трафик, можно “просто” правильно подобрать симметричные сеансовые ключи. Однако эта задача вовсе не эквивалентна восстановлению ключей из записанного обмена параметрами DH. Скорее всего, с DH разобраться легче (теоретически; а на практике – приходится надеяться на уязвимости, которых, впрочем, немало).
Для детального понимания ситуации нужно рассмотреть следующий случай: предположим, что стороны, обменивающиеся данными в рамках защищённой сессии, используют заранее известный им разовый (относительно сессии) набор секретных сеансовых симметричных ключей и, скажем, AES. То есть, симметричные ключи не генерируются при помощи обмена в рамках DH, а известны заранее. По каналу связи они не передаются, канал не используется для их генерации. (Аутентификацию оставим за скобками.) Пусть используется добротный режим потокового шифрования: генерируется ключевой поток (гамма), совпадающей по длине с открытым текстом, а шифротекст является результатом операции XOR над открытым текстом и ключевым потоком. Примерно так работает GCM (аутентификацию мы договорились оставить за скобками) и всякий другой “режим счётчика”. Так как полученный ключевой поток будет, вообще говоря, вычислительно неотличим от псевдослучайной функции, то для записавшей трафик стороны ситуация окажется, условно говоря, семантически неотличима от абсолютно стойкого шифрования.
Думаю, понятно, что при использовании DH ситуация отличается в корне: теперь в составе сеанса появляются открытые ключи DH, которые представляют собой новый вектор атаки, а кроме того – они сохраняются вместе с трафиком. А вот в предыдущем случае – физическое уничтожения носителя ключей, действительно, приводит к уничтожению и самих ключей.
Конечно, это достаточно техничный момент. Тем не менее, он актуален для современного использования TLS. Например, если у кого-нибудь есть супер-пупер-сверхкомпьютер, который позволяет за разумное время решать произвольную задачу дискретного логарифмирования (то есть, “обращать” DH), то этот кто-то может замечательно читать ключи DH из записанного трафика – потому что эти ключи там есть.
(Впрочем, для AES тоже можно предложить научно-фантастический компьютер, решающий соответствующую систему уравнений: но такому компьютеру потребуется известный открытый текст, а для случая DH и логарифмирования – он не нужен.)
Комментарии (6) »
Некоторое время назад выяснилось, что в Symasntec выпустили для Blue Coat промежуточный сертификат УЦ, который мог быть использован в SSL-прокси (для систем инспектирования трафика) – этот момент вызвал довольно живое обсуждение, так как прозрачный перехват TLS остаётся горячей темой в сообществе разработчиков браузеров. Следующее событие про эти две компании: Symantec покупает Blue Coat.
Comments Off on Symantec и Blue Coat
Про перехват TLS я уже писал, например, применительно к HTTPS, а также касательно некоторых технических особенностей, обеспечивающих прозрачность перехвата TLS. Продолжим тему технических деталей. Пусть требуется пассивно читать трафик TLS, сервис-провайдер готов участвовать, но не имеет возможности предоставить внешний API для доступа к ключам, как быть? Есть известное решение, но оно требует некоторого бэкдора.
Идея состоит в том, чтобы значение ключа можно было восстановить из самого защищённого трафика. Напомню, что трафик TLS защищается при помощи симметричного шифра и сеансового ключа. В современных реализациях сеансовый ключ генерируется сторонами по протоколу Диффи-Хеллмана (классического или на эллиптических кривых), который и обеспечивает защиту сессии. Какие секретные параметры нужно знать, чтобы вычислить сеансовый ключ? Такой параметр лишь один – это экспонента Диффи-Хеллмана (DH), используемая сервером (или экспонента клиента). Действительно, если прослушивающая канал сторона знает экспоненту (являющуюся в протоколе Диффи-Хеллмана секретным ключом сервера), то она может вычислить общий сеансовый ключ так же, как это делает сервер или клиент. Осталось понять, как можно передать значение экспоненты, например, с сервера “в эфир”, чтобы не догадались те, кто канал не должен прослушивать. Для этого в TLS есть целый ряд способов. Самый простой – это поле ServerRandom, которое содержит случайное значение длиной в 32 байта (256 бит) и передаётся в открытом виде. В этом поле может быть передано состояние генератора псевдослучайных чисел, который используется для выбора значения секретного значения протокола Диффи-Хеллмана. Зная состояние генератора – третья сторона сможет определить это секретное значение.
Осталось придумать, как сохранить в секрете возможность прослушивания – чтобы расшифровать данные мог только тот, “кому следует”. Для этого оператору сервера передаётся открытый ключ (например, в качестве типового параметра настроек), который он использует для зашифрования состояния генератора, перед тем, как передать его в поле ServerRandom на всеобщее обозрение. Кстати, 256 бит – это слишком мало для RSA, но вполне достаточно для эллиптических кривых, поэтому в качестве механизма защиты может использоваться какая-нибудь разновидность криптосистемы Эль-Гамаля на эллиптических кривых. Считается, что именно этот способ предполагался на роль бэкдора в нашумевшем случае DUAL_EC_DRBG. Естественно, зашифрованный параметр в ServerRandom практически неотличим от случайного числа – чтобы что-то понять, нужно знать секретный ключ, который неизвестен даже серверу-источнику перехватываемого трафика. (Передача ключей в ServerRandom – не единственный способ.)
При данной схеме третья сторона прослушивает канал, записывает трафик, а при необходимости – расшифровывает его без участия провайдера сервиса. То есть, последний никак не будет “скомпрометирован”. В этом отличие от схемы с предоставлением API, наличие которого, во-первых, раскрывает намерения провайдера, во-вторых, компрометирует перечень прослушиваемых каналов, так как каждому подключению соответствует обращение к API, которое можно зафиксировать в логах. Бэкдор с публикацией ключа DH – позволяет действовать в пассивном режиме. На стороне сервера раскрыть такой бэкдор может только анализ исходного кода, если не были предприняты дополнительные меры по защите, вроде выноса части криптофункций в аппаратный модуль (HSM), но это история для другой заметки.
Комментарии (1) »
Несколько технических моментов, которые касаются практики использования TLS и интересны в свете обсуждения новостей о готовящемся (якобы) перехвате TLS-соединений в Казнете.
Очевидно, что для прозрачного перехвата TLS достаточно, чтобы перехватывающий узел знал секретный серверный ключ. Но это условие не является необходимым. Перехватывающий узел может не содержать секретного ключа, но успешно проводить перехват. Если вы внимательно посмотрите на протокол установления соединения TLS, то наверняка заметите, что секретный ключ там требуется лишь один раз. Пусть, например, клиент и сервер договариваются о соединении TLS 1.2, использующем AES в качестве шифра и протокол Диффи-Хеллмана на эллиптических кривых (ECDHE) для генерации сеансового ключа. В таком случае секретный ключ сервера требуется только для того, чтобы подписать сообщение Server Key Exchange, содержащее серверные параметры протокола Диффи-Хеллмана. Эту функцию подписывания перехватывающий узел может возложить на легитимный сервер, который, по запросу, подпишет выбранные перехватывающим узлом параметры. Естественно, легитимный сервер должен, таким образом, добровольно принимать участие в перехвате. Эта замечательная и очень полезная технология используется для балансировки нагрузки – в CloudFlare, известном своими передовыми разработками в этой области, она называется Keyless SSL. Кроме того, этот же метод годится для систем обнаружения вторжений (IDS), защиты от атак и множества других полезных приложений.
Предположим, что требуется перехватывать трафик, идущий в сторону сервисов условной компании “Имярек”. Согласие “Имярек” получено. В таком случае, SSL-прокси, расположенный в любой точке сети, действует следующим образом: TCP-сессии, в рамках которых клиенты пытаются установить TLS-соединение с тем или иным сервисом, заводятся прокси на собственный внутренний сервер; этот сервер устанавливает TLS-соединение с клиентом, обращаясь, в нужный момент, за подписью к API “Имярек”; с точки зрения клиента – TLS-соединение выглядит неотличимым от прямого соединения с “Имярек”. Для перехвата не потребовалось иметь секретный ключ, не потребовалось размещать на клиенте специальный сертификат. Однако, потребовалось прямое участие “Имярек” в процессе: эта компания должна предоставить API, позволяющий работать перехватывающим узлам. (В данной схеме есть ещё отдельная задача по трансляции трафика между клиентом и сервером после перехвата. Так, если это HTTPS, то его можно транслировать в HTTP и передавать в открытом виде – но потребуется поддержка HTTP сервисом, что, вообще говоря, неверно. Перехватывающий узел также может установить собственную TLS-сессию с сервером и транслировать клиентский трафик через неё. Но детали – оставим за рамками этой записки.)
Трафик TLS-сессии защищается сеансовым ключом. Если на перехватывающем узле не требуется полное управление установлением соединения, а нужна только возможность доступа к трафику, то такой прокси может просто получать текущий сеансовый ключ (и, строго говоря, криптографический контекст) с TLS-сервера. В TLS даже существует стандартный механизм маркирования сессий при помощи уникального идентификатора, который передаётся в открытом виде. Сценарий: SSL-прокси начинает записывать трафик, обнаружив TLS-соединение; параллельно отправляется запрос в API сервиса, трафик которого требуется прочитать, – запрос содержит уникальный идентификатор сессии (он передаётся при установлении соединения в открытом виде); в ответ сервис присылает сеансовый ключ и начальное состояние сеанса, если оно требуется. В результате проксирующий узел может пассивно просматривать трафик. Секретный серверный ключ от сертификата не потребовался, специальный сертификат – тоже. Но, опять же, необходимо участие провайдера сервиса. Последний, впрочем, во всех случаях сохраняет контроль над секретным серверным ключом, а предоставление API для получения подписей – не является большой технической проблемой. Ключевой момент: так как провайдер сервиса добровольно участвует в работе системы перехвата, оба описанных метода не нарушают никаких регламентов и требований инфраструктуры TLS глобальной Сети.
Если договориться с провайдером сервиса не удаётся, то возможен другой вариант: участие хорошо известного удостоверяющего центра (УЦ). “Хорошо известного” – в том смысле, что признаваемого браузерами (в случае с HTTPS). Схема с выпуском перехватывающих промежуточных сертификатов – тоже хорошо известна, некоторые УЦ на этой схеме даже попадались. SSL-прокси может взаимодействовать с УЦ следующим образом. Прокси перехватывает TLS-соединение в момент установления, после чего отправляет на специальный API УЦ запрос с сетевым именем, к которому обращается клиент. УЦ известен секретный ключ, который прокси использует при перехвате. УЦ в режиме онлайн выпускает “короткоживущий” сертификат (например, валидный в течение суток) для ключа прокси и требуемого сетевого имени. Этот сертификат возвращается в качестве ответа API. Далее SSL-прокси использует его для подмены и, таким образом, выдаёт себя за узел, с которым пытался соединиться клиент. Выпуск сертификата занимает короткое время, при этом секретные ключи, необходимые для выпуска сертификатов, не покидают пределов информационных систем УЦ. При таком перехвате поломается заметное число приложений, использующих TLS, в частности, браузеры, поддерживающие Key Pinning, будут выдавать предупреждение системы безопасности – так как используемый прокси ключ не соответствует серверному.
В описанной выше схеме потребовался выпуск сертификата, потребовалось участие УЦ, зато не требуется согласия провайдера сервиса, соединения в направлении которого перехватываются, также не требуется устанавливать дополнительный сертификат на клиенте – там уже есть нужный сертификат УЦ. Основная проблема: предоставление подобного API (которое легко маскируется под обычный партнёрский интерфейс УЦ) прямо нарушает регламенты и требования, поэтому представляет собой угрозу для бизнеса УЦ. (Занятно, что в сентябре 2015 года УЦ Symantec оказался пойман на выпуске большого числа короткоживущих “тестовых сертификатов” для доменов, администраторы которых сертификатов не заказывали. Возник даже некоторый скандал.)
Итак, схем перехвата TLS – много. Некоторые из них изящны, не требуют взлома шифров, внедрения вредоносного ПО или “вредоносных” сертификатов на стороне клиента. TLS лишь пытается решить задачи по защите информации, но, как и прежде, большой ошибкой будет считать, что TLS что-то гарантирует, в том числе, и в плане аутентификации узла, с которым клиент установил соединение.
(Напомню, кстати, что я поддерживаю специальный ресурс, детально описывающий технические подробности TLS.)
Комментарии (1) »
В продолжение заметки про сеансовые ключи TLS, генерируемые по протоколу Диффи-Хеллмана (DH). Этот протокол, в классическом случае, работает на “обычной” конечной группе (современный вариант использует группу точек эллиптической кривой – см. ниже). Группа DH задаётся единственным числом – модулем. Это обязательно большое простое число. На практике веб-серверы так настроены, что используют ту или иную типовую группу (или типовой модуль, что эквивалентно). Модуль не является секретным. То есть, известна группа, используемая большинством веб-серверов, поддерживающих DH (для Рунета это более 60% веб-серверов). Эта группа является 1024-битной, что не так много.
Вся практическая полезность DH строится на сложности задачи дискретного логарифмирования (отыскания по известным A,G такого e, что A = G^e). Так вот, один из моментов, на который обратили внимание авторы атаки на TLS Logjam, состоит в том, что если у вас много ресурсов, то, в теории, для 1024-битной группы можно уже сейчас предвычислить её арифметические структуры, потратив пару лет работы суперкомпьютера и сохранив результаты в специальных таблицах. После этого вычислять дискретный логарифм можно достаточно быстро (за часы, а возможно, даже в режиме онлайн), особенно, если вы используете специальную многопроцессорную систему. Это означает, что можно расшифровать записанный ранее трафик TLS-сессий (а также других протоколов, использующих DH). Дело в том, что сеансовый ключ, если вы умеете отыскивать дискретный логарифм, элементарно вычисляется из ключа DH, который передаётся в открытом виде. Предвычислить нужную структуру можно только для известной группы, поэтому важно, чтобы TLS-серверы использовали типовые параметры. При этом, для тех, у кого ресурсов мало (кто не является специализированным агентством, например), группа остаётся вполне стойкой.
Лирическое отступление: как упоминалось выше, есть современная разновидность DH, работающая на группе точек эллиптической кривой – ECDH. Этот протокол также распространён в современных реализациях TLS. Из-за особенностей групповой операции на эллиптической кривой, отыскание дискретного логарифма в такой группе сложнее, поэтому, во-первых, можно использовать более короткие ключи, и, во-вторых, использовать общую кривую. На практике самый распространённый случай – кривая secp256r1, предлагающая 256 бит. Естественно, на ум сразу приходят теории о том, что АНБ известна пара-тройка секретных теорем, которые позволяют резко уменьшить вычислительную сложность дискретного логарифмирования на кривой secp256r1 (которая, кстати, в АНБ и сконструирована).
Самое занятное, что если группу классического DH в TLS легко поменять – модуль и генератор передаются в сообщении сервера и могут быть любыми, – то для эллиптических кривых всё сильно сложнее: параметры здесь фиксированы заранее, клиент и сервер могут договориться только о самой кривой, выбрав её из ограниченного списка. Для эллиптической криптографии уже находили эффективные оптимизации: например, существуют так называемые суперсингулярные кривые, на которых дискретное логарифмирование оказывается разрешимым на практике. (Поэтому данный тип кривых нельзя применять в качестве основы для “классического” ECDH или алгебраически родственной криптосистемы ECDSA; что, кстати, не означает неприменимость этих кривых в криптографии вообще – предложены алгоритмы электронной подписи, использующие именно суперсингулярные кривые, но это другая история.) В общем, если вы умеете “логарифмировать” на эллиптической кривой, то ECDH точно также теряет надёжность, а памяти для хранения оптимизации, вполне возможно, требуется меньше (из-за меньшей разрядности группы).
Комментарии (6) »
В рамках поддержки перспективного направления, я добавил на dxdt.ru поддержку криптосистемы ECDSA – это электронная подпись, использующая эллиптические кривые (в отличие от RSA). Для того, чтобы браузер мог использовать ECDSA, кроме поддержки браузером требуется специальный SSL-сертификат, выпущенный с подписью ECDSA. То есть, “традиционный” сертификат – не годится, так как он использует подпись RSA и, соответственно, в его составе опубликован ключ RSA, что, понятно, не позволяет применить ECDSA. (Кстати, не стоит путать ECDSA и DSA – сертификаты, использующие последнюю, в сети не встречаются, кроме редчайщих тестовых, а сама эта криптосистема признана невостребованной и вытесняется из браузеров.)
Итак, требуется сертификат, поддерживающий ECDSA – оказывается, пока что мало кто такие предлагает, хотя сертификаты удостоверяющих центров с ECC (криптографией на эллиптических кривых) есть. Я воспользовался Namecheap.com, где обнаружились относительно недорогие сертификаты Comodo PositiveSSL, для которых поддерживается ECC. Чтобы получить сертификат с ECDSA – нужно подготовить соответствующие ключи и соответствующий CSR (запрос на выпуск сертификата). Типовые CSR для RSA – не годятся: отправка такого CSR приведёт к тому, что вам выпустят RSA-сертификат. Сделать правильно можно силами OpenSSL:
$ openssl ecparam -name prime256v1 -genkey -out ec-prime256v1-private.pem
– генерирует ключ (секретный). Для ключа нужно выбрать кривую (криптосистемы используют различные кривые, из типовых наборов). Я выбрал кривую под названием prime256v1. Конечно, правильный выбор кривой – весьма важный шаг, известно, что “не все кривые одинаково полезны”. Но нужно учитывать и другие факторы: доступность кривой в сборке серверного ПО, фактические требования по защите информации. А также приходится учитывать невероятную путаницу, которая сложилась вокруг эллиптических кривых, используемых в практической криптографии. Например, prime256v1, как её называет OpenSSL, также известна как NIST P-256, кривая, рекомендованная для использования в информационных системах штатовских государственных структур – с некоторых пор, не лучший выбор. В общем, про кривые я как-нибудь напишу отдельно. Пока что на dxdt.ru используется prime256v1. Это “256-битная” кривая, что соответствет текущим представлениям об обеспечении достаточной секретности. (Естественно, ключ лучше защитить паролем.)
$ openssl req -new -key ec-prime256v1-private.pem -sha256 -out req.pem
– выводит CSR в req.pem (запрос на выпуск сертификата – этот файл нужно переслать в удостоверяющий центр). Здесь используется сгенерированный прошлой командой ключ, а также указана хеш-функция, требуемая для электронной подписи. Так как у нас “256-битная” кривая, то использовать хеш-функцию большей “размерности” смысла нет.
Полученный сертификат я сейчас установил на сервер параллельно с RSA-сертификатом, который был раньше. То есть, браузеры (или боты), которые не поддерживают ECDSA – смогут установить соединение с RSA. Сервер может отличить таких клиентов на основе списка шифронаборов, который они передают в начальной стадии соединения. Думаю, что какое-то время RSA-сертификат будет присутствовать (у меня в запасе есть бесплатный от WoSign).
Надо заметить, что dxdt.ru таким образом оказывается в числе редких сайтов, поддерживающих современные ECDSA-сертификаты. В Рунете, впрочем, таких сайтов около 7,5 тыс. (уточнение 01/08/15: это уникальных сертификатов для Рунета около 7,5 тыс.), но это сайты, использующие сервис CloudFlare, который активно продвигает ECC и автоматически подключает своим клиентам TLS (даже если их сайты не умеют поддерживать HTTPS). Отдельных веб-узлов, не CloudFlare, отдающих валидные ECDSA-сертификаты – в Рунете пока практически нет.
Комментарии (2) »
В свете недавно выявленной уязвимости TLS – Logjam возник интерес к отличиям различных версий и реализаций алгоритма Диффи-Хеллмана. Вообще, современное состояние дел с криптографией в Интернете таково, что вместо небольшого набора простых и понятных протоколов, используется огромная куча спецификаций, в которых, по историческим причинам, наворочено много разных тонкостей. Одна из таких тонкостей – отличие шифронаборов, содержащих в своём обозначении DH, от шифронаборов с DHE (добавлен суффикс E).
DH – обозначает Диффи-Хеллмана. E – Ephemeral (почему-то сейчас в переводе используют “эфемерный”, хотя лучше подошло бы “краткосрочный” или “единовременный”). Обычно пишут, что вариант DH – не обладает прогрессивной секретностью (то есть, записанный ранее трафик можно раскрыть через какое-то время, если удалось получить секретный ключ сервера), а DHE – обладает. В чём же различия?
Вспомним, что алгоритм Диффи-Хеллмана использует следующие общие параметры: P – модуль (большое простое число, задающее группу, в которой производятся вычисления – (mod P), дальше это обозначение опускаю); G – “генератор” (число, элемент выбранной группы). Это публичные параметры. Условный “открытый ключ” сервера образуется при помощи вычисления A = G^a, где a – секретная часть ключа (экспонента). Клиент выбирает своё значение b, вычисляет B = G^b и передаёт на сервер. Для получения общего секрета сервер и клиент вычисляют, соответственно, s = B^a = (G^b)^a = G^(ba) и s = A^b = (G^a)^b = G^(ab). Обратите внимание на параметры со стороны сервера: P,G,A.
В случае реализации DH предполагается, что параметры сервера (P,G,A) – заранее подписаны неким внешним ключом, что позволяет клиенту проверить их подлинность. Это означает, что параметры фиксированы от сессии к сессии, а сервер может использовать только одну экспоненту (a), которая соответствует G^a = A. Самое важное, что фиксируется именно экспонента a – сервер должен её сохранять в долговременной памяти, так как она связана с открытой частью ключа A. Есть старые рекомендации, предписывающие включать параметры DH в состав сертификата. Впрочем, на практике такие вещи не встречаются. Понятно, что если секретные ключи сервера, а именно – значение a, оказались раскрыты, то они позволят вычислить сеансовые ключи (s) для всех записанных сессий, так как теперь аналитику известна величина a и он может определить s = B^a = G^(ab) (значение B – сохранено в записи трафика, так как его в открытом виде передаёт клиент). Очевидно, что точно так же можно раскрыть трафик, если аналитику известен секретный параметр на стороне клиента (b) – например, этот параметр утёк из браузера.
Итак, основная особенность: в случае DH – заранее предполагается, что секретный параметр алгоритма Диффи-Хеллмана сохранён на диске и может быть доступен третьим лицам. Дело в том, что само по себе использование одинакового параметра для разных сессий никак не гарантирует его раскрытия.
В случае DHE – как минимум a и G^a = A – генерируются сервером заново для каждой сессии, и, как считается, значения не сохраняются на долгое время. А для того, чтобы клиент мог провести аутентификацию параметров, они подписываются ключом сервера (тот же ключ используется в SSL-сертификате). Это нормальный современный вариант использования алгоритма Диффи-Хеллмана в TLS.
Но здесь есть хитрость, про которую почему-то редко упоминают. Хитрость в том, что математически обе схемы (DH и DHE) не отличаются. Различается лишь реализация управления секретом на сервере – в случае DH он обязательно сохраняется, так как строго определён для всех сессий, а в случае с DHE – сохраняться секрет не должен. Но если вдруг секретный сессионный параметр DHE как-то записывается, например, в дампе внутреннего трафика, или в “снапшоте” памяти сервера, или – благодаря особой утечке, связанной с ошибкой в программном коде, то никакой “прогрессивной секретности” уже не получится: DHE становится равен DH, а записанный ранее трафик можно расшифровать.
Комментарии (1) »
В продолжение истории об уязвимости в протоколе TLS, получившей название Logjam. Использование уязвимости базируется на нестойких параметрах алгоритма Диффи-Хеллмана – малого модуля, длиной в 512 бит (так называемый “экспортный вариант” параметров алгоритма). Для того, чтобы успешно применить эту уязвимость в реальности, требуется совпадение нескольких факторов:
1) атакующий должен иметь возможность активно перехватывать TLS-соединение. То есть, между клиентом и сервером должен находиться активный перехватывающий узел, не просто умеющий делать DPI, но работающий с весьма сложной логикой: нужно находить в TCP-трафике сообщения TLS, декодировать их, “завешивать” сессии, подменять информацию в пакетах;
2) атакующий должен уметь быстро, максимум – за какие-то минуты, а скорее – за десятки секунд, решать задачу дискретного логарифмирования для 512-битного модуля; несмотря на то, что 512 бит это, по нынешним меркам, мало, задача всё равно остаётся сложной, для ускорения потребуется многопроцессорный сервер или кластер (лучше – специализированный) с большим быстрым дисковым массивом, нужным для хранения предварительно вычисленных таблиц со структурой группы, соответствующей заданному модулю. У перехватывающего узла должен быть онлайн-доступ к серверу логарифмирования – потому что этому узлу требуется вычислять секрет, чтобы перехватить сессию;
3) атакуемый TLS-сервер должен поддерживать заведомо устаревшие “экспортные параметры” алгоритма Диффи-Хеллмана.
Да, “сильные игроки” могут себе позволить первый и второй пункт. Но так как эти пункты затратные, наверняка там очередь заявок стоит, то использовать их имеет смысл только против “важных целей”. И тут возникает некоторое несоответствие: почему интересующий специальное агентство сервер должен находиться под столь неумелым администрированием, что на нём используют “экспортные параметры”? Мало-мальски ценные сервисы, которые думают о безопасности, – они давным давно отказались от “экспортных параметров”. Про то, что это проблемная конфигурация, известно много лет. Поэтому добротно настроенные системы, которыми должны бы пользоваться “важные цели”, применяют современные параметры. Соответственно – против них указанная уязвимость заведомо не сработает (ведь даже сервисы Google попадают здесь в категорию безопасных).
Что, конечно, не отменяет пользы от привлечения внимания к дефекту протокола. Есть шанс, что в TLS 1.3 что-то поправят (вероятно, добавив новых дефектов, так как в сторону упрощения спецификация пока что идёт с большим трудом).
Комментарии (1) »
Новый