Введение
Существующие популярные анонимные сети, подобия Tor или I2P, хороши своим прикладным использованием, а также относительно хорошей скоростью и лёгкостью настройки. Они также хороши и непосредственно в анонимизации трафика, когда нам необходимо скрыть истинную связь между отправителем и получателем, основываясь на принципе федеративности, то есть на свойстве, при котором узлы сети расположены в разных государствах, а сама цепочка маршрутизации проходит сквозь множество несвязанных между собой узлов. Но что делать, если государство единственно, как выстраивать маршруты в целях анонимизации, если нет никакого сетевого доступа в другие государства? Что делать, если все доступные государства находятся в своеобразном картеле, где сам принцип федеративности теряет свой основной замысел?Принцип федеративности
Чтобы ответить на заданные вопросы, нам необходимо для начала разобрать сам принцип федеративности, а именно, то, на факте чего он держится и то, от чего он защищает. Для такой цели мы введём два новых термина — мощность федеративности и полиморфизм информации. Начнём с последнего.Полиморфизм информации — это есть свойство изменчивости передаваемого объекта при множественной маршрутизации несколькими субъектами сети, разграничивающее связь субъектов посредством анализа объекта. Так например, если существует три субъекта сети {A, B, C} и объект P, который передаётся от A к B и от B к C соответственно, то внешний вид информации P1 и P2 должен определяться как [P1 = (A → B)] ≠ [P2 = (B → C)], где P ∉ {P1, P2} и P1 ≠ P2, (B не связывает {P1, P2} с P) и (A не связывает {P1, P} с P2) и/или (C не связывает {P2, P} с P1). В большинстве случаев полиморфизм информации достигается множественным шифрованием объекта: [E2(E1(P)) = (A → B)] ≠ [E1(P) = (B → C)], (где E — функция шифрования), при котором интерстициальный, промежуточный субъект B становится неспособным связать {E2(E1(P)), E1(P)} с P, а субъект C неспособен связать {E1(P), P} с E2(E1(P)).
Мощность федеративности — количество государств, несвязанных между собой общими политическими интересами, через территорию которых проходит маршрутизация полиморфной информации. Из этого следует, что если сеть разворачивается лишь в пределах одного государства, то мощность федеративности по умолчанию будет равна единице. Также, из этого следует, что обычная, неполиморфная маршрутизация не будет повышать мощность федеративности, даже при учёте существования нескольких несвязанных государств.
И таким образом, сам принцип федеративности можно описать в виде двух необходимых критериев:
- Необходимо использовать противоречия государств — вариативные и несогласованные законы, политические и империалистические интересы. Всё это есть моменты, при которых одно государство не будет выдавать информацию о своей сети другому государству. И чем более агрессивно настроены страны по отношению друг к другу, тем менее успешно они могут контролировать свои собственные ресурсы. В таком случае, необходимо строить сеть по федеративному принципу, чтобы узлы располагались на разных континентах мира, странах и государствах.
- Необходимо использовать изменения информации в процессе её маршрутизации. При таком способе информация будет представлена в полиморфной и самоизменяющейся оболочке. Такой подход необходим в моменты, когда информация, приходящая из государства A в государство B, будет снова возвращаться на свою «родину» A. В качестве примера можно привести луковую маршрутизацию сети Tor, где само шифрование представлено в виде слоёв, которые каждый раз «сдирают», снимают при передаче от одного узла к другому.
*Здесь также нужно взять во внимание конкретные уязвимости в реализации и проектировании тех или иных анонимных сетей, например Tor и Crowds уязвимы к timing-атакам, к которым, тем не менее, не уязвимы I2P и Mixminion. Это говорит о том, что уязвимости не лежат в плоскости принципа федеративности, а относятся исключительно к специфике архитектуры самой сети.
Проблема глобального наблюдателя
Принцип федеративности работает до тех пор, пока мощность федеративности больше единицы. И в этом кроется главная проблема, т.к. могут существовать сценарии, при которых становится невозможным применять принцип федеративности. Например, если государство X отгородится от всего остального мира, или если государство Y заблокирует большую часть VPN-сервисов и общеизвестных узлов анонимных сетей, или если абоненты (отправитель и получатель) находятся в одном и том же государстве Z, не ограничивающем связь, а следовательно и маршрутизацию со внешним миром, и при этом анонимная сеть A всё же уязвима к timing-атакам. В любом из этих сценариев, принцип федеративности оказывается в проигрышном положении.В то время как последний случай можно относительно легко исправить просто сменив анонимную сеть A, уязвимую к timing-атакам, на анонимную сеть B, неуязвимую к timing-атакам, а со вторым случаем можно бороться посредством передачи/получения списков скрытых узлов (мостов) или арендой VPS/VDS сервера за границей в качестве дальнейшего VPN к анонимной сети, последний же, третий случай такими лёгкими манёврами не получится исправить. Само блокирование всей остальной сети приводит нас к проблеме глобального наблюдателя, в которой любые действия совершаются в заведомо замкнутой и прослушиваемой среде: наблюдателю становится известен весь маршрут передаваемого объекта, становится известен тот факт, кто его создал, когда он его создал, по какому маршруту он его перемещал, и в конечном итоге, становится известен тот факт, кому такой объект был передан.
Таким образом, все анонимные сети, базируемые на принципе федеративности, становятся уязвимы к проблеме глобального наблюдателя, потому как модель угроз на базе федеративности не предполагает решения проблемы при условии существования единого и монопольного наблюдателя. Реализация дополнительных "фич" со стороны анонимных сетей, например в лице примитивной генерации мусорного трафика, лишь затушёвывает основное противоречие, но не решает его окончательно. При достаточно длительном периоде рассмотрения действий в сети можно будет замечать и отделять мусорный трафик от истинного, потому как первый есть лишь наложение на второй. Таким образом, если не будет существовать истинного трафика, то суммарный объём всего трафика снизится до мусорного и тем самым, глобальный наблюдатель уже апостериори, по истечению времени анализа, будет знать действительную разницу между разнородным видом трафика. И как следствие, в следующих своих анализах, глобальный наблюдатель априори будет учитывать эту разницу.
Теоретически доказуемая анонимность
Несмотря на кажущуюся затруднительную ситуацию, существует ряд анонимных сетей способных противостоять глобальному наблюдателю, будучи расположенными в заведомо враждебной, прослушиваемой и замкнутой среде. Отличительной особенностью таковых сетей является тот факт, что глобальный наблюдатель становится неспособным выявляться закономерности маршрутов или отличий в типе трафика. Более формальное определение таковых сетей звучит следующим образом.На сегодняшний момент времени существует три вида задач анонимизации с теоретически доказуемыми моделями. На основе таковых задач могут быть созданы непосредственно сами анонимные сети.Анонимными сетями с теоретически доказуемой анонимностью принято считать замкнутые, полностью прослушиваемые системы, в которых становится невозможным осуществление любых пассивных атак (в том числе и при существовании глобального наблюдателя) направленных на деанонимизацию факта отправления и/или получения информации, или на деанонимизацию связи между отправителем и получателем с минимальными условностями по количеству узлов неподчинённых сговору. Говоря иначе, с точки зрения пассивного атакующего, апостериорные знания, полученные вследствие наблюдений, должны оставаться равными априорным, до наблюдений, тем самым сохраняя равновероятность деанонимизации по N-ому множеству субъектов сети.
- Проблема обедающих криптографов (анонимные сети: Herbivore, Dissent)
- Задача на базе очередей (анонимные сети: Hidden Lake, M-A)
- Задача на базе увеличения энтропии (анонимные сети: отсутствуют)
Проблема обедающих криптографов является достаточно старой и устоявшейся задачей в научных кругах, что в действительности является очень хорошим качеством. Но стоит учитывать, что две оставшиеся задачи являются относительно новыми, им буквально всего один-два года, что может вызвать вполне оправданный скептицизм. В таком случае, о последних задачах вы можете почитать в ссылках указанных выше или более подробно, и во всех нюансах, вы можете почитать в работе - Абстрактные анонимные сети.
Вкратце о проблеме обедающих криптографов
Первой теоретически доказуемой анонимной сетью (как ядро) становится задача обедающих криптографов. Выглядит она так (не буду пересказывать о том, как криптографы обедают и о том, что существует некий АНБ, раскажу вкратце): существует три участника сети {A, B, C}. Один участник хочет послать 1 бит информации по сети (либо 1, либо 0 соответственно), но таким образом, чтобы другие субъекты не узнали кто отправил данную информацию. Предполагается, что таковые участники соединены между собой, тем самым имеют безопасный канал связи, а также имеют расписание по которому в каждый момент времени T генерируется новый бит.
Предположим, что участник A хочет отправить информацию по сети так, чтобы {B, C} эту информацию получили, но не смогли узнать, кто действительно является отправителем. Иными словами, для B это может быть {A, C}, а для C это {A, B} с вероятностью 50/50. Все участники начинают согласовывать общий бит со своими соседями (в момент времени T, конечно же). Предположим, что участники {A, B} согласовали бит = 1, {B, C} = 0, {C, A} = 1.
Далее каждый участник сети XOR'ит (операция исключающее ИЛИ) биты со всех своих соединений: A = 1 xor 1 = 0; B = 1 xor 0 = 1; C = 0 xor 1 = 1. Данные результаты обмениваются по всей сети и XOR'ятся каждым её участником: 0 xor 1 xor 1 = 0. Это говорит о том, что участник A передал бит информации = 0. Чтобы субъект A мог передать бит = 1, ему необходимо добавить операцию НЕ в своём вычислении, то есть A = НЕ(1 xor 1) = 1. В итоге, все вычисления прийдут к такому результату: 1 xor 1 xor 1 = 1.Таким образом, можно передать 1 бит информации полностью анонимно (конечно же со стороны определения теоретически доказуемой анонимности).
Сеть на базе задачи обедающих криптографов при трёх участниках {A, B, C}
Предположим, что один из участников, либо B, либо C захочет деанонимизировать либо {A, C}, либо {B, C} соответственно (то есть узнать, кто является отправителем информации). Тогда ему потребуется узнать согласованный секрет со стороны другой линии связи, что является сложной задачей (если конечно не был произведён сговор нескольких участников). Таким образом, атака со стороны внутреннего пассивного наблюдателя становится безрезультатной. Со стороны внешнего глобального наблюдателя такая же ситуация, потому как он видит лишь переадресации зашифрованных битов (потому как используется безопасный канал связи) в один момент времени T всеми участниками сети.
Вкратце о задаче на базе очередей
Предположим, что существует три участника {A, B, C}. Каждый из них соединён друг c другом (не является обязательным критерием, но данный случай я привёл исключительно для упрощения). Каждый субъект устанавливает период генерации информации = T. В отличие от DC-сетей, где требуется синхронизация установки периода по времени, в задаче на базе очередей такое условие не является обязательным. Иными словами, каждый участник сети может начать генерировать информацию с периодом = T в любое время, без предварительной кооперации/синхронизации с другими участниками. У каждого участника имеется своё внутренее хранилище по типу FIFO (первый пришёл - первый ушёл), можно сказать имеется структура "очередь".
Сеть на базе очередей при трёх участниках {A, B, C}
Предположим, что участник A хочет отправить некую информацию одному из участников {B, C}, так, чтобы другой участник (или внешний наблюдатель) не знал, что существует какой-либо факт отправления. Каждый участник в определённый период T генерирует сообщение. Такое сообщение может быть либо ложным (не имеющее никакого фактического содержания и никому по факту не отправляется, заполняясь случайными битами), либо истинным (запрос или ответ). Отправить раньше или позже положенного времени T никакой участник не может. Если скопилось несколько запросов одному и тому же участнику, тогда он их ложит в свою очередь сообщений и после периода T достаёт из очереди и отсылает в сеть.
Таким образом, внешний глобальный наблюдатель будет видеть лишь картину, при которой каждый участник в определённо заданный период времени T отправляет некое сообщение всем остальным узлам сети, что не даёт никакой информации о факте отправления, либо получения. Внутренние пассивные участники также неспособны узнать коммуниицирует ли один из участников в данный период времени с каким-либо другим, т.к. предполагается, что шифрованная информация не выдаёт никаких данных об отправителе и получателе непосредственно.
Вкратце о задаче на базе увеличения энтропии
Предположим, что существует три субъекта {A, B, C} и существует глобальный наблюдатель, целью которого является определение отправителя и получателя в сети. Предположим также, что все субъекты данной системы не заинтересованы в деанонимизации друг друга (эта условность будет служить лишь упрощением, на практике она в полной мере не обязательна). Анонимизация здесь строится на итеративной схеме, иными словами, чем больше вы будете отправлять сообщений, тем лучше качество анонимности будет становиться.
Предположим, что сеть базируется на схеме запрос-ответ, иными словами, когда один пользователь отправит запрос, то другой пользователь должен будет на него ответить.
Предположим, что мы являемся субъектом A, а получателем для нас будет являться субъект C. Мы знаем публичные ключи всех пользователей {B, C}. Шифрование происходит публичным ключом получателя. Предполагается, что никто не сможет расшифровать сообщение кроме узла обладающего приватным ключом. Чтобы отправить сообщение M, нам необходимо проделать одно из следующих действий с вероятностью 1/2:
- Зашифровать M открытым ключом пользователя C и отправить шифрованное сообщение EC(M) всем пользователям сети, то есть пользователям B и C.
ИЛИ - Зашифровать M дважды, сначала открытым ключом пользователя C, а затем открытым ключом пользователя B и отправить шифрованное сообщение EB(EC(M)) всем пользователям сети, то есть пользователям B и C.
Но мы держим в голове тот факт, что схема анонимизации итеративна и с каждым проходом лишь увеличивает анонимность. Пока что мы проигнорируем первый пункт с инициатором связи и попытаемся рассмотреть второй пункт. Действительно, если связь прервётся, то глобальный наблюдатель сможет узнать кто являлся получателем сообщения. Но теперь, что если связь будет продолжаться, хотя бы ещё одну итерацию, то насколько увеличится анонимность?
Для лёгкости восприятия, мы теперь будем исходить из лица внешнего глобального наблюдателя. Я буду указывать (A -> B) как факт отправления, что A отправил B информацию. (ИЛИ) будет говорить о неопределённости со стороны наблюдателя.
Если мы далее продлим связь на плюс одну итерацию, то итоговая схема будет выглядить следующим образом:
- (A -> B ИЛИ A -> C) = запрос(1)
[Внешний наблюдатель знает лишь факт отправления и то, кто отправил сообщение - A, но пока не знает кто является получателем] - (B -> A ИЛИ C -> A) = ответ(1)
[Внешний наблюдатель знает, что с вероятностью 1/2 пакет мог быть зашифрован лишь единожды и тогда B или C сразу отправит пользователю A ответ]
ИЛИ
(B -> C ИЛИ C -> B) = маршрутизация(1)
[Внешний наблюдатель знает, что с вероятностью 1/2 пакет мог быть зашифрован дважды и тогда B или C будет являться маршрутизатором к C или B соответственно] - (B -> A ИЛИ C -> A) = ответ(1)
[Внешний наблюдатель знает, что с вероятностью 1/2 пакет мог быть зашифрован дважды и тогда B или C после этапа маршрутизации отправит пользователю A ответ]
ИЛИ
(B -> A ИЛИ B -> C ИЛИ C -> A ИЛИ C -> B) = запрос(2)
[Внешний наблюдатель предполагает, что ответ мог быть уже выдан на этапе 2., а на этапе 3. мог быть сгенерирован совершенно новый запрос]
Сеть на базе увеличения энтропии при трёх участниках {A, B, C} (увеличение энтропии на единицу)
При этом, новая итерация запроса рушит уверенность в получателе первой итерации, потому как происходит пересечение первой незавершённой итерации запрос-маршрутизация-ответ со второй итерацией запрос. Таким образом, энтропия, по-факту увеличивается "авансом" к отправителю, потому как сначала она увеличивается для получателя, а только потом переходит на отправителя. Иными словами, если мы уверены, что цепь событий продолжится, то на втором этапе для получателя будет повышена энтропия на 1 бит, и только потом, на следующем - третьем этапе, энтропия будет повышена для отправителя.
Таким образом, хоть при первой итерации мера неопределённости равнялась 0 бит, но как только достигается вторая итерация, неопределённость увеличивается на бит и как следствие, делит ранее 100%-ую вероятность вдвое. Вышеописанную схему можно представить ещё более лёгким образом, в виде перекрытия запросов и ответов:
- запрос(1)-ответ(1)-запрос(2)-ответ(2)
- запрос(1)-маршрутизация(1)-ответ(1)-запрос(2)
Если таким же образом продолжать цепь событий, то энтропия будет каждый раз увеличиваться на единицу. Визуально это можно изобразить на вышеприведённом рисунке. В результате, глобальному наблюдателю остаётся лишь догадываться кто является отправителем и получателем, и с каждым разом вероятность определения старых запросов будет постепенно "растворяться" во множестве новых.
Все анонимные сети с теоретически доказуемой анонимностью обладают в определённой степени схожими характеристиками. Возможно таковые являются основополагающими для всех сетей с теоретически доказуемой моделью, т.к. пока неизвестны другие задачи, которые бы могли игнорировать нижеуказанные пункты.
- Мусорный (ложный) трафик является неотъемлемой частью теоретически доказуемых анонимных сетей. В то время как в других анонимных сетях ложный трафик лишь накладывается на истинный, в теоретически доказуемых сетях ложный трафик порождается самим ядром, механизмом, задачей анонимизации.
- Передаваемый объект транспортируется всем узлам сети, не имея точного и чёткого маршрута своего движения. Иными словами, нагрузка всей сети определяется линейно от количества её участников, то есть за O(N).
- За счёт первого и второго пункта, анонимные сети с теоретически доказуемой анонимностью могут работать лишь в пределах малых групп участников, например 30-100 узлов, в отличие от тех же анонимных сетей Tor и I2P, у которых нет таких специфичных пунктов, а следовательно и ограничений.
- Ранее могло показаться, что полиморфизм информации необходим всегда в анонимных сетях, и являлся в некой степени характерной особенностью самих анонимных сетей. Но как оказалось, анонимные сети могут вовсе не обладать полиморфизмом информации и оставаться при этом анонимными сетями, что и показывает своим существованием задача на базе очередей.
- Основываясь лишь и только на проблеме обедающих криптографов, а также на задаче очередей можно было бы выдвинуть ложное предположение, что все теоретически доказуемые сети должны быть последовательны в своих запросах (исключать параллельность), основываясь лишь и только на очередях (локальных или глобальных). Но задача на базе увеличения энтропии рушит эту теорию. Хоть и действительно, если узел будет генерировать куда больше запросов в один момент времени, чем большая часть сети, то это станет подозрительным, тем не менее, сама случайность может сыграть противоположное действие. Поэтому перед выполнением параллельных запросов остаётся лишь высчитать вероятность появления N-ой параллельности. Если вероятность достаточно большая, то и сама параллельность становится вполне допустимой в сети.
- При поверхностном рассмотрении теоретической доказуемости может показаться, что выдвигаемые задачи порождают лишь одноранговые сетевые архитектуры, исключая при этом какую бы то ни было гибридность. На самом же деле, задачи вполне могут существовать и быть реализованы внутри гибридных систем. Так например, задача на базе очередей может быть адаптирована под предоставление анонимности исключительно отправителя, но не получателя. В такой системе гибридность становится необходимой, чтобы собирать анонимные сообщения в кучу и далее их постепенно раскрывать, проводя через несколько узлов.
Многоранговые сети делятся на две модели: централизованные и распределённые. Централизованная или классическая клиент-серверная архитектура является наиболее распространённой моделью из-за своей простоты, где под множество клиентов выделяется один сервер, выход из строя которого приводит к ликвидации всей сети. Распределённая многоранговая система предполагает множество серверов, принадлежащих одному лицу или группе лиц с общими интересами, на множество клиентов, тем самым решая проблему уничтожения сети при выходе из строя одного или нескольких серверов. Из вышеописанного также следует, что классическая централизованная структура является лишь частным случаем более общей распределённой модели, или иными словами, сам факт распределённости становится следствием централизации. Сети на основе многоранговой архитектуры расширяются изнутри, относительно своего ядра, и не допускают расширения извне.
В одноранговых (peer-to-peer) системах все пользователи однородны, имеют одинаковые возможности, могут представлять одни и те же услуги маршрутизации. Сами одноранговые сети могут быть разделены на три модели: централизованные, децентрализованные и распределённые (последняя – условно). Централизованные одноранговые сети представляют собой соединения на базе одного или нескольких, заранее выделенных или динамически выделяемых серверов-ретрансляторов, исключение которых приводит к блокированию всей сети. Отсутствие прав серверов в такой модели начинает порождать равноправность их клиентов. Распределённые сети не выделяют какой-либо центр или узел связи, сохраняя факт одновременной и полной коммуникации узла со всеми другими узлами, иными словами, со всей сетью. Иногда под распределённой связью подразумевают также необходимое N-ое количество соединений, необязательно со всей сетью. В децентрализованных сетях становится возможным образование неравномерного распределения соединений и появление «неофициальных» узлов-серверов, часто используемых другими узлами в качестве последующей маршрутизации. Таким образом, децентрализованная модель, в своём определении, начинает быть более подверженной концентрированию линий связи, чем распределённая модель. Тем не менее, распределённая модель является лишь конфигурацией децентрализованной и полноценно, в отрыве от последней, рассматриваться не может. Сети на основе одноранговой архитектуры расширяются извне, за исключением начальной фазы одноранговой централизации.
Гибридная система объединяет свойства многоранговых и одноранговых архитектур, пытаясь взять и удержать как можно больше положительных и меньше отрицательных качеств. Сама гибридность системы может рассматриваться в разных значениях и проявлениях, как пример на уровне топологий: «шина + кольцо», «кольцо + полносвязная», «звезда + ячеистая» и т.д., или на уровне прикладного рассмотрения: «одноранговая + многоранговая». Плюсом многоранговых архитектур становится возможность разделения логики на серверную и клиентскую, а также более быстрая и/или статичная скорость маршрутизации. Плюсом одноранговых архитектур становится высокая отказоустойчивость за счёт внешнего расширения сети и возможность построения безопасной, а также масштабируемой «клиент-клиент» связи. Минусом гибридных архитектур на ранних стадиях развития является их возможный, осуществимый и более вероятностный переход в многоранговые системы (по сравнению с одноранговыми) за счёт большого уплотнения серверов принадлежащих одному лицу, либо группе лиц с общими интересами.
Стоит также сказать, что теоретически доказуемая анонимность не является абсолютной анонимностью, в том простом плане, что первая ограничена лишь и только пассивными атаками, в то время как вторая защищена в общем от всех возможных атак. Первую возможно доказать лишь за счёт собственной ограниченности пассивных наблюдений, которые более не могут предоставить новые векторы нападений, что нельзя сказать об активных наблюдателях, атаки которых могут успешно синтезироваться, улучшаться, обновляться. Поэтому существование абсолютной анонимности, в тех или иных условиях, остаётся всегда под вопросов, что, тем не менее, не распространяется на теоретическую анонимность.
Пример активной атаки (запрос-ответ)
Предположим, что существует всего три узла в сети {A, B, C}. Мы являемся атакующим под точкой A. В нашем распоряжении есть идентификатор ID (допустим публичный ключ) одного из субъекта: либо B, либо C. Нашей целью становится связывание данного идентификатора с реальным сетевым адресом, тобишь целью становится узнать и связать реальный IP-шник узла с ID.
Если мы можем исполнять роль как глобального наблюдателя, так и внутреннего узла, в роли узла - A, то сама атака становится примитивной. Мы начинаем генерировать запрос к одному из узлов {B, C} по идентификатору ID. Т.к. архитектура сети построена по принципу "запрос-ответ", то на любой запрос будет сгенерирован свой ответ. Т.к. анонимная сеть является теоретически доказуемой, то просто проанализировав трафик сети мы ничего не получим, поэтому нам необходимо проделать некую активную манипуляцию, а именно - заблокировать на время одного участника: либо B, либо C от всей другой сети.
И так, мы блокируем участника B, отправляем сгенерированный запрос по идентификатору ID. Если спустя время мы получаем ответ, то получателем является узел C, и как следствие, мы связываем ID с IP адресом. Иначе, если мы не получаем ответ, то получателем является узел B (так как он был заблокирован), и также связываем его IP адрес с ранее известным ID. В итоге, мы деанонимизировали участника сети и если кто-то будет отправлять сообщения с данным ID, то мы уже будем знать кто конкретно сидит под данным идентификатором.
Скрытие факта анонимизации
При теоретически доказуемой анонимности глобальному наблюдателю становится проблематичным выявить само состояние субъекта в сети, а именно совершает ли он сейчас или когда-либо совершал определённое действие (отправление / получение информации) или всё время бездействовал. Тем не менее, это не мешает глобальному наблюдателю выявить принадлежность субъекта к этой сети по характерным и специфичным особенностям самой системы.Так например, при задаче на базе очередей достаточно лишь выявить, что субъект каждый заданный интервал времени = T отправляет шифрованные сообщения в сеть. В проблеме обедающих криптографов достаточно сравнивать лишь массовость XOR операций. Из приведённого списка теоретически доказуемых моделей наверное наименее подверженная к чёткому определению привязанности субъекта к анонимизации трафика является модель на базе увеличения энтропии за счёт отсутствия конкретных паттернов поведения.
Тем не менее, что делать с оставшимися двумя задачами? Ответ на этот вопрос может лежать в нескольких плоскостях.
- Первый и самый очевидный - это генерировать в случайный промежуток времени ложный трафик. К сожалению, это будет лишь затушёвывать анонимизирующий трафик.
- Второй способ - это растягивать период генерации, в таком случае наблюдателю потребуется больше времени для сопоставления закономерностей. Но, применив единожды данную закономерность, наблюдатель сможет впоследствии более эффективно выявлять анонимизацию трафика.
- Третий способ - сделать сами периоды случайными. Такой способ не сработает для DC-сетей (проблема обедающих криптографов), потому как в данном типе задачи необходима сильная синхронизация участников сети по периоду генерации трафика, что нельзя сказать о задаче на базе очередей. В задаче на базе очередей каждый участник устанавливает свой период генерации информации, а потому и сам может в определённые промежутки времени его менять.
- Шифруем сообщение X, получаем E(X);
- Добавляем к E(X) N случайных байт до статичного размера L(S), где L - функция вычисления количества байт в сообщении S. То есть S = E(X) || r(N), где r - функция генерации случайных N байт, || - конкатенация байт.
- К полученному результату S добавляем R случайных байт, то есть S || R = E(X) || r(N) || R.
Запуск теоретически доказуемой анонимности
К сожалению, некоторые анонимные сети с теоретически доказуемой анонимностью так и не выходят в открытую среду, оставаясь лишь и только теорией, практику которой видел лишь ограниченный круг лиц. Как бы это не звучало парадоксально, такое утверждение вполне справедливо для сетей на основе проблемы обедающих криптографов, которой как минимум уже 35 лет.Herbivore
Так например, сеть Herbivore имеет следующую страницу на своём сайте. Иными словами, чтобы "потыкать" данного травоядного нужно отправить на email сообщение, что вы заинтересованы в данном ПО и механизме работы и может быть, в итоге вам выдают исходники.Dissent
Сеть Dissent ушла дальше своего "коллеги" по задаче, создав вполне себе открытый репозиторий на github, тем не менее, такая сеть не обновлялась уже как минимум 9 лет. Нельзя сказать однозначно, что это плохо, при условии, если сеть полностью завершена и готова к эксплуатации, на что неоднозначно намекает сам архивный репозиторий.Давайте попробуем запустить Dissent из исходников.
В зависимостях Dissent указано две библиотеки: Qt и CryptoPP. В репозитории Dissent в README пишется, что мы можем использовать команду qmake dissent.pro, но в моём случае она никак не сработала. Устанавливаем их. Скачиваем репозиторий https://github.com/weidai11/cryptopp и прописываем команды (как указано в install.txt):
$ make
$ make test
$ sudo make install
CryptoPP компилирует библиотеку по умолчанию последней версией стандарта C++, поэтому необходимо было спустится до стандарта C++11. Для этого я просто поменял в коде Gnumakefile одну строку при компиляции:
# Было:
CXXFLAGS ?= -g2 -O3 -fPIC -pipe
# Стало:
CXXFLAGS ?= -std=c++11 -g2 -O3 -fPIC -pipe
Теперь запускаем вновь все те три команды. Копируем основной репозиторий Dissent и запускаем две команды, как указано в инструкции README.
$ qmake application.pro
$ make
К сожалению на второй команде у меня возникла ошибка компиляции.
g++ -c -pipe -Werror -std=c++11 -g -D_REENTRANT -Wall -Wextra -fPIC -DVERSION=3 -DFAST_NEFF_SHUFFLE -DCRYPTOPP -DQT_NETWORK_LIB -DQT_CONCURRENT_LIB -DQT_CORE_LIB -I. -Iext/qhttpserver/src -Iext/qhttpserver/http-parser -Iext/qt-json -Iext/qxt -Isrc -Isrc -I/usr/include/qt -I/usr/include/qt/QtNetwork -I/usr/include/qt/QtConcurrent -I/usr/include/qt/QtCore -I. -I/usr/lib/qt/mkspecs/linux-g++ -o qhttpconnection.o ext/qhttpserver/src/qhttpconnection.cpp
g++ -c -pipe -Werror -std=c++11 -g -D_REENTRANT -Wall -Wextra -fPIC -DVERSION=3 -DFAST_NEFF_SHUFFLE -DCRYPTOPP -DQT_NETWORK_LIB -DQT_CONCURRENT_LIB -DQT_CORE_LIB -I. -Iext/qhttpserver/src -Iext/qhttpserver/http-parser -Iext/qt-json -Iext/qxt -Isrc -Isrc -I/usr/include/qt -I/usr/include/qt/QtNetwork -I/usr/include/qt/QtConcurrent -I/usr/include/qt/QtCore -I. -I/usr/lib/qt/mkspecs/linux-g++ -o qhttprequest.o ext/qhttpserver/src/qhttprequest.cpp
g++ -c -pipe -Werror -std=c++11 -g -D_REENTRANT -Wall -Wextra -fPIC -DVERSION=3 -DFAST_NEFF_SHUFFLE -DCRYPTOPP -DQT_NETWORK_LIB -DQT_CONCURRENT_LIB -DQT_CORE_LIB -I. -Iext/qhttpserver/src -Iext/qhttpserver/http-parser -Iext/qt-json -Iext/qxt -Isrc -Isrc -I/usr/include/qt -I/usr/include/qt/QtNetwork -I/usr/include/qt/QtConcurrent -I/usr/include/qt/QtCore -I. -I/usr/lib/qt/mkspecs/linux-g++ -o qhttpresponse.o ext/qhttpserver/src/qhttpresponse.cpp
g++ -c -pipe -Werror -std=c++11 -g -D_REENTRANT -Wall -Wextra -fPIC -DVERSION=3 -DFAST_NEFF_SHUFFLE -DCRYPTOPP -DQT_NETWORK_LIB -DQT_CONCURRENT_LIB -DQT_CORE_LIB -I. -Iext/qhttpserver/src -Iext/qhttpserver/http-parser -Iext/qt-json -Iext/qxt -Isrc -Isrc -I/usr/include/qt -I/usr/include/qt/QtNetwork -I/usr/include/qt/QtConcurrent -I/usr/include/qt/QtCore -I. -I/usr/lib/qt/mkspecs/linux-g++ -o qhttpserver.o ext/qhttpserver/src/qhttpserver.cpp
gcc -c -pipe -Werror -g -D_REENTRANT -Wall -Wextra -fPIC -DVERSION=3 -DFAST_NEFF_SHUFFLE -DCRYPTOPP -DQT_NETWORK_LIB -DQT_CONCURRENT_LIB -DQT_CORE_LIB -I. -Iext/qhttpserver/src -Iext/qhttpserver/http-parser -Iext/qt-json -Iext/qxt -Isrc -Isrc -I/usr/include/qt -I/usr/include/qt/QtNetwork -I/usr/include/qt/QtConcurrent -I/usr/include/qt/QtCore -I. -I/usr/lib/qt/mkspecs/linux-g++ -o http_parser.o ext/qhttpserver/http-parser/http_parser.c
ext/qhttpserver/http-parser/http_parser.c: In function ‘http_parser_parse_url’:
ext/qhttpserver/http-parser/http_parser.c:2092:18: error: this statement may fall through [-Werror=implicit-fallthrough=]
2092 | found_at = 1;
| ~~~~~~~~~^~~
ext/qhttpserver/http-parser/http_parser.c:2095:7: note: here
2095 | case s_req_server:
| ^~~~
cc1: all warnings being treated as errors
make: *** [Makefile:1916: http_parser.o] Error 1
Ошибка как мы видим не критичная, просто залезаем в код указания компиляции и убираем опцию Werror в файле dissent.pro.
# Было:
QMAKE_CXXFLAGS += -Werror -std=c++11
QMAKE_CFLAGS += -Werror
# Стало:
QMAKE_CXXFLAGS += -std=c++11
Далее возникли более забавные ошибки вида:
src/Crypto/AbstractGroup/CppECGroup.cpp: In member function ‘virtual Dissent::Crypto::AbstractGroup::Element Dissent::Crypto::AbstractGroup::CppECGroup::EncodeBytes(const QByteArray&) const’:
src/Crypto/AbstractGroup/CppECGroup.cpp:157:48: error: ISO C++ forbids declaration of ‘type name’ with no type [-fpermissive]
157 | CryptoPP::Integer r(reinterpret_cast<const byte*>(data.constData()), data.count());
| ^~~~
src/Crypto/AbstractGroup/CppECGroup.cpp:157:48: error: expected ‘>’ before ‘byte’
src/Crypto/AbstractGroup/CppECGroup.cpp:157:48: error: expected ‘(’ before ‘byte’
157 | CryptoPP::Integer r(reinterpret_cast<const byte*>(data.constData()), data.count());
| ^~~~
| (
src/Crypto/AbstractGroup/CppECGroup.cpp:157:48: error: ‘byte’ was not declared in this scope; did you mean ‘CryptoPP::byte’?
157 | CryptoPP::Integer r(reinterpret_cast<const byte*>(data.constData()), data.count());
| ^~~~
| CryptoPP::byte
In file included from /usr/local/include/cryptopp/config.h:27,
from /usr/local/include/cryptopp/cryptlib.h:105,
from /usr/local/include/cryptopp/nbtheory.h:9,
from src/Crypto/AbstractGroup/CppECGroup.cpp:3:
/usr/local/include/cryptopp/config_int.h:66:23: note: ‘CryptoPP::byte’ declared here
66 | typedef unsigned char byte;
| ^~~~
src/Crypto/AbstractGroup/CppECGroup.cpp:157:53: error: expected primary-expression before ‘>’ token
157 | CryptoPP::Integer r(reinterpret_cast<const byte*>(data.constData()), data.count());
| ^
make: *** [Makefile:2655: CppECGroup.o] Error 1
Необходимо было в коде поменять byte на CryptoPP::byte. Далее при продолжении компиляции возникли следующие схожие ошибки:
src/Crypto/CryptoPP/RsaPrivateKeyImpl.cpp: In member function ‘virtual QByteArray Dissent::Crypto::CppRsaPrivateKeyImpl:ecrypt(const QByteArray&) const’:
src/Crypto/CryptoPP/RsaPrivateKeyImpl.cpp:63:20: error: ‘SHA’ was not declared in this scope
63 | RSAES<OAEP<SHA> >:ecryptor decryptor(*m_private_key);
| ^~~
src/Crypto/CryptoPP/RsaPrivateKeyImpl.cpp:63:23: error: template argument 1 is invalid
63 | RSAES<OAEP<SHA> >:ecryptor decryptor(*m_private_key);
| ^
src/Crypto/CryptoPP/RsaPrivateKeyImpl.cpp:63:25: error: template argument 1 is invalid
63 | RSAES<OAEP<SHA> >:ecryptor decryptor(*m_private_key);
| ^
src/Crypto/CryptoPP/RsaPrivateKeyImpl.cpp:63:38: error: expected initializer before ‘decryptor’
63 | RSAES<OAEP<SHA> >:ecryptor decryptor(*m_private_key);
| ^~~~~~~~~
src/Crypto/CryptoPP/RsaPrivateKeyImpl.cpp:65:26: error: ‘decryptor’ was not declared in this scope; did you mean ‘Decrypt’?
65 | int data_start = decryptor.FixedCiphertextLength() + AES::BLOCKSIZE;
| ^~~~~~~~~
| Decrypt
make: *** [Makefile:3619: RsaPrivateKeyImpl.o] Error 1
Нужно было поменять SHA на CryptoPP:SHA1. Далее при компиляции возникла ещё одна ошибка
/usr/bin/qmake -o Makefile application.pro
g++ -fPIC -o dissent qhttpconnection.o qhttprequest.o qhttpresponse.o qhttpserver.o http_parser.o json.o qxtcommandoptions.o BaseDCNetRound.o CSDCNetRound.o Log.o NullRound.o NeffShuffleRound.o Round.o RoundFactory.o CommandLine.o ConsoleSink.o FileSink.o Settings.o ClientConnectionAcquirer.o Overlay.o ServerConnectionAcquirer.o Connection.o ConnectionManager.o ConnectionTable.o Id.o AsymmetricKey.o DsaPrivateKey.o DsaPublicKey.o NeffShuffle.o DiffieHellman.o KeyShare.o LRSPrivateKey.o LRSPublicKey.o OnionEncryptor.o RsaPrivateKey.o ThreadedOnionEncryptor.o IntegerGroup.o AbstractGroup.o CppECGroup.o ECParams.o CiphertextFactory.o BlogDropServer.o PublicKeySet.o ChangingGenServerCiphertext.o HashingGenClientCiphertext.o ChangingGenClientCiphertext.o ElGamalServerCiphertext.o Parameters.o ClientCiphertext.o BlogDropUtils.o ServerCiphertext.o BlogDropClient.o Plaintext.o ElGamalClientCiphertext.o HashingGenServerCiphertext.o PublicKey.o BlogDropAuthor.o PrivateKey.o Roster.o RpcHandler.o SignalSink.o ClientSession.o ServerSession.o Session.o SessionSharedState.o Address.o AddressFactory.o BufferAddress.o BufferEdge.o BufferEdgeListener.o Edge.o EdgeFactory.o EdgeListener.o EdgeListenerFactory.o TcpAddress.o TcpEdge.o TcpEdgeListener.o Logging.o Random.o Sleeper.o StartStop.o Time.o Timer.o TimerEvent.o Utils.o GetDirectoryService.o GetFileService.o GetMessagesService.o SendMessageService.o SessionService.o WebServer.o WebService.o CryptoRandomImpl.o DiffieHellmanImpl.o DsaPrivateKeyImpl.o DsaPublicKeyImpl.o HashImpl.o IntegerImpl.o RsaPrivateKeyImpl.o RsaPublicKeyImpl.o Application.o moc_qhttpconnection.o moc_qhttprequest.o moc_qhttpresponse.o moc_qhttpserver.o moc_BaseDCNetRound.o moc_CSDCNetRound.o moc_NeffShuffleRound.o moc_NullRound.o moc_Round.o moc_CommandLine.o moc_Overlay.o moc_Connection.o moc_ConnectionAcquirer.o moc_ConnectionManager.o moc_BufferSink.o moc_RequestResponder.o moc_RequestHandler.o moc_ResponseHandler.o moc_RpcHandler.o moc_SignalSink.o moc_SourceObject.o moc_ClientSession.o moc_ServerSession.o moc_Session.o moc_SessionMessage.o moc_SessionSharedState.o moc_SessionState.o moc_Edge.o moc_EdgeListener.o moc_TcpEdge.o moc_TcpEdgeListener.o moc_SignalCounter.o moc_StartStopSlots.o moc_Timer.o moc_MessageWebService.o moc_WebServer.o -lcryptopp -std=c++11 -fkeep-inline-functions -fPIC -fPIE -fpermissive /usr/lib/libQt5Network.so /usr/lib/libQt5Concurrent.so /usr/lib/libQt5Core.so -lpthread
/usr/bin/ld: /usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/../../../../lib/libcryptopp.a(dll.o): relocation R_X86_64_PC32 against undefined symbol `_ZThn8_NK8CryptoPP12CBC_ModeBase13IVRequirementEv' can not be used when making a PIE object; recompile with -fPIE
/usr/bin/ld: final link failed: bad value
collect2: error: ld returned 1 exit status
make: *** [Makefile:721: dissent] Error 1
Пришлось снова компилировать библиотеку CryptoPP, но с опцией fPIE. Я поменял в коде следующее:
# Было:
CXXFLAGS ?= -std=c++11 -g2 -O3 -fPIC -pipe
# Стало:
CXXFLAGS ?= -std=c++11 -g2 -O3 -fPIE -pipe
Перекомпилировал и ... ничего не получилась. Ошибка та же. Пытался также с другими версиями CryptoPP, но получал уже другие ошибки (не найденных функций).
...
/usr/bin/ld: Application.o.data.rel.ro._ZTVN8CryptoPP17TransparentFilterE[_ZTVN8CryptoPP17TransparentFilterE]+0xd8): undefined reference to `CryptoPP::BufferedTransformation::Skip(unsigned long)'
/usr/bin/ld: Application.o.data.rel.ro._ZTVN8CryptoPP17TransparentFilterE[_ZTVN8CryptoPP17TransparentFilterE]+0x128): undefined reference to `CryptoPP::Filter::TransferTo2(CryptoPP::BufferedTransformation&, unsigned long&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool)'
/usr/bin/ld: Application.o.data.rel.ro._ZTVN8CryptoPP17TransparentFilterE[_ZTVN8CryptoPP17TransparentFilterE]+0x130): undefined reference to `CryptoPP::Filter::CopyRangeTo2(CryptoPP::BufferedTransformation&, unsigned long&, unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool) const'
/usr/bin/ld: Application.o.data.rel.ro._ZTVN8CryptoPP10BufferlessINS_6FilterEEE[_ZTVN8CryptoPP10BufferlessINS_6FilterEEE]+0xd8): undefined reference to `CryptoPP::BufferedTransformation::Skip(unsigned long)'
/usr/bin/ld: Application.o.data.rel.ro._ZTVN8CryptoPP10BufferlessINS_6FilterEEE[_ZTVN8CryptoPP10BufferlessINS_6FilterEEE]+0x128): undefined reference to `CryptoPP::Filter::TransferTo2(CryptoPP::BufferedTransformation&, unsigned long&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool)'
/usr/bin/ld: Application.o.data.rel.ro._ZTVN8CryptoPP10BufferlessINS_6FilterEEE[_ZTVN8CryptoPP10BufferlessINS_6FilterEEE]+0x130): undefined reference to `CryptoPP::Filter::CopyRangeTo2(CryptoPP::BufferedTransformation&, unsigned long&, unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool) const'
/usr/bin/ld: Application.o: in function `CryptoPP::SourceTemplate<CryptoPP::RandomNumberStore>:ump2(unsigned long&, bool)':
/usr/local/include/cryptopp/filters.h:1440: undefined reference to `CryptoPP:EFAULT_CHANNEL[abi:cxx11]'
/usr/bin/ld: /usr/local/include/cryptopp/filters.h:1440: undefined reference to `CryptoPP::RandomNumberStore::TransferTo2(CryptoPP::BufferedTransformation&, unsigned long&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool)'
/usr/bin/ld: Application.o: in function `CryptoPP::SourceTemplate<CryptoPP::RandomNumberStore>:umpMessages2(unsigned int&, bool)':
/usr/local/include/cryptopp/filters.h:1442: undefined reference to `CryptoPP:EFAULT_CHANNEL[abi:cxx11]'
/usr/bin/ld: Application.o: in function `CryptoPP::SourceTemplate<CryptoPP::RandomNumberStore>:umpAll2(bool)':
/usr/local/include/cryptopp/filters.h:1444: undefined reference to `CryptoPP:EFAULT_CHANNEL[abi:cxx11]'
/usr/bin/ld: Application.o: in function `CryptoPP::Unflushable<CryptoPP::Filter>::Flush(bool, int, bool)':
/usr/local/include/cryptopp/simple.h:156: undefined reference to `CryptoPP:EFAULT_CHANNEL[abi:cxx11]'
collect2: error: ld returned 1 exit status
make: *** [Makefile:729: dissent] Error 1
В итоге, как бы я ни старался реанимировать пациента, он сопротивлялся. Возможно в моих действиях были ошибки. Может не те версии библиотек установил, но нигде не было информации какие конкретно версии необходимо устанавливать. Может дистрибутив не тот, т.к. я работаю на Manjaro. Может ещё что. Если кому либо удастся нормально установить, напишите в комментариях, я посмотрю и также попытаюсь воспроизвести действия.
Hidden Lake
Данный представитель уже основан не на проблеме обедающих криптографов, а на задаче очередей. Также как и Dissent, у Hidden Lake есть свой репозиторий на github. Написан Hidden Lake на языке программирования Go, поэтому нам не будет надобности тоскать туда-сюда библиотеки, по отдельности их компилировать и далее линковать как мы это пытались делать в Dissent. В этом плане, компиляция Hidden Lake будет попроще.Hidden Lake (HL) — это децентрализованная friend-to-friend (F2F) анонимная сеть, основанная на принципе микросервисной архитектуры и написанная на языке Go. В ядре анонимной сети (Hidden Lake Service = HLS) содержится анонимизирующий алгоритм с доказуемой моделью на базе очередей.
Помимо HLS, проект HIdden Lake также содержит другие сервисы, а именно: 1) Hidden Lake Traffic (HLT) - распределитель трафика, способный работать как в роли ретранслятора сообщений, так и в роли хранилища трафика; 2) Hidden Lake Messenger (HLM) - прикладное приложение, предоставляющее возможность отправления / получения сообщений и файлов. В приложениях: HLS, HLT, HLM, и в их комбинациях: HLS+HLM, HLS+HLT, HLS+HLT+HLM, выражается весь проект HL.
Hidden Lake на данном этапе представлен лишь одним готовым прикладным приложением - мессенджером HLM. В действительности же, на базе Hidden Lake может быть создана масса других приложений будь то это электронная почта, файловые сервисы, социальные сети и прочее. Тем не менее, для рассмотрения того, как работает Hidden Lake нам вполне будет достаточно одного прикладного приложения в роли HLM.
Для запуска сети HIdden Lake подготовлено много разных способов. Так например, мы можем воспользоваться докером и просто запустить сразу все три приложения HLS+HLM+HLT уже связанные между собой. Мы можем скомпилировать такие приложения самостоятельно. А можем и вовсе скачать последние версии приложений с релиза. Так как мы пытались запустить Dissent из исходников (скомпилированные версии я и вовсе не нашёл), то здесь поступим ровно также.
Скачиваем репозиторий https://github.com/number571/go-peer, переходим в директорию cmd/hidden_lake/composite/default/service_messenger и вводим команду make build. Для успешной компиляции необходим компилятор языка Go версии 1.17 или выше.
$ make build ✔
cp ../../../../../cmd/hidden_lake/_default_cfg/hls.cfg .
cp ../../../../../cmd/hidden_lake/_default_cfg/hlm.cfg .
go build -o ../../../../../bin/hlc_sm ./cmd/hlc_sm
for arch in amd64 arm64; \
do \
CGO_ENABLED=0 GOOS=linux GOARCH=${arch} go build -o ../../../../../bin/hlc_sm_${arch}_linux ./cmd/hlc_sm; \
CGO_ENABLED=0 GOOS=windows GOARCH=${arch} go build -o ../../../../../bin/hlc_sm_${arch}_windows.exe ./cmd/hlc_sm; \
CGO_ENABLED=0 GOOS=darwin GOARCH=${arch} go build -o ../../../../../bin/hlc_sm_${arch}_darwin ./cmd/hlc_sm; \
done;
В итоге, в директорию bin переместятся скомпилированные версии связки приложений HLS+HLM для операционных систем MacOS, Windows, Linux и архитектур arm64, amd64. На данном этапе мы можем либо самостоятельно перейти в директорию bin и запустить от туда hlm_sc (приложение под текущую ОС и архитектуру), либо просто воспользоваться командой make run.
$ make run
./../../../../../bin/hlc_sm
[INFO] 2023/08/11 16:46:11 HLS is running...
[INFO] 2023/08/11 16:46:13 service=HLS type=BRDCS hash=31215845...D72F5DA7 addr=08C2E3F5...48D654ED proof=0001308494 size=8192B conn=127.0.0.1:
[INFO] 2023/08/11 16:46:16 HLM is running...
[INFO] 2023/08/11 16:46:18 service=HLS type=BRDCS hash=387026C2...0CA61A6A addr=08C2E3F5...48D654ED proof=0001496192 size=8192B conn=127.0.0.1:
[INFO] 2023/08/11 16:46:23 service=HLS type=BRDCS hash=1EC9CAD7...FB3121E1 addr=08C2E3F5...48D654ED proof=0001185181 size=8192B conn=127.0.0.1:
[INFO] 2023/08/11 16:46:28 service=HLS type=BRDCS hash=188B9574...D9A2E9A8 addr=08C2E3F5...48D654ED proof=0001079271 size=8192B conn=127.0.0.1:
[INFO] 2023/08/11 16:46:33 service=HLS type=BRDCS hash=0EE3515E...3220D848 addr=08C2E3F5...48D654ED proof=0000150822 size=8192B conn=127.0.0.1:
[INFO] 2023/08/11 16:46:38 service=HLS type=BRDCS hash=8F3C1F45...4F8EB74E addr=08C2E3F5...48D654ED proof=0000006201 size=8192B conn=127.0.0.1:
[INFO] 2023/08/11 16:46:43 service=HLS type=BRDCS hash=8F2F7D46...3DD3361F addr=08C2E3F5...48D654ED proof=0000868908 size=8192B conn=127.0.0.1:
Как только мы запустим приложение hlm_sc, то у нас появятся логи, свидетельствующие о том, что происходит генерация трафика от HLS (ядра анонимной сети). Для того, чтобы перейти в HLM, нам необходимо зайти в бразуер и ввести в адресную строку: localhost:9591.
Нас встретит страница about. Для того, чтобы начать пользоваться анонимной сетью, нам необходимо для начала зарегистрироваться, перейдя по кнопке в Sign up.
Регистрация подразумевает собой либо создание приватного ключа, либо его внесение (если таковой уже существует). В нашем случае мы хотим создать приватный ключ, поэтому ничего не заполняем в четвёртом поле. Регистрация является локальной и никакие данные при ней не отсылаются во вне. Вводимые логин / пароль служат для последующего шифрования генерируемого приватного ключа.
Как только вы зарегистрировались, вас автоматически редиректнет на страницу Sign in. Вводим в поля регистрационную информацию: логин и пароль.
Мы вошли в аккаунт, теперь нам доступны новые возможности, а именно - Friends (список друзей) и Settings (собственно настройки). Переходим для начала в Settings.
Здесь мы видим сразу несколько возможностей. Первое - это настройка языка интерфейса. По умолчанию выбран английский язык, но после регистрации и авторизации можно его сменить либо на русский, либо на эсперанто. Второе, что нас на данном этапе больше всего интересует - это соединения. Нам необходимо подключиться либо к уже существующему узлу HLS, либо к ретранслятору в роли HLT. API и того и другого одинакого по способу принятия сообщений, поэтому нам без разницы кто это будет.
В README cmd/hidden_lake существует уже готовый список ретрансляторов (а также хранилищ) к которым можно подключиться.
Всего существует три роли различных соединений. HLS - это непосредственно узел сети, генерирующий трафик. HLTr - это ренстралятор сети, роль которого лишь перераспределять трафик. HLTs - это хранилище сообщений, которое вбирает в себя сообщения и сохраняет их в свою БД,. HLTr очень часто может совмещаться с HLTs, для того, чтобы не только быть хранилищем сообщений, а быть хранилищем трафика. В таком случае HLTr/HLTs предлагает возможность подтягивать трафик, в момент, когда человек был в оффлайне.
Бирюзовый цвет - это соединения с HLS или с HLTr. Синий цвет - это соединения с HLTs. Отличие таковых видов соединений сводится к тому, что HLS и HLTr - это соединения постоянно живущие, пока мы находимся в онлайне. В то время как HLTs - соединение живущее лишь и только в момент авторизации для подтягивания сообщений.
Если бирюзовый цвет становится сервым, то это говорит о том, что мы не можем подключиться к данному узлу/ретранслятору. Возможно он вышел из сети, возможно мы неправильно указали адрес, а может быть у нас не совпадает ключ сети. Ключ сети - это способ разграничивать множество малых подгруп для того, чтобы они не сливались воедино.
Для того, чтобы начать общение, нам необходимо сделать два действия: 1) скопировать свой открытый ключ (нажать на кнопку Ключ в разделе Аккаунт) и передать его своему собеседнику, 2) получить публичный ключ собеседника и поместить его на страницу Друзей.
Как только мы добавили собеседника в друзья, мы можем к нему перейти. При этом можно здесь также заметить поле __iam__. Это можно сказать псевдодруг, коим являемся мы сами. Более простыми словами, это как Избранное в мессенджерах, где вы сами себе можете отправлять сообщения.
Переходим к собеседнику "Мой смартфон". Пишем сообщения, получаем сообщения. Помимо отправления сообщений мы также можем отправлять файлы, но есть сильные ограничения на размер.
Мы можем здесь отправить лишь плюс-минус 3550 байт, то есть примерно 3KiB. Связано это по нескольким моментам.
Первый - это размер генерируемого трафика. HLS всегда генерирует сообщения по 8KiB каждые 5 секунд. Это же делают все другие участники сети. Если бы каждый участник генерировал бы в 5 секунд по 1MiB, то некоторые каналы (например в 100Мбит) могли быть бы перегружены уже при пяти участниках в сети. Поэтому генерируемые сообщения должны быть малыми.
Второй - это служебные или заголовочные байты, в которых указан публичный ключ отправителя, подпись, сеансовый ключ, случайное число (соль), хеш и доказательство работы. В общей сложности все эти заголовочные байты уже занимают больше половины пространства. Связано это в первую очередь тем, что используется 4096-битный RSA ключ.
Алгоритм шифрования RSA был выбран по двум причинам: 1) в языке Go он стандартизирован, 2) нет реализованного, стандартизированного и проверенного ECIES на языке Go даже у сторонних разработчиков. 4096 бит был выбран по причине консервативности. Далее, содержимое файла кодируется в base64 со стороны HLM, уменьшая тем самым размер фактически разрешённого файла ещё на 1/4.
{ "head": { "salt": "b94a7134ad710a563c3377b0b7cceb3b0f5eb9e0a0711bf2d92ffd1d91c75a04dd008b9b10db2b781b44ca6d51e8ef9a", "session": "911bc236a09dd440d3fbdc317689399b8ada6fe3621d974ed669abbe19d5fee00e20dc2489e05b6d893c7df0980439fb746f184cd55477890f456f556a06e53fb33f898cdba7d6bde48bfbc64895dc729a055ddebfc50f03d3f6275daa82f9b1765ac4b1a22a70b34c36621d2dee2dbf8fe8cca34889e38648afbabf4d281419c7a5bc16b74a8c6f485399df9d7ed9c1943daab4d16f7bb619ccf16e7cd5b318cc06858dcc6aa3a342d46b7d85f95a1b83a0c36dc0481f9367eded73cd762680da181ad4ab1750cd7e111f7c3cf2d8ab36f620b39cf7952be7558f9c59e0d4c358b81116a04b612562f103a0d414beca41fdfa5993ee0fcb142340e2eaccfc8dd78fb03abba562fc829d4a751c8e0f76701d10dc495e533a393b82b420f53f8301ad21052a8d164e9cc7f4c56e0f2c5a05208a52070b2422381f0186ca1bd8a95517d6c4eec9ba0dcc0e2c3757151912ec6522709d661bcdbb8b4a65384686bb2315decb838e50c5278169c1b934ba71f4e80c4b8ad02ce6186224b0a397264abf32af5aa43cdcca4166de51004ef5949284983ae451b1883d281847aee49762814ab80a0e1660a8dba2086bacea6e8ab03fef6a27ffc7424d794e18ff90234c52d02337f2349be19625c11ecd71159fcbdb1d96a6193c94379e7120fd52d16c7fc5b541fdfc0630378194638f332f8a02f104f8ceb191ef3b1452260bf0722e", "sender": "66f53e667a81cdf3eedeb168ca18d14e3b4df33efe874c8c8b427070ec87039a5e4ace9d4c610eaeb1ef8dbec678b4966ca1b3144778c3f80d5d4677dc52af8b5401e929280395b57cda30f5068b4a026089f51e39f7a61dc7ff6d38e478f59f67be5373903a9712b9b0a477334c08cb8fbe4afc3ade1264fb85df14786a960f81f82b4277005d0cc2dba51e975c777e5162f3095d438b38a559cfe5fd6198b13cddc3f39132b8623b456aa841242839ce7e60de218e7e5478a3f17632d4e1daf4d0e41a43343da9e3d8dd674ee6dbe34c71dc46c8f70ffd2c5a0450436c6edda8186f6fc9c3234e977389380d7644e7da91ccbfa3def18be37fa6592562c4a72ee828124f84e385e903b1c6690476b98d7bcf0ed3b42d7b4dfb2de295a703bae9129f290ec4bfbbc8ef1ac34ebf2ef0cbcbb74d9d70b3b22d913cc95728d959eb4925d33e63564fa4b531cc8d9cc742c6a1832ef1578f3067aef929b69dd6e96f91aa09d252c1990625e65dcbe5c48a21243f8d5a61c01c73d3344b10b50fe8c7bc5eaccfb4048e228adcac91c46fa340e9dd1b8d29a06469f5100c06f3f285897f98bd3da097bb83025fbf0c9f77911d3a48ec96012d2f70fccdb9b7481d3b4779b470493f35ae461abb4170ae90f018531c4c8e2b9bd40a27a44b5b34d35383436e23fd728a7083a1776d016fa04c2875ead333b4bf879e137dd925261d47cd6909d6fd0fca89c50c7f7010ea2f386df2dfc8470e4415d84507fd0dd2" }, "body": { "sign": "f6de218f325bd46dc91f20ef79961ab5878b85ad9e775c570f4786d8fdc376ac6b964bd51280470ba231acd786e50b8d71fcc1bce1cd947e4a19b5fe034861d2066d9d5a36af8da2cf7aac4f71f387882115b888021550517b726aab778fae682264e55da1e6c69791a4d30e98987ef2fda06795c21f3a009d58e041dd207e66b22d97ed812e3ee3a6fc76d1dc0aec6901d2835fef8959d9f36edfb0cead6801f9fe3771e2ffbce8207dd349e99fd36df141cf96aa14b3e2a5dabfa209861221b0d4b64ee712f75eb893f8a9bb5e0e6bd00598bb30fef128c5f71bcf196f6e65b2de3c67b48f4c7c59817cf4c1b336e46a096dd5344200008efbe636973a5c3fbcf7c81df49518a437b4ca96e01f9f9190558c1996b05e500c06302dc2ec8d0c466d2727ae56ddf61cee519ac5a46737672e4b8a2fe0ca4ee3d74c24c521a22976e7edca1ba3a5a027c5cd647fcefb6d82b2935862a75f3a655a7fdfe5d6ad7991e6ac4869048f7f85bd6f70e4102b70c7ed59a5118c949be8141a78fdb0624845e7a3793ab4dff74fba747d62c40e9244802a8b32a5767f9887a3653254ee2e7734f0a341f792d766adfa08f33aed3e22b1bc57e6079ac5638f64908712cd2cfabe7fef62aea1493e34126bc0d129d2661677404dba31778560c2e8e3371a79609d6322aa8d2fb2ce72cdb0f008940e60b2d9a41f8f474f68eed1934ebb83e8cbb48944aeb5b3ca43db7c5bc63c3892", "hash": "8b17c13830200845bb9603952a61651786157ade10ee34b4a99de4c6ac0a72c6", "proof": "00000000000005dd" } } === ef0689774058b36c424a478699b8b29438144e230cfec234e39704649fa7c51491126bf896161b259d45a4b93cb646c817e51a61ba4c5ffe792e7dd7943e29392198d75b4d41953b285b54610c8934baaede61c24eccca290c8c05c65725d05f4ca1198c74b70a0ac71eb166b3a284e6e4b4b8c1b5338b32c912e8220502a184d8cead5db4964c0de60d4185de0339099da0df69758c82c8cac3a03e171ad0d52dcf2f85a3b04043d2acfb20196d33ec938d53effcd96840cfd1d34354f2275a8ef1fa8aeb65068fe1d5798ca6151b088e034f0b4433db2d25c0ad6d9bf9df467446bae9b9c441c457938d7844d75e2e9b73ab152270f5686a315d96a3a70aa024ab1cf56d2d1d55d0363276cb9f625781ea68c31e9c73662a3587bad1003afe66819c39c2468483228e13734dcb3278f872ac7f7dd2d1976dc5ea5936431ec5a4c3070ddbc46a30fde97adcac3e132c0ae821eb6d343c1abc1819712e9ca48fa2165ef9384f4b76de23b43139c8bdc7aa4aebe9a870735e4f6a037532084b9ac75875347582cd92fb6191c775feba54d648a3d6f1b2e9632531065c4e596af4706ae65e7413aa41b1e82461647f47bd38c59511d278e9a43bdefec7cdbc25b29b12eee51ad4d63e075872726b5d505f4a3e5065495e6dc02d65dfccc7cddf37fc1c4735ad8214415a8ff85096cd75df5221924b291d92a8a591267e0347b0aca0072f74eeafe774f5ae6e5c77df7330ad477fa4231a2c97610f8bbdeeaf05b985f6d4bae1b1e37954afdd84a7b805f1ba905a4d0d4314cc961f3137f579903e55fb56d4ced33e9df07047d6671bbcea235001255cb405be7f8bdddbc4f5589be89a3f48677680a204a4df959973ddc0aa94cf27a1823b553ccea541e7ff8647d85d336cd9528a36b2ab958ca3017b10055bb45041ce4f8edd5e01a40c0d4d7f6480d160d7ff97450a1b24bc560cccf58f11a684384f1c47dda3485ca64b3c087b3d96f7ccef1128e035280105a9b3606bc888edb7849159f51af25f8717730d43036232fb3c9ce61c7b6b26b17fd7373e5ce140923fadccf9b1119be2309e689049c2b794c9716567a711554075a8e0f765c5fc2af77545ba2fd4d5e61dfde5043e1e398c0d4304c7cb0d7303654dd546078a4809e3d97d80259466cd002e6e450a9fd49b162e136753f96c071ab50ab3775bd3c596041fc9b9f36f475b7040484edae38b1d7eafe95fc63135476e309f4abb3296a6a0ef7bde5a4eb744ab31b8f5933ab6723c0883a28a9671747b59bfa69527a387340b236a9eee845ae23c694e57f62f4ecf8dc43c9ad0b977c52c5254edb1aa4fe2008cadc284e3ef3edb60448ee86df701750874dc2b5cacda78e141ecf258cd834a23b6892791693ada327c22ba66f0e9f8940939992b67f0daa5fb09d1553eec54da2469431781eca954075dec593e6a590525191c384187f448c310a7e8145f98647ef04cc870af01bf0ec60b2a56ab94fc8961c3ed541035edc43b0ae4979faf9e944be7bc057fda070e9a32b07058cb4d96f67f402d0dfea0e402771b2d049eaefa43c4697c513b6469222f0caa90d979c6ac51033543296d6bfb7e8e4feb54f9c1654c5c34f5a36a3634575a331637ed4ad40d8cf92aea4230d8d78d17b11ccb2461cceada7cd8f457b67f561acca079ad4ac2c2680598135d85ea74fb05edd594195b38b31f0f920d765e718cbe54cd80bb823d934ee6fa0a59bd713f67d39047da7f8a5db888617da0928df0e3670dafb270f521ce8145d6b12ca87a6893c4afbab06a3475ff0c66ba8d4294f01ef51a68e2ae886392ef4b9565836ba0de338efbb010f00297818b538b3364d633d014eb09f2a1ef95bc5aaeffdc28131ebca9bd72e9fc2c34c1fb35a3c4346bc5aca22f31d9706e3d763d1a11440540d9ab9c5a622a562c77eab1e028d45e2d608449a5b3a16c426dcf7a4d28ee7085675559dd2a4970c4bbf006a1caf467eab6b6a1118e114cb3e24c7e71443fecaceb716fa91f3fd91e4e73cdf8f63c660c97e7e638eb36b6f6fbbdadaffb08bc3f5544343a99e05da3c9d4b782eb54ed4ec6464427c17fd6e6289395a93427828a54e8d07b3d981648abd6f7fe68f3677d50c1e0b7ea598a6cad1df2e970bdad7dea0ee5f703185ce46eb91020afebd713a98a27f0aaa1516885ce973d7379a18adb579e21287f2f7d57bb6b6bb3e5a12fd1b38657d41ece38bda7c8089eb98119c399cc3a11ed33846393956b8a99b90cdb1e5f079d57c75ddd8295cf3ed2cea012cecf03fdab0539a6633c84a7f03fb5c9367db475fe951552a224c35a571efc262491b93bec33229b631d6f7d2b8d52e7f58dcde8baa1add7ada0f988622262d8eea399de25689c3947f6abbbca6a53b1b26ecaa0297a8052570c444e99123e15cb96d6e4bcfaf5d44a70cca321fad057927fcb11352af70eb5cf9cc8e205dba36bd387b92cbd81d6324c912231e8481e4bee3a6a00b2e6def3107e0498367e1327aeb86d9858edd439c64373caf1384f3302c183e8bcad34b2f2d203c4cf89cdfa5ca6d0c1790b10ed99f3f12c26f5daee3cdcbaad9c552130b9a7fff46114e68fea33389662f7f04dd2131b435031b5b405276dc1e93afb568896912bfe396e0f195583750d7e1fbbbf089ab5bccb286597bf4813577e93e96e3fedce91bf019d89eba5825089f86c1552920873512ddc65306af87845da91f52b787f389624faa701dfad6d0aebf1e70753f30ff61a5c701bdaee5e9d402866cebbe31cd1a5a6e803e3f637c77d11a718301dc0a2d7a7f71f12dee2db7538513b5e030a9ee3588c560670425e089f827026ebdc4745be3e4d44d1e913ccff6af7a81be1d766d011bc8573f795e45c9a6d84dab58ca2d37df7077bd5bc2a8a1f103848b5555d8f0dd406901397e2a8d880d32b53dc39e85c7f30488367183385f5e98936fcd9792bb08a32a6aa09cfb7c597600865284f86d987fdb55c33cd5b98e9ce77d4a4d24c92aff426a9c8afced5b3a653bdea1f330799d2a5719e59049a0e94e2107c67b822855f4450191451a3decc0ea751e2ff5c304b1b4b436ab1dabe6b43f7b8848b62ed76e471003127a46b8992237ea474f520e49af79ac8e5a1d88c08127c2b245b4e523421e45dc793d83120a89b4872acb032f1fac9c34c72cfa48a0e3a295f16fc33162e0e3cbc9ec588f829219646cfba8b821ff14be4add5ee7be0fc55b37de5268f9ab1735c54bb24d9e94334b17248769aef00b6871ad2b6c99fbc86018ca839d4740e94797cb7ccdb06aebdc3ff8cb3d45f249c63c936a3debc5fc5c2b6d847108b59e4e30bf8c1cd0f9d4ea467520a046f2a52155e40092d1204b60c9aaca72ba5c66aa9d2c4d41124668373b49184f83649f1ae86a861286efaa2aa7fb84c62fd4ad79f1fe190599d5b06c4bf1f87590f32eb9615c5faad923d5afc49a9200378eef9448bc666645e500e8e1bbec269048ce9bb19deeb7c12c1f385f6d59c3da8b2983b2539449cf70767e04c7435a86fb5b99d1d468e6733a64f496cf58d2e19c4861a4d25c56791fd4b926cbe381f52bb6ff361c9252f2c21bc27e565450ecfef902b5fbc67496960bc3b12267e4f324cdc062003fb531638300fdc63c55249d25d87e88881cb8f22d5bbc3498d6d5815e365d9b74360cb75bc941fd8695a3e311c70ba27bf952f40edf96c3ff611909c8bbcecb72b0fd1eec1ac49d1b1d4b0c1dcdd10f5fb564305057cc12ce7c6ad85db2987b8b3a63a7c42e87b6aacc46f42b154564c414a3eb63c9887e5f2716d48e555dd58606063f01f6dcaddd024755072d7ffc025c4db69fee19c7805249773d52bf8bcf52aff602e17f9844f3a99e498d1246ad840ae7f1a8030b2e2963fec2a972695a0d033024df22565b62d2c548c24c08d4997a946bd14ad847b3b46c7c03f58118a12d0f6d6ea5c457ab7d6103421fa122c08062600372821b3a71ce9f3e37d13a68b91c592796d15cdbc928257d2863b24e855cb4e6c0bdf7d5fe778bdb23b49200e4fe69d7529665a69deb31e35eea752079691e01294f06571cf05e9cfeedd9f6512f1505374fadf9bc34756f8055678bda60cd4261572031aa8b542b24a1515670ff05204b95d21fa7df8d54c2074ae062f4c5819ce20dd617c860e1d04a84e51a27dee826342cad6fd6bec03ed5a689581cbdce52837ce5245bf7045039f2ea4b13e06ae4cded42af5be35b6891010f2aa3eefa4ad76f3780f9952f073ef62edc5e617a96ac6b537401f4cc590741e1f673709daf230c1fedd639d092f1c909f40d8aaed0ccab17bae61799f96fd2141d72afcfb25689e332b7e259a65bf0bc55ca51dbdd92252108d40b4918d407c1898ffa04a7c9084d77dfbe89c05ce565ca850932154b989c5d2fafc3e1803965beb7eed23542fdaf3cf776de21e81062f5019e4987080f239ef496f41d6a54c18ba72d03ba3830d11db10e4f0afd806bbc212f05891bdc20a285e7897e8380e28d5c59dd837a7e5beadd57f73d4e1f239934a28ba4e8d076010535fde9a7cbde321a13499530053d53e8fc204f92ba6d32aea1143e611a9cd9fd9390ea3170de553b9dd334d2a1df8dc68846efaf7e2569eb1b7b7885273727fe1003848458cf5df986cf2b1570919353b4148a3e10ee8c33cee75b6f300b566c86107716ae3022682f4b11e3cfe807bc92b598a65ae60682a422aa7d65692c5ee1cbf586871e2f55839066c1ecf2df40ad69e7f682d387ea01701fc60873dbab4f020514c730ad6151fce8e89a06d750535f8358cce0d77cd829f21fe08a3dabcb6a64d2ff3f3de25dca004a9e925cf8082d273a347ae9b90ea6078aed7da3c61ccc8844415a4fafb40abff420adbbae29ad38d4871b7714a5cd5ee3c0da5afe82901667bcd2164150c1e2fef89e6eac13aa6f95a3e549d12bf064f45865359bb0e57bba5453dc386af84cc0a691052ddaf88dcb6cfb4d95030f602ad78eacb286e0baae3af03b6fe7914ed1619a73d359af47076c535a450a623124b2aa0d789198c6c6e62040844a9eb3f3bfd8a0e99d550bf29f0476d9cb702879dd5402f170669d2cbff11b3b839d94c31da1e0400443a751c266124ef0c592e74b3d2ef0b48116341ac1aa267fb043d62aea255b973eb5ceda6c5be20ddcec5ab87b98df257609d79e872090e0a17e1bfaf76cd855e861e2d64fc8bbe081ea5da25f6ef7ecd5ca767498f76cb37e36745a1f610a467939bd0b07735c3065dcfa29852b752fdd0445cb05efa1c256d0c842cbde28714cef4484736c28acfa9f005683362c13fd65638d3432fa28ce16c8dbbd40cbebb05be25c79e69d58ee551d3550106a4ae0e8aa033d35f7f6db9eff58430c192ed55a07381e5f8a9e04dc733cbe570feaa828f07c20eba343705a58cca67d24682fa3e82cdb5552c926ef56a7bbc400406702a7a40fae9db3ed4a4fdbb6ddf580f8f0521402333564c0f43943c8df600c43ac702ecbd765e69844d841fe38d012c308cc11bb2672fda48c6c3bf77c1c550a5d82d2b7ab39e9eb3462328faa64c4912660ebc998f1682945ebda73583db1a4737eb86387225053b7e0e17a1e1c5d77bc05688505fe7786d692283b0c8a36b09aa731230c454b29856361a3078376dc904115f34d3dc528e95f8df89527ee739741d0e618e351544e47e630db8cfb023f2e01ef80ac4abd655a1d15ef15d4cc824982f34a24562e6885534aa1eea5c5881dc579b9692c1ca33925d267c7d2dfc73b32586a8557bf056bdea2023e4ea3c2b7883c08a9b73cc7c18b0b49d805e93f0897b0875278ab30dc951e20f8ada6422bfc75bda6793f818eebd5a94c75537c4e9fadab1d9048eee91137fadc79c82d18900eaf68c6bf196be307b38684b31203990216a323e5e2f3723bd8d24025b613eb4e134d4066836e8f18f4a696b9b0279c086374c1dd52cdfc27dc7faf1159ea8e9378455c1ffddec68c7278f6e75c81f06c41d4e93a9c42f827d5ead144434ed521ccbd281034c4f4962c60c3f2a74ed1d956d5abebaf3d9078fd97d1d605745c520f9753e4cc8d448b0242045dac90ad184cf1b3ef681f5c5a0f76ebbc0766c11661fd1bfdc54e1b0315aae95d2b0e09633b99ba3d8a0420ae2735e9615f775b67c514666bb4cb0dc6a81777df1c3ffb58a59c1ce8bd3b8173d794a7777e0c053298b6783e17732a92175b86f1f801bbb398b65d011718079f89b647396dbfc01bc3013e6470a872564918ec5eb744630e15101aa8c9272b53f2348c2af7a770f6a46a106e356d011072ff45f90db3f2b57f3867e4b3649f3fba62858f140dd657290e68768a91e3626b30173b8bc355168d172d95a896791e989b72b0abd53972a17afe909714613707aa7ffd99635e7b6570f08b65bc2a9c67484dad11c1eb72ace19a01ca7755865096231107521ec96f16d226e850b124567a490acb6cb505a015cc1bd34263d941e69d07c08913dcf5830b6e4a438118bb973d0eb8cff619af9e59cd2b9917abf66056e051b04cec3b2253378874f24a7fb8684d4579d9e489ff2cd01c7854a49e3da44f470a79d69050a48e5cfb951d7d1554304e163d3c407e439272aa7562f0e82a860aa5bd864a84fe7fa2baf8535d7693ebf8f28cc622fcdb862b373aabc63a4b8ebb5095e67304d1153123e8c36a06c94e673e88d6a3b394233fe06
В результате всего вышеописанного были рассмотрены основные способы анонимизации сетевого трафика внутри заведомо замкнутной и прослушиваемой среды. Помимо самой анонимизации, также были рассмотрены способы сокрытия факта этой же анонимизации. Были приведены примеры использования теоретически доказуемой анонимности на примере сети Hidden Lake.
Можно ли оставаться анонимным внутри государства, которое закрыло весь внешний Интернет?
Введение Существующие популярные анонимные сети, подобия Tor или I2P , хороши своим прикладным использованием, а также относительно хорошей скоростью и лёгкостью настройки. Они также хороши и...
habr.com