Как понять, что факторизация числа 15 не может ничего говорить о реализации квантового алгоритма Шора? Понять это несложно: один из делителей числа 15 должен быть меньше 4 (потому что 4^2 == 16), единица не рассматривается по условиям задачи, и это не 2 (потому что только нечётные подходят). Так что любой процесс поиска, каким бы аналоговым он ни был, если вообще сходится, то неизбежно попадёт в 3, что и будет верным ответом.

Заметьте, что ещё и 5 = 3 + 2, а простых чисел, меньших 15, только шесть: поэтому, учитывая, что умножение здесь коммутативно (это очень важно для квантовых алгоритмов), число 2 отбрасывается, а схема поиска расщепляется на пары, то, в самом худшем случае, вероятность, что аналоговый аппарат, состояния которого переключаются по возможным узлам дерева, промахнётся – меньше трети. (На практике, ещё раз, для промахов там просто нет места.)



Комментировать »

Минутка специфического интернет-технологического юмора:

A (печатая в консоли, случайно склеивает два IP-адреса, вот так: 192.168.11.12192.168.12.11.).
B (наблюдая за процессом, пишет в чат): Это был адрес в формате IPv010.
A: Почему десять?
B: Потому что два IPv4 склеились – то есть, четыре плюс четыре.
A: Тогда должно быть IP-8.
B: Вот я и пишу: IPv010.



Комментарии (1) »

Продемонстрировано извлечение данных, раскрывающих секретный ключ ECDSA, из аппаратных токенов YubiKey при помощи ПЭМИН (то есть, побочных электромагнитных излучений и наводок). Используется утечка информации о внутреннем состоянии микроконтроллера при выполнении математических операций (алгоритм Евклида при вычислении обратного элемента, которое необходимо в ECDSA). По ссылке выше – очень большое описание, потому что атака сложная, требуется достаточно хитрая аппаратура и нужен не просто физический доступ, но необходимо разобрать токен. (via)

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

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

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



Комментировать »

Недавняя записка про оптимизацию циклов и микроконтроллеры иллюстрирует весьма важный момент, связанный с пониманием алгоритмов, записи алгоритмов и реализаций этих алгоритмов. Не менее рельефный пример в этом же направлении касается базовых логических операций и понимания записи формул. Речь про вопрос из области логики, логических выражений: является ли P и ¬¬P – одним и тем же? Даже разработчики-программисты нередко говорят, что “да, является”.

Знак “¬” – это логическое отрицание, проще говоря – “не”, или “!”, как будет во многих привычных языках. То есть, казалось бы, тут, во второй части, написано, что “не-не-P”, а тогда, если P имеет значение TRUE, то “не-не-P” тоже TRUE; то же верно и для P == FALSE. Понятное двойное отрицание, поэтому, что P, что ¬¬P – разницы нет: одно и то же. Это, впрочем, не совсем так.

Использование дополнительной “закорючки” (“¬”) позволило реализовать два способа записи, которые точно отличаются. Как способ записи, как “формула”, “P” и “¬¬P” – сильно разные вещи. Посудите сами: во втором случае на два “знака-закорючки” больше; кроме того – для выполнения “сокращения” нужно ввести дополнительное правило, по которому двойное отрицание вообще схлопывается, а чтобы это правило сработало, потребуется его внести “в набор допустимых операций” и применить, то есть, продумать и оптимизировать, даже если не сравнивать именно две записи. Так что “¬¬P” приносит с собой много разного, отсутствующего в “P”.

Понятно, что тут очень многие соглашения вынесены за скобки, но, тем не менее, это хороший пример базовых свойств процесса оптимизации. Да, компилятор мог бы заменить ¬¬P на P. Почти что то же самое компилятор и проделывает, когда заменяет запись цикла, тело которого не вносит изменений в результаты работы фрагмента кода, на простое присваивание:

b = 14; 
for(a = 0; a < 8; a++){ 
 b = b + a;
} 

заменяется на эквивалентное

b = 42;

(или это не эквивалентная замена?)

Вообще, запись алгоритма, содержащая определение цикла, описывает повтор неких операторов/команд, но не определяет, как этот повтор должен реализовываться на оборудовании. В принципе, тело цикла можно прямо выписать в качестве повторений команд, это известный приём оптимизации, он так и называется - "развернуть циклы". Очень часто, будучи применённым к программе на языке высокого уровня (ЯВУ), приём даёт заметный прирост производительности. Почему? Потому что исчезли накладные вычислительные расходы. При обычной обработке представления цикла на ЯВУ - появляются необходимые машинные команды, соответствующие "записи" цикла, а процессор вынужден их исполнять. Команд может оказаться неожиданно много: например, потребуется сложная обвязка для реализации обработки переменной цикла.

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



Комментировать »

Постквантовые криптосистемы из рекомендованных NIST используют большие по количеству байтов ключи и значения подписей. Это особенно заметно, если сравнивать с привычными “классическими” криптосистемами на эллиптических кривых: постквантовые схемы требуют в сотню раз больше байтов; требования для разных криптосистем и разных сочетаний параметров различаются, но, тем не менее, это буквально рост на пару десятичных порядков: так, подпись в “минимальном” варианте SLH-DSA записывается в 7856 байтов, сравните с 64 байтами ECDSA/P-256, например; другие наборы параметров SLH-DSA требуют для подписи по 16 килобайтов и более, у ML-DSA – поменьше. Такой рост объёмов передаваемых данных составляет заметную проблему для практики TLS.

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

Уровни, – начиная с базового, с TLS-записей, – выстраиваются следующим образом:
1) TLS-записи;
2) TLS-сообщения;
3) блоки данных внутри TLS-сообщений.

Блоки данных формируют TLS-сообщения, которые передаются в TLS-записях. Здесь на каждом уровне в заголовке присутствует поле с записью длины, то есть, резкое увеличение длины подействует на всех уровнях. Одно из радикальных проявлений – на уровне TLS-записей. В TLS-записи вкладывается весь TLS-трафик. Заголовок TLS-записи содержит: один байт, обозначающий тип записи; два байта, в которых записывается номер версии протокола; два байта, кодирующих длину данных. При этом максимальная длина ограничена спецификацией отдельно, и для TLS 1.3 составляет 16384 + 256 == 16640 байтов (октетов, в более строгой, “сетевой” терминологии).

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

Занятно, что сейчас TLS-сертификаты для веба, то есть, для использования в распространённых веб-браузерах, требуют наличия так называемых SCT-меток, подтверждающих, что тот или иной доверенный лог Certificate Transparency видел соответствующий (пре)сертификат. Такое подтверждение, как нетрудно догадаться, реализуется с помощью электронной подписи. В случае постквантовых криптосистем, подписи SCT-меток тоже должны разрастись в объёмах. То есть, если оставить архитектуру такой, какая она есть, то TLS-сертификаты станут весить килобайт пятьдесят каждый. Не очень-то удобно.

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

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

Естественно, большое количество дополнительных байтов потребуют и схемы согласования симметричных ключей с постквантовой стойкостью (ML-KEM, в терминах NIST). Из-за этих схем увеличивается объём начальных сообщений TLS. Тут уже можно вспомнить и про TCP, так как влияние TCP-параметров имеет наибольшее значение именно на начальном этапе TLS-соединения: существенное раздутие ClientHello/ServerHello приводит к тому, что сообщения вылезают за привычные границы TCP-сегмента.

Является ли большой объём данных, требуемый для записи параметров современных постквантовых криптосистем, необходимым условием достижения постквантовой стойкости? Вряд ли. Даже в упомянутых выше криптосистемах использование большого количества байтов диктуется не столько желанием “увеличить пространство перебора”, сколько требованиями по оптимизации вычислений, которые всё же должны выполняться за какое-то разумное время. Текущие параметры нередко всё равно разворачиваются из, например, 256-битного вектора инициализации. С другой стороны, квантовых компьютеров пока нет, а постквантовая стойкость тут всё ещё определяется относительно одного конкретного квантового алгоритма – алгоритма Шора, – так что для взлома предложенных постквантовых криптосистем могут придумать новые, не менее квантовые, алгоритмы, и большое количество байтов, требуемое для записи ключа или значения подписи, не поможет, так или иначе: не факт, что универсальная постквантовая стойкость вообще возможна – в континуум одинаково легко проваливается и 16 килобайт, и 16^16 килобайт, и даже соответствующие факториалы.



Комментировать »

Letter AНемного технических деталей про протокол Диффи-Хеллмана в практике интернет-коммуникаций, почему ключи остаются в трафике, и немного про симметричные шифры.

Протокол Диффи-Хеллмана (DH) подразумевает, что каждая из сторон вычисляет свой секрет, потом на основе этого секрета вычисляет собственный открытый параметр (назовём пару этих параметров A и B), передаваемый по открытому же каналу. После того, как сторонам удалось обменяться открытыми параметрами, они могут определить уже общий симметричный секрет, на основе которого вычисляется секретный ключ (чаще – ключи) для симметричного шифра. Так вот, каждый из параметров A и B содержит полную информацию, необходимую для вычисления общего секрета (пояснение, 31/08/24: речь тут про вычисление по записи трафика DH). Это так по определению протокола, иначе сторонам не удалось бы получить одинаковый секрет. Другое дело, что извлечь эту информацию, исходя из известных алгоритмов, вычислительно трудно (но возможно). В частности, не было бы предмета для постквантовой криптографии, если бы ключи “классических” реализаций DH не восстанавливались бы полностью из записи трафика. Так что ключ есть в трафике, а не “только на клиенте”. Это всё известно специалистам, а DH в криптографии и не позиционируется как “ключ только на клиенте”, чтобы это ни значило.

Заметьте, что на практике, если конкретная реализация криптосистемы уязвима, то открытые параметры DH (A, B) могут предоставлять информацию о том, как оптимизировать поиск нужного секрета – это обычный приём. “Обратной задачей DH” называют задачу определения исходного секрета по открытому параметру (А или B). Однако вовсе не обязательно уметь решать обратную задачу быстро и универсальным образом. Можно ограничиться прямой задачей: при знании исходного пользовательского секрета решение этой задачи – быстрое по определению, это важный математический момент; специально подобранные параметры и/или дефектный датчик случайных чисел могут свести перебор к минимуму, если атакующей стороне известен другой секрет или параметр, который задаёт бэкдор (намеренно созданную уязвимость). Соответственно, оптимизированный перебор проводится до тех пор, пока подбираемое значение не совпадёт с перехваченным открытым параметром – в этом полезная роль этого параметра, так как подбирать ключ симметричного шифра, обычно, посложнее.

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



Комментировать »

Массовый централизованный сервис для обмена сообщениями должен обеспечить собственную надёжность и иметь возможности по восстановлению. Уже эти моменты гарантируют, что с пользовательскими сообщениями, сохраняемыми внутри сервиса, ситуация будет не самой прямолинейной, поэтому рассуждать об удалении переписки по команде пользователя – несколько странно. Посмотрим подробнее на разные особенности “хранения сообщений”.

Так, сообщения сохраняются в какой-то, условно, “базе данных”, потому что речь про централизованный сервис. База может быть распределённой или нет, это тут не особенно важно, потому что “распределение” всё равно происходит внутри единого сервиса (по условию задачи). Работа с базой данных может быть реализована при помощи той или иной распространённой СУБД, либо каким-то собственным решением; да, от хорошо спроектированного сервиса – можно было бы ожидать собственного специализированного решения. Однако тип решения для управления базой данных тут тоже не важен, поскольку так или иначе должны быть и “холодные” резервные копии, и реплики, работающие онлайн, последние, как минимум, необходимы для балансировки между дата-центрами и для обработки локальных отказов. И резервная копия, и реплика – содержат сообщения пользователей в некоторых файлах, выгружаемых на “диски” (то есть, в систему хранения данных). Если эти файлы куда-то утекают, то, понятно, из них можно восстановить сообщения. Кто-то сделал дамп дисков системы хранения данных (или, условно говоря, просто вынул пару дисков и унёс, потому что “так можно было”)? У этого “кого-то” теперь есть все сообщения.

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

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

Другой, менее очевидный, вариант: разнообразные логи – общие системные, а также логи конкретных программных сервисов. В лог-файлы записывается самая разнообразная информация. Там могут быть и пароли пользователей, в том числе, в открытом виде (известная история из практики Facebook); могут быть ключи/пароли, защищающие резервные копии; могут быть реквизиты доступа к базам данных и много всего другого, вплоть до самих текстов сообщений, передаваемых мессенджером. Логи (лог-файлы) передаются через вычислительную сеть – это самое обычное дело: в “операционной практике” принято логи собирать на центральных лог-коллекторах, которые являются отдельными физическими серверами. Более того, типовая практика подразумевает использование логов в системах обнаружения вторжений (или “обнаружения утечек/угроз”, SIEM и т.д., и т.п., там море аббревиатур и терминов, так что называть можно по-разному, но часто наличие такой системы – ни много ни мало, а строгое требование политики ИБ). А чтобы логи так использовать, их нужно скопировать в соответствующую систему. Понятно, что делаются и резервные копии логов, а сами лог-записи, – возможно, превращённые в какие-то типовые “сообщения о событиях”, – записываются в ту или иную дополнительную БД (“от SIEM в SOC”). У этой БД есть реплика, резервные копии, ну и так далее.

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

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

А ещё есть контейнеризация (читай – разные воплощения Docker). Контейнеры – это программно-обособленные копии системного и прикладного окружения. Контейнеры, как и снапшоты виртуальных машин, могут попадать в резервные копии, передаваться между серверами, и так далее, и тому подобное. Естественно, внутри контейнера легко могут оказаться (и оказываются) самые критически важные данные и ключи доступа.

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

Вернёмся к обсуждению сервисов, реализующих “мессенджеры”. Архитектурной особенностью центрального (централизованного) сервиса обмена сообщениями является то, что все точки “копирования сообщений” будут сосредоточены в небольшом количестве “сетевых локаций”. Для действительно распределённой P2P-системы это было бы не так. В теории, даже в центрально сервисе, если пользовательские сообщения, передаваемые сервисом, зашифрованы на стороне клиента без доступа сервера к ключу, то во всех упомянутых выше случаях внутри копий на стороне сервиса окажутся только зашифрованные “блобы”. Проблема в том, что такой идеальный подход на практике реализован далеко не всегда, даже если заявлен и предусмотрен. Это происходит из-за наличия ошибок и административных “особенностей” (как минимум, тут всегда остаются открытыми метаданные, а ключи – могут и утечь). Если же ключи как-то на сторону сервиса передаются, то эти ключи там могут быть сохранены, в том числе, в результате “побочных процессов”, например, в момент миграции конкретного экземпляра ПО сервиса на другую аппаратуру.



Комментировать »

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

Дело в том, что начальное сообщение, отправляемое клиентом, – ClientHello, – содержит много параметров и, соответственно, имеет структуру, которой хватает для эффективного построения отпечатков. Например, весьма подробное представление о том, как такой классификатор действует, можно составить, если внимательно посмотреть на выдачу моего тестового сервера TLS 1.3. Посмотреть можно непосредственно веб-браузером. При успешном соединении сервер вернёт страницу, где в подробностях показано то самое CLientHello, которое сервер получил от клиента. Вы можете подключиться браузером, обновить страницу несколько раз и увидеть, какие блоки данных не изменяются и, поэтому, служат основой для построения сигнатур.

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

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

Эта же идея важна и для разбора самого сообщения ClientHello, где она позволяет анализировать структуру следующего уровня, так как ClientHello вложено в TLS-запись. А состоит идея в том, что значения байтов, кодирующих предполагаемую длину, интерпретируются как смещение; полученное значение прибавляется к текущему адресу (в предварительно собранном потоке байтов) и значения байтов по вычисленному адресу сравниваются с ожидаемыми значениями, которые там оказались бы, если это действительно анализируется ClientHello. И если TLS-записи тут не добавляют много нового (они просто следуют одна за одной), то в ClientHello появляются вложенные поля данных (расширения) и более богатая структура, которая, тем не менее, устроена точно так же: значения байтов, интерпретируемые как целое число, задающее длину, должны строго сходиться, когда рассматриваются в виде цепочки. Заметьте, что до разбора самих значений полей данных дело ещё даже не дошло. Это важная особенность TLS: данный протокол не обладает скрытностью. Скрытный протокол выглядел бы случайным набором байтов со случайными же значениями. TLS, – особенно, на начальном этапе соединения, – выглядит как связанная строгими параметрами длины и типов байтовая структура (так, впрочем, и должно быть).

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

Итак, вернёмся к ClientHello. Помимо верхнеуровневой структуры из вложенных блоков, есть и содержание этих блоков. Например, сообщение ClientHello, в самом начале, после указания версии, полей Random и SessionID, содержит перечень шифронаборов, которые поддерживает клиент. (Это всё хорошо видно в выдаче тестового сервера.) Сокращённый пример: 0x1301, 0x1303, 0x1302, 0xC02B, 0xC02F… На уровне потока данных это всё просто последовательные значения байтов, по два байта на каждый идентификатор шифронабора (понятно, что данному блоку предшествуют байты с записью длины, что добавляет “узнаваемости”).

Так, для конкретной версии браузера перечень шифронаборов – узнаваем. В принципе, ничто не мешает клиенту менять состав и порядок пар байтов, обозначающих шифронаборы, но, например, Firefox передаёт фиксированный набор. Понятно, что строгая последовательность из 36 байтов – это уже достаточный идентифицирующий признак. (36 байтов получается так: 17 идентификаторов шифронаборов от Firefox, по два байта каждый, плюс два байта на запись длины.) Чуть более подробный пример, начальная часть ClientHello TLS 1.3:

 Type (тип сообщения, 0x01, один байт - подходит для сигнатуры);
 Len (длина сообщения, три байта - подходит для сигнатуры: должно соответствовать общей структуре);
 Version (версия, 0x0303, два байта - подходит для сигнатуры);
 Random ([...], 32 "случайных" байта - не подходит для сигнатуры);
 SessionID_Len (длина данных Session_ID, один байт, для TLS 1.3 - подходит для сигнатуры);
 SessionID (обычно, для TLS 1.3 от браузера тут будет 32 байта - не подходит для сигнатуры).
 CS_Len (длина данных списка шифронаборов, два байта - подходит для сигнатуры);
 CS (список двухбайтовых идентификаторов шифронаборов - подходит для сигнатуры).
 [...]

При этом, скажем, браузер Chromium/Chrome добавляет к списку шифронаборов так называемые значения GREASE (для тестирования реализаций TLS), которые меняются от сеанса к сеансу. Но значения GRASE имеют строго определённый формат, так что их несложно распознать автоматом. Если взять такой клиент, как cURL, то состав ClientHello будет другим, в частности, другим будет список шифронаборов. Более того, по составу ClientHello нередко можно определить даже используемую библиотеку, реализующую TLS.

Естественно, не только шифронаборы подходят для построения сигнатуры. В ClientHello современных браузеров присутствует разнообразный набор расширений – это дописываемые в сообщение поля со своей структурой: они содержат заголовок с записью длины, дополнительные блоки внутри. Для TLS 1.3 расширения имеют определяющее значение. Внутри расширений передаются различные необходимые параметры, в частности, открытая часть протокола Диффи-Хеллмана и открытый ключ постквантовой криптосистемы X25519Kyber768. По составу и количеству расширений можно построить дополнительную сигнатуру. Так, уже наличие X25519Kyber768 едва ли не однозначно выдаёт современный веб-браузер. А ведь современный браузер ещё и укажет расширение ECH (Encrypted ClientHello). Firefox использует зафиксированный порядок расширений ClientHello, а браузер Chromium/Chrome – порядок следования расширений изменяет между сессиями. Однако даже в случае, когда порядок расширений разный, всё равно можно использовать перечень имеющихся расширений для построения сигнатуры.



Комментировать »

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

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

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

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

В первом случае – допустимый контекст использования ключа задаёт сертификат и, так сказать, семантика применения этого сертификата. Например, приложение может в принципе принимать TLS-сертификаты (и ключи из них) только в контексте подписывания TLS-параметров при HTTPS-доступе к веб-серверу, и всё. Естественно, в сертификате предусмотрены дополнительные флаги и параметры, определяющие допустимые способы использования ключа. Их приложение тоже может учитывать каким-то своим способом (но, заметьте, использование ключа для подписи – в сертификате “от сайта” должно быть разрешено и так; см. выше).

Во втором случае, когда приложение “верит в сам ключ”, сертификат служит лишь контейнером для доставки этого ключа. “Верить в сам ключ” – означает, что доверие распространяется прежде всего на конкретное значение ключа, но при этом сам сертификат из рассмотрения может и не исключаться. Например, это обычная практика для корневых ключей в TLS для веб-сайтов и браузеров.

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



Комментировать »

В продолжение записки про ИИ Google и “серебряную медаль” Международной математической олимпиады. Там исходная задача, которую потом “решает” ИИ, прежде переводится людьми на входной язык системы машинных доказательств – то есть, на некоторый формальный язык, описывающий в определённых логических формулах целевое состояние, соответствующее задаче. Это не программа, как иногда пишут, а запись, грубо говоря, теоремы, соответствующей задаче, в формулах, которые возможно (при некоторых ограничениях) доказать в данной системе. Да, доказательство выполняется при помощи компьютерных вычислений, тем не менее, формальная запись задачи-теоремы не является программой, реализующей некий алгоритм – иначе не было бы смысла в поиске записей доказательств. И вот в “популярном изложении” необходимость такого перевода обосновывают тем, что нужно “переписать на языке, понятном системе”. Это, конечно, искажение. Но с ним связаны два важных момента.

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

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

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



Комментировать »

Исследователи, сравнивая в автоматизированном режиме (fuzzing) поведение различных микропроцессоров семейства RISC-V, обнаружили дефекты команд в линейке распространённых ЦПУ T-Head C910. Дефекты относятся к конкретной реализации и расширениям RISC-V, которые могут использовать разработчики совместимой аппаратуры.

Особенно интересно выглядит команда, позволяющая реализовать прямую запись данных в физическую память (ОЗУ) по произвольному адресу, минуя не только внутренний кеш, но и вообще все аппаратные ограничения на уровне процессора. Такой “гаджет”, конечно, позволяет добиться уверенной эскалации привилегий (и не только), в том числе, из любых контейнеров и прочих систем виртуализации. В качестве примера в исходной работе приводятся линуксы и модификация системного вызова getuid() таким образом, чтобы он всегда возвращал значение 0 (это, соответственно, root в линуксах). Очевидно, от типа ОС такой результат не зависит, так как речь про произвольный и прямой доступ в память.

(Новость OpenNet.)



Комментировать »