Обновить
2K+
159
Коваленко Геннадий@Number571

Криптограф, Программист

265
Подписчики
Отправить сообщение

Но разве реальная случайность не зависит от наблюдателя?

Если не углубляться в философию наблюдателя и говорить именно что про +- реальную случайность, то в контексте криптографии - не зависит. Если случайность реальна, то и взломать или найти закономерности в ней будет теоретически невозможно / неосуществимо.

Для взломщика это скорее всего будут те самые 6-7 бит, ибо он не может восстановить внутреннее состояние таймеров. Даже если он знает алгоритм и начальный seed, он не знает, в какой момент времени были сделаны замеры (T1, T2)

Предположим, что это вообще единственная модель угроз, доступная криптоаналитику. Даже в этом случае, T1,T2 - это 64-битные числа и для правильного их нахождения потребуется потратить приблизительно 2^65 операций. Теперь примем во внимание, что сам timestamp - это не случайное число, мы чётко знаем его поведение - оно увеличивается, а некоторая его часть остаётся в основном неизменной (по типу префикса 17755... для текущего времени). Это говорит о том, что область вычислений на самом деле куда ниже 2^64. Итого, мы получаем, что даже если бы генератор был +- безопасным, он является небезопасным по выбранным параметрам - буквально уязвим к перебору при достаточных средствах злоумышленника.

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

Энтропия - это абсолютная величина, вы говорите про вычислительную сложность. Из более-менее близкого примера - это пароль и пароль проброшенный через KDF (с конфигурацией, например +2^20 вычислений). Если энтропия пароля 40-бит, то даже когда он будет проброшен через KDF, энтропия результата также будет 40-бит, но вычислительная сложность станет уже 60-бит. Энтропия - это фактически начальные условия в отрыве от какого-либо алгоритма. В вашем случае энтропией выступает timestamp, но вы решаете вычислять энтропию от результата алгоритма (который был произведён от метки времени). В этом и суть, что предоставленная вами энтропия - она ложная при любом сценарии, будь то практическом или теоретическом.

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

Точно также, как если бы мы просто запустили rand(time.Now().UnixNano()) на двух машинах - т.к., мы физическим не сможем запустить их синхронно, даже если будем использовать для этого какие-нибудь автоматизированные скрипты или программы.

И да, а вы не задумывались, что было бы если бы такой генератор построить на сверхточных часах?

Мы бы потратили много денег на аренду сверхточных часов только для того, чтобы протестировать небезопасный ГПСЧ. К тому же, если мы говорим про ГСЧ построенные на хаосе, то скорее всего результат был бы вообще противоположным - тобишь генератор стал бы ещё хуже рандомить числа.

Всё бы хорошо, если бы не было так плохо. Пробовали ли вы считать энтропию от обычного ГПСЧ, который уже встроен в любые стандартные библиотеки любого языка программирования, включая PHP? Вы бы обнаружили, что при вычислении энтропии почти любая встроенная функция рандома будет всегда стремиться к 8 битам вне зависимости от криптостойкости генератора - даже обычный линейный конгруэнтный генератор по вашей функции будет стремиться к максимальному значению. А всё по тому, что некорректно проводить тестирование качества генератора по формуле вычисления энтропии. При вычислении энтропии мы должны брать во внимание не только те байты, которые уже имеются на руках, но также и априорные вероятности того, как и за счёт чего эти байты были получены. Из-за этого реальная энтропия вычисления будет куда ниже вычисляемой по сырым байтам.

Вот как пример кода на языке Go, где я использую стандартный математический (не криптографический) ГПСЧ и получаю "энтропию" в 7.997064, хотя фактическая энтропия сводится только лишь к использованию time.Now().UnixNano() - и это вряд-ли достигнет даже пары бит.

package main

import (
	"fmt"
	"math"
	"math/rand"
	"time"
)

func entropy(b []byte) float64 {
	freq := make(map[byte]uint, 256)
	for _, v := range b {
		freq[v]++
	}
	e := .0
	total := uint(len(b))
	for _, v := range freq {
		if v > 0 {
			p := float64(v) / float64(total)
			e -= p * math.Log2(p)
		}
	}
	return e
}

func main() {
	r := rand.New(rand.NewSource(time.Now().UnixNano()))

	buf := make([]byte, 65536)
	if _, err := r.Read(buf); err != nil {
		panic(err)
	}

	fmt.Printf("Entropy: %f\n", entropy(buf))
}

Вы скорее всего не понимаете разницы между ГПСЧ и ГСЧ как таковыми - в одном случае есть точно заданный алгоритм генерации, в другом - алгоритма никакого нет. Если применяется ГПСЧ и таковой уязвим к атакам анализа, тарабарщину можно восстановить крайне просто (на примере ЛКГ):

  1. Дано: "р щвао ку гевре в 8:88"

  2. Предполагаем, что начало = "я буду"

  3. Выполняем XOR операцию: "р щвао" XOR "я буду"

  4. Получаем часть предполагаемого ключа в ГПСЧ = X

  5. Подставляем данный X в формулу: (aX + b) (mod N) = Xi

  6. Если Xi со следующими байтами шифртекста (по типу "ку гевре") даёт что-то осознанное - мы взломали шифр

  7. Если нет - делаем другое предположение (возвращаемся к шагу 2)

Если бы вы сменили ГПСЧ / КСГПСЧ на ГСЧ - всё вами описанное действительно бы работало правильно. Но если вы используете ГПСЧ - это априори вред для конечных пользователей, даже обычные граждане смогут технически взломать данную систему шифрования, не говоря уже о спецслужбах. Если вы используете КСГПСЧ - ок, но смысла теперь от ключа размером в сообщение никакого нет, потому что генерируемая гамма держится на ключе, размер которого ограничен. Легче уж в таком случае просто отдавать пользователю ключ от КСГПСЧ, а не гамму, которая была им сгенерирована. Именно что только при наличии истинного ГСЧ может быть реализован поистине шифр Вернама.

Рекомендую более подробно углубить знания в криптографии. Меня пугает, что этим продуктом мог бы кто-то в действительности воспользоваться, надеясь на мнимую безопасность.

Самый простой и элементарный вектор атаки - это обычный брутфорс 2^53 элементов (https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Math/random#примеры), что под силу почти любому государству или большой корпорации. Как только найдётся часть последовательности, которая при xor операции с шифртекстом будет выводить что-то осмысленное, это уже будет считаться взломом. С шифром Вернама, где взлом исчисляется бесконечностью, этот кандидат уж точно не вяжется.

Что касается более простых атак, то математический рандом является в основе своей линейным конгруэнтным генератором. И вот его линейность - это самый значимый недостаток.

x_{i+1} = (ax_{i}+b)\text{ }(mod\text{ }n)

Из этой формулы мы видим, что обладая числами a, b (которые зачастую являются константами) - мы можем двигаться в любом направлении - хоть назад, хоть вперёд. И так как выходной результат - это вход следующей итерации, то зная хотя бы часть ключа, мы сможем восстановить весь ключ. Что собственно также не вяжется с шифром Вернама, где ключ полностью является случайным и все его элементы равномерно и равноверятно распределены на всей последовательности. Существуют алгоритмы, которые могут восстановить последовательность и без знания (a, b).

Если вы будете считать, что "ключ же никому не будет отправляться, а если он как-то попал в руки третьей стороны, то это проблема пользователя" - то вы скорее наивны. Криптоаналитик вполне может делать предположения о шифртексте - он знает его размер, он может предположить, что в начале текста могут быть слова "Добрый день", "Привет", "Как дела?" и прочее. Из этого он уже будет получать перевес в вероятностях, которые смогут и будут помогать в раскрытии ключа этого ГПСЧ.

UPD. К тому же, по вашему скрину, - вы даже пробелы и спецсимволы не шифруете. Это рай для криптоаналитика, потому что видеть где конкретно располагаются слова и какой они длины - это уже >90% решённой задачи.

Небезопасный какой-то шифратор получился...

let key = '';
for (let i = 0; i < keySize; i++) {
  const randomChar = String.fromCharCode(
    printableStart + Math.floor(Math.random() * printableRange)
  );
  key += randomChar;
}

Здесь как минимум вместо математического генератора нужно использовать криптографический. Как максимум - настоящий ГСЧ, если предполагается, что это шифр Вернама

окей, что то похожее на битмесседж... но добавлена отправка раз в N секунд, что еще сильнее создает флуд в сети

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

не совсем понятно, как устроена доставка если пользователь которому адресовано сообщение был оффлайн ...

Раньше эту роль выполнял HLT, который сохранял N-ое количество сгенерированных сообщений, а узлы их подгружали в момент подключения к сети. В текущей реализации этот механизм был убран - возврат этой логики под вопросом. Легче создать логику на уровне прикладных сервисов, когда обмен сообщениями происходит при помощи "запрос-ответ", а процедура отправления сообщений - это их локальное сохранение в хранилище + отправка по сети.

... есть какое то подтверждение доставки или иной механизм?

Есть, существует два типа запросов - Send и Fetch. Первый отправляет сообщение без подтверждения, второй - с подтверждение (получением ответа). Если ответ при Fetch не был получен - выполняются ретраи. Логика при которой запрос был получен (обработан), а ответ - нет (из-за чего возникает ретрай), должна регулироваться уже прикладными сервисами.

не понятно что делать если ключ скомпроментирован, обычно делается основной ключ и ключ представляющий тебя в сети, <...>, а в этом проекте как?

В этом проекте существует долговременный ключ, который идентифицирует пользователя. Им шифруют сообщения, им подписываются сообщения (фактически это два ключа - ML-KEM + ML-DSA, интерпретируемые как один). Каждое сообщение шифруется одноразовым симметричным ключом, который инкапсулируется при помощи ML-KEM.

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

и смена ключа происходит безболезненно

Смена ключа при компрометации безболезненно нигде не проходит, особенно если это долговременные ключи.

Понятно. Более реалистично тогда это через личные сообщения провернуть, группы будут отлетать по бану очень быстро такие.

Недостаток в том, что будет существовать точно известная связь 1к1. Конечно можно объединить множество личных чатов в одну общую сеть, тем самым сделав 1кN сеть, но это будет отправление одинаковых сообщений по множеству чатов, что будет детектироваться как спам куда быстрее, чем писать по одному сообщению в групповой чат.

Энивэй, скорость такого взаимодействия, получается смехотворна...

Да, это факт, адаптация будет съедать и без того не быструю передачу данных.

Да и клиента, реализующего эту возможность, как я понимаю, пока не предвидится, хоть для того же ВК?

Пока есть возможность использовать другие виды связи, то не предвидится. На поддержку таких адаптеров будет уходить много времени, т.к. подобные централизованные сервисы достаточно часто могут менять алгоритмы вставки палок в колёса.

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

Конечно будет опрометчиво говорить, что такая реализация адаптера будет простой. Баны и каптчи - никто не отменял. Из-за этого адаптер должен уметь не только продьюсить/консьюмить сообщения, но и должен уметь делать трафик более невидимым и по возможности решать проблемы с банами / каптчами.

По простому - скачать бинарники из релизных версий (тут - hlc и тут - hl-client) и просто их запустить. Этого будет достаточно, HLC запустит ноду, HL-Client подключится к ней. Чтобы HLC подключился к какому-либо внешнему ретранслятору / глобальной сети - нужно запустить узел с опцией `--network oi4r9NW9Le7fKF9d`. Через графический интерфейс HL-Client'а уже можно работать со всем добром - добавлять друзей, редактировать соединения и просто общаться.

В результате, действий получается не сильно много. Безусловно больше на один-два шага, чем в любой централизованной связи, но на деле не критично. Возможно подробности работы самой сети и её изменений, описанные в статье, придали вид сложности. На деле же, на более прикладном уровне, это работает плюс-минус просто.

Но скажите - вот есть такая модель OSI. Какие уровни покрывает ваша сеть?

Если натянуть сову на глобус, то думаю можно покрыть все уровни. Вопрос только зачем и для чего. OSI - это всё же модель, более подробная, чем TCP/IP, GP/12, но если последних хватает для описания задачи, то OSI становится просто-навсего оверинжинирингом.

Дело в том, что децентрализованных сетей (разной степени анонимности) много. Разных. Но на мой взгляд, ни одна из них полноценно не достигла самого верхнего уровня - назовем его условно "пользовательским"

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

Задумка прямого P2P-соединения хороша, но в реальном мире почти неосуществима. Вы убрали из модели угроз сервера, которые могли бы хранить метаданные о вас, вашем онлайн/оффлайн статусе, переписках и прочей активности - это хорошо. Тем не менее P2P-соединение - оно не является прямым, оно проходит сквозь множество маршрутизаторов провайдеров связи, фактически тех же серверов, всё также собирающих множество метаданных. Чтобы скрыть от них активность уже недостаточно обычной установки P2P-соединения в сети Интернет. В результате, мы получаем слегка пониженный риск сбора метаданных, но основной риск в лице майора - он остаётся.

Важно, чтобы DES не был замкнутой криптосистемой. Напомню, что криптосистема называется замкнутой, если для любых трёх ключей  i, j, k существуют ключи r, s, такие что T_iT_j(x) = T_r(x), T_iT_j^{-1}T_k(x) = T_s(x)для любого сообщения x.

Что даёт условие T_iT_j^{-1}T_k(x) = T_s(x)? Кажется, что достаточным будет только условие T_iT_j(x) = T_r(x).

Команда мессенджера <...> заявила, что доступ к содержимому серверов невозможен чисто технически даже для инженеров (секретные чаты хранятся в зашифрованном виде, а ключи — на устройствах пользователей).

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

В административной команде мессенджера подчеркнули, что коммуникационный сервис Telegram всегда активно модерировал вредоносный контент на своей платформе, соответствуя или превосходя все отраслевые стандарты.

И противоречий в их суждениях конечно же никаких не видно... Цирк какой-то.

Скорее всего предполагали в OpenAI использовать гомоморфное шифрование, а из-за некомпетентности то ли журналюк, то ли самих разработчиков - написали о сквозном шифровании.

Если использовать M3-систему вместо классического DH, то, как понимаю, логика с простыми числами будет отсутствовать? Но при таком сценарии разве не будет возникать малых подгрупп, количество элементов в которых будет меньше заданного N? Протокол DH использует для предотвращения этому надёжные простые числа вида p=2q+1.

Также, есть ли какие-нибудь бенчмарки M3-системы в сравнении с DH? Могу ошибаться, но кажется, что классический DH с переумножением чисел будет быстрее при условии, что модуль N в M3-системе сопоставим с модулем p в DH-протоколе.

Это интересно. Если всё так, то это действительно здорово. Есть ли статьи, где об этом можно почитать более подробно? Вроде и читал статьи / работы с сайта I2P, но конкретики по тому как ложный трафик генерируется, в какой пропорции и насколько он завязан на открытых текстах не нашёл - вполне возможно, что мог это и пропустить.

Он не "взламывает" AES так, как алгоритм Шора взламывает RSA, но он эффективно уменьшает стойкость ключа вдвое.

Если мы говорим про стойкость ключа (т.е. его сопротивляемость к полному перебору), то алгоритм Гровера уменьшает его не вдвое, а в 2^{N/2}раз. Вдвое он уменьшает именно что количество бит.

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

1
23 ...

Информация

В рейтинге
7 275-й
Откуда
Россия
Работает в
Зарегистрирован
Активность

Специализация

Бэкенд разработчик, Разработчик приложений
Старший
Golang
C
Криптография
Микросервисная архитектура
Информационная безопасность