Тайные каналы связи или как централизованные сервисы способны разлагаться изнутри

Введение

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

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

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

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

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

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

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

Альтернативы?

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

  1. Клиент-безопасные приложения. Отличительной особенностью данного вида приложений, в сравнении со множеством других, является доказуемая безопасность сетевых коммуникаций исключительно клиентской стороной. Иными словами, это говорит о том, что даже если информация будет передаваться серверной стороне или храниться на ней, то сервисы всё равно не смогут проанализировать или видоизменить такого рода данные, т.к. они находятся в зашифрованном или аутентифицированном виде. Частным случаем такого вида коммуникаций является сквозное (end-to-end) шифрование. К такому виду приложений, как пример, относятся RetroShare, Freenet, Bitmessage и т.д.

  2. Анонимные (скрытые) сети. Отличительной особенностью данного вида приложений становится либо сокрытие факта передачи информации от точки A до точки B, либо сокрытие связи между точками A и B. В отличие от клиент-безопасных приложений, анонимные сети представляют собой исключительно способ маршрутизации между абонентами системы. Это говорит о том, что принимающая сторона, в виде точки B может являться централизованным сервисом связи, и как следствие, нарушать конфиденциальность информации. В следствие этого, необходимо объединять клиент-безопасные приложения с анонимными сетями, чтобы достигнуть и безопасности передаваемой информации и анонимность её субъектов. К тому виду приложений, как пример, относятся Tor, I2P, Mixminion и т.д.

  3. Тайные каналы связи. Не являются сугубо монолитными решениями, а скорее представляют собой некую оболочку либо над клиент-безопасными приложениями, либо над анонимными сетями. Исключительной особенностью тайных каналов связи является их теоретическая способность внедряться в любые уже выстроенные виды коммуникаций, вследствие которых итоговая связь между субъектами становится безопаснее изначальной. За счёт такого критерия, тайные каналы связи становится возможным применять в централизованных сервисах, не выделяя при этом собственные сервера и память для хранения всей поступаемой информации. Комбинация «тайный канал связи + клиент-безопасное приложение» может быть реализовано при помощи PGP/GPG программ, когда информация зашифровывается локально и передаётся принимающему абоненту через централизованный сервис связи. Комбинация же «тайный канал связи + анонимные сети» куда более интересна и нигде ранее в литературе не рассматривалась, а поэтому данная статья большую часть внимания будет уделять именно такой концепции.

Абстрактные анонимные сети

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

Чтобы ответить на данный вопрос, нам необходимо спроектировать такую анонимную сеть, для которой были бы незначимы следующие явления как: 1) высокий уровень централизации; 2) открытость и известность IP-адресов; 3) отсутствие маршрутизации; 4) количество узлов в сети; 5) отключение узлов от сети; 6) замедление или ускорение трафика. На первый взгляд кажется, что такого рода комбинацию невозможно спроектировать и тем более реализовать.

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

Проектирование абстрактных сетей

На самом деле спроектировать такую сеть не является сильно сложной задачей, ровно как и её реализация. Так например, можно реализовать абстрактную анонимность на базе уже готовых анонимных сетей, но лишь с одним условием — чтобы их анонимность была теоретически доказуемой. К такому виду анонимных сетей относятся DC-сети на базе проблемы «обедающих криптографов». Помимо прочего, существуют ещё более «элегантные» проблемы, как например задача «на базе очередей».

Теоретически доказуемая анонимность

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

Проблема обедающих криптографов

Выглядит она так (не буду пересказывать о том, как криптографы обедают и о том, что существует некий АНБ, раскажу вкратце): существует три участника сети {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 бит информации полностью анонимно (конечно же со стороны определения теоретически доказуемой анонимности).

Предположим, что один из участников, либо B, либо C захочет деанонимизировать либо {A, C}, либо {B, C} соответственно (то есть узнать, кто является отправителем информации). Тогда ему потребуется узнать согласованный секрет со стороны другой линии связи, что является сложной задачей (если конечно не был произведён сговор нескольких участников). Таким образом, атака со стороны внутреннего пассивного наблюдателя становится безрезультатной. Со стороны внешнего глобального наблюдателя такая же ситуация, потому как он видит лишь переадресацию зашифрованных битов (потому как используется безопасный канал связи) в один момент времени T всеми участниками сети.

Сами по себе DC-сети не являются абстрактными анонимными сетями, но при этом наиболее приближены к ним. Так например, для анонимизации трафика им безразличны такие условности как: 1) открытость и известность IP-адресов; 2) отсутствие маршрутизации; 3) количество узлов в сети; 4) отключение узлов от сети; 5) замедление или ускорение трафика. Единственное, что отделяет DC-сети от абстрактных сетей, является критерий высокого уровня централизации. Проблема обедающих криптографов предполагает, что все субъекты будут соединены между собой при помощи связи «один-к-одному». Если же изменить вид связи на «все-к-одному», то последний, кто будет содержать все коммуникации воедино и будет являться деанонимизирующим узлом. Чтобы избавиться от такого явления, нужно исключить необходимость в связи «один-к-одному». Это можно сделать следующим образом: каждый субъект заранее согласовывает свои ключи со всеми остальными субъектами, но использует централизованный узел исключительно в качестве ретранслирующей функции. Таким образом, нарушается прямолинейная связь «один-к-одному», но образуется свойство абстрактности. Чтобы облегчить передачу ключей между всеми участниками сети, можно воспользоваться асимметричной криптографией.

Задача на базе очередей

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

Вкратце суть задачи на базе очередей сводится к следующему: предположим, что существует три участника {A, B, C}. Каждый из них соединён друг к другу (не является обязательным критерием, но данный случай я привёл исключительно для упрощения). Каждый субъект устанавливает время генерации информации = T. У каждого участника имеется своё внутренее хранилище по типу FIFO (первый пришёл — первый ушёл), можно сказать имеется структура «очередь».

Задача на базе очередей

Задача на базе очередей

Предположим, что участник A хочет отправить некую информацию одному из участников {B, C}, так, чтобы другой участник (или внешний наблюдатель не знали, что существует какой-либо факт отправления. Каждый участник в определённый период T генерирует сообщение. Такое сообщение может быть либо ложным (не имеющее никакого фактического содержания и никому по факту не отправляется, заполняясь случайными битами), либо истинным (запрос или ответ). Отправить раньше или позже положенного времени T никакой участник не может. Если скопилось несколько запросов одному и тому же участнику, тогда он их будет ложить в свою очередь сообщений и после периода T достанет из очереди и отправит в сеть. Таким образом, сама структура задачи на базе очередей есть множество последовательно выстроенных очередей, в отличие от единственной очереди в DC-сетях.

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

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

  1. HLS — ядро анонимной сети с теоретически доказуемой анонимностью на базе очередей.

  2. HLM — анонимный мессенджер построенный на базе ядра HLS.

  3. HLT — приложение сохраняющее и перераспределяющее трафик HLS.

Возврат клиентского паразитизма

С учётом всего вышеописанного, становится возможным использовать комбинацию «тайный канал связи + абстрактная анонимная сеть». Основная суть задачи будет заключаться в сохранении анонимизирующего трафика, но таким образом, чтобы использовать сторонние ресурсы — централизованные сервисы, в качестве основного способа сохранения и перераспределения информации. Иными словами, мы будем являться некого рода паразитами, использующими вычислительные ресурсы совершенно по иному назначению, чем это изначально предполагалось создателями подобных сервисов.

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

В реализации подобного тайного канала связи мы будем использовать композицию Hidden Lake приложений, а именно — HLS (service), HLM (messenger) и HLT (traffic). Вкратце, всю архитектуру можно представить в виде следующей схемы.

Архитектура тайного канала связи при использовании HLS, HLM и HLT

Архитектура тайного канала связи при использовании HLS, HLM и HLT

На данной схеме есть несколько ключевых моментов и терминологий.

  1. Payload — это информация в открытом, незашифрованном виде, в то время как Message — это информация в закрытом, зашифрованном виде.

  2. HLS работает с TCP протоколом во внешней сети и с HTTP протоколом во внутренней сети. Данный сервис хранит на своей стороне исключительно хеш-значения получаемых или отправляемых сообщений типа Message.

  3. HLM представляет собой исключительно графический интерфейс с БД, хранящей открытую информацию — отправляемые и получаемые сообщения типа Payload.

  4. HLT является сервисом необходимым для перераспределения трафика от HLS. Можно сказать, что HLT лишь эмулирует поведение HLS с целью получения сырых сообщений типа Message.

  5. HLT перенаправляет сообщения типа Message на сервис Sender. Sender представлен в роли потребителя (consumer) информации для HLT, суть которого сводится к преобразованию сырой информации типа Message в оболочку F (Message) таким образом, чтобы Service смог успешно сохранить полученную им информацию. Иными словами, оболочку F можно также назвать интерфейсов конечного сервиса.

  6. HLT принимает сообщения типа Message от сервиса Receiver. Receiver представлен в роли производителя (producer) информации, суть которого сводится к постоянным проверкам обновления списка сообщения со стороны субъекта Service. Можно сказать, что Receiver выполняет обратные операции в сравнении с Sender, то-есть F (Message) → Message.

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

Архитектура анонимизации трафика при использовании HLS и HLM

Архитектура анонимизации трафика при использовании HLS и HLM

Как видно из этого схема получается достаточно простой, но и более абстрактной, потому как Network можно представить в виде суммы (HLT + Sender + Receiver + Service). За счёт такой абстрагируемости мы можем легко переключаться между Network и комбинацией с участием HLT. Также можно сказать, что Sender и Receiver представляют собой адаптеры, которые переводят один тип сообщения в другой.

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

Реализация тайного канала связи

Предположим, что существует некий централизованный сервис у которого присутствуют функции push (загрузки сообщений), load (выгрузки сообщений) и size (количество сообщений). Этого будет вполне достаточно для последующей реализации адаптеров Sender и Receiver.

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

func trafficPage(hostService string, portService int) func(w http.ResponseWriter, r *http.Request) {
	return func(w http.ResponseWriter, r *http.Request) {
        // HLT отправляет POST запросы потребителям
		if r.Method != http.MethodPost {
			api.Response(w, 2, "failed: incorrect method")
			return
		}

        // Получаем Message от HLT
		res, err := io.ReadAll(r.Body)
		if err != nil {
			api.Response(w, 3, "failed: read body")
			return
		}

		// Конвертируем Message в формат сервиса 
		_, err = api.Request(
			http.MethodPost,
			fmt.Sprintf("%s:%d/push", hostService, portService),
			F(res),
		)
		if err != nil {
			api.Response(w, 4, "failed: bad response")
			return
		}

		api.Response(w, 1, "success: push to service")
	}
}

Продолжим кодом Receiver’a. Данный код более сложный, потому как должен: 1) сохранять номер сообщений со стороны сервиса; 2) должен постоянно прослушивать новые сообщения поступаемые на сервис.

for {
        // Задержка должна быть меньше периода генерации сообщений
        // в HLS, но и не сильно низкой, чтобы сервис не начал
        // блокировать.
		time.Sleep(time.Second)

        // Пытаемся узнать у сервиса количество сообщений.
		strCount, err := api.Request(
			http.MethodGet,
			fmt.Sprintf("%s:%d/size", hostService, portService),
			nil,
		)
		if err != nil {
			fmt.Println(err)
			continue
		}

		countService, err := strconv.ParseUint(strCount, 10, 64)
		if err != nil {
			fmt.Println(err)
			continue
		}

        // Получаем последнее количество сообщений которое мы смогли прочитать.
		countDB, err := countOfDataInDB()
		if err != nil {
			fmt.Println(err)
			continue
		}

        // Получаем новые сообщения с сервиса.
		for i := countDB; i < countService; i++ {
			data, err := api.Request(
				http.MethodGet,
				fmt.Sprintf("%s:%d/load?data_id=%d", common.HostService, portService, i),
				nil,
			)
			if err != nil {
				fmt.Println(err)
				continue
			}

            // Получаем сообщение и сервиса и преобразуем его
            // вид для сервиса HLT
			msg := message.LoadMessage(
				iF(data),
				message.NewParams(
					hls_settings.CMessageSize,
					hls_settings.CWorkSize,
				),
			)
			if err := hltClient.PutMessage(msg); err != nil {
				fmt.Println(err)
				continue
			}

            // Повышаем количество загруженных сообщений на единицу.
			incrementCountInDB()
		}
	}

Хоть данный пример и является в некой степени лабораторным, на нём очень легко рассмотреть основные особенности. Во-первых, такой пример более детерминирован для последующих тестирований, нам не надо полагаться на сторонний сервис, который может со временем изменить структуру своих запросов и ответов. Во-вторых, для реализации адаптеров нам нет надобности знать исходный код самого сервиса, нужно лишь знать основные запросы 1) на получение количества новых или всех сообщений; 2) на отправление одного или множества новых сообщений; 3) на получение одного или множества существующих сообщений. Всё это можно посмотреть буквально в браузере, выкачав нужные cURL запросы с заголовками и куками. В-третьих, если централизованный сервис легко позволяет регистрироваться и авторизироваться без привязки к номеру телефона (или чего подобного), то один и тот же аккаунт может использовать группа клиентов, что будет проще для коммуникации.

Теперь давайте проверим, будет ли работать и функционировать прикладное приложение HLM, при котором множество HLS не связываются напрямую, а проходят сквозь централизованный сервис связи посредством HLT и адаптеров. Все исходные коды приложений находятся полностью в открытом доступе: HLS, HLM, HLT. Вы также можете проверить их работоспособность в директории examples/_cmd.

Переходим в директорию examples/_cmd/anon_messenger/secret_channel и запускаем make. Запустится два узла с комбинациями HLS+HLM+HLT, у каждого из которых будут одинаковые адаптеры Sender и Receive. Также запустится централизованный сервис, через который будет проходить весь анонимизирующий трафик.

Открываем localhost:8080 и localhost:7070. Это те самые два узла, которые были запущены.

Начальная страница HLM

Начальная страница HLM

Переходим в Sign in и авторизируемся как user/password. Данные записи уже были созданы для тестов, в которых также хранится список друзей. Т.к. пользователей всего два, то они хранят публичные ключи друг друга. Переходим в список друзей и пишем друг другу сообщения.

Отправление и получение сообщений в HLM

Отправление и получение сообщений в HLM

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

Логи от сервисов HLS и HLT со стороны одного узла

Логи от сервисов HLS и HLT со стороны одного узла

По логам мы также можем увидеть, что каждый период времени = T (в контексте HLS это 5 секунд) генерируются сообщения. Это основной механизм работы задачи на базе очередей.

Вышеописанный пример может быть достаточно тяжеловесным для изучения, потому как содержит в себе ещё и использование HLM, который, как я ранее упоминал, не является ключевым механизмом. Поэтому для более лёгкой реализации можно продемонстрировать echo_service, который находится на одном из узлов. Для этого примера нам необходимо перейти в директорию examples/_cmd/echo_service/secret_channel и запустить make. Также запустятся два узла HLS+HLT, на них адаптеры Sender+Receiver и отдельно запустится сервис связи.

Для проверки перейдём в директорию ниже, в examples/_cmd/echo_service и запустим скрипт request.sh. Получим ответ return=1 (что является кодом без ошибки) и полученный ответ в result в hex кодировке. Если декодируем, то получим сообщение {"echo":"hello, world!","return":1}, что является ответом от сервиса в HLS.

Полученный результат скрипта обращающегося к echo-сервису на одном из узлов

Полученный результат скрипта обращающегося к echo-сервису на одном из узлов

Скрипт request.sh

#!/bin/bash

str2hex() {
    local str=${1:-""}
    local fmt="%02X"
    local chr
    local -i i
    for i in `seq 0 $((${#str}-1))`; do
        chr=${str:i:1}
        printf "${fmt}" "'${chr}"
    done
}

JSON_DATA='{
        "method":"POST",
        "host":"hidden-echo-service",
        "path":"/echo",
        "head":{
            "Accept": "application/json"
        },
        "body":"aGVsbG8sIHdvcmxkIQ=="
}';

PUSH_FORMAT='{
        "receiver":"PubKey(go-peer/rsa){3082020A0282020100B752D35E81F4AEEC1A9C42EDED16E8924DD4D359663611DE2DCCE1A9611704A697B26254DD2AFA974A61A2CF94FAD016450FEF22F218CA970BFE41E6340CE3ABCBEE123E35A9DCDA6D23738DAC46AF8AC57902DDE7F41A03EB00A4818137E1BF4DFAE1EEDF8BB9E4363C15FD1C2278D86F2535BC3F395BE9A6CD690A5C852E6C35D6184BE7B9062AEE2AFC1A5AC81E7D21B7252A56C62BB5AC0BBAD36C7A4907C868704985E1754BAA3E8315E775A51B7BDC7ACB0D0675D29513D78CB05AB6119D3CA0A810A41F78150E3C5D9ACAFBE1533FC3533DECEC14387BF7478F6E229EB4CC312DC22436F4DB0D4CC308FB6EEA612F2F9E00239DE7902DE15889EE71370147C9696A5E7B022947ABB8AFBBC64F7840BED4CE69592CAF4085A1074475E365ED015048C89AE717BC259C42510F15F31DA3F9302EAD8F263B43D14886B2335A245C00871C041CBB683F1F047573F789673F9B11B6E6714C2A3360244757BB220C7952C6D3D9D65AA47511A63E2A59706B7A70846C930DCFB3D8CAFB3BD6F687CACF5A708692C26B363C80C460F54E59912D41D9BB359698051ABC049A0D0CFD7F23DC97DA940B1EDEAC6B84B194C8F8A56A46CE69EE7A0AEAA11C99508A368E64D27756AD0BA7146A6ADA3D5FA237B3B4EDDC84B71C27DE3A9F26A42197791C7DC09E2D7C4A7D8FCDC8F9A5D4983BB278FCE9513B1486D18F8560C3F31CC70203010001}",
        "hex_data":"'$(str2hex "$JSON_DATA")'"
}';

d="$(date +%s)";
curl -i -X POST -H 'Accept: application/json' http://localhost:7572/api/network/request --data "${PUSH_FORMAT}";
echo "Request took $(($(date +%s)-d)) seconds";

Заключение

На основе всего вышесказанного мы смогли воспользоваться (и сможем пользоваться) централизованными сервисами связи с целью безопасного и анонимного общения посредством тайных каналов связи. За счёт хорошей абстрагируемости сервисов HLS, HLM и HLT между собой, нам оставалось лишь реализовывать адаптеры (сервисы) типа Sender и Receiver для конечного сервиса.

Вся данная статья не могла быть быть написана без теоретической базы, которой являются такие статьи как Теория строения скрытых систем, Монолитный криптографический протокол и Абстрактные анонимные сети. Данные работы также находятся полностью в открытом доступе на github репозитории.

© Habrahabr.ru