Несколько лет назад у меня возникла идея, как можно с этим бороться и сделать создание правила для DPI-фильтра невозможным на практике.
Суть идеи заключается в том, чтобы вместо открытых данных пересылать случайные данные, но которые можно по некоторому заранее известному, желательно трудозатратному алгоритму без секретной компоненты, преобразовать обратно в открытые данные.
Таким образом, это не добавит какой-либо секретности в пересылаемые данные, но затруднит их непосредственный анализ без предварительной обработки, которая в масштабах глобального прослушивания повлечет за собой как минимум ложнопозитивные сработки, и как максимум — невозможность справиться с потоком данных с точки зрения требуемых ресурсов.
Для кодирования следует разбить открытые данные на чанки по N бит, затем для каждого чанка нужно брутфорсом подобрать такой случайный блок данных фиксированного размера H, который при декодировании превратится в ожидаемый чанк открытых данных в N бит размером. Пример такой процедуры декодирования — циклически посчитать SHA256 от блока случайных данных 1000 раз, и затем вернуть младшие N бит хэша.
Приведу пример декодирования готовой строки. Допустим, у нас есть следующие бинарные данные:
4b 82 93 6a b5 0f 39 9b 33 18 2a 7d b4 96 c2 f8 | K..j..9.3.*}....
cb 57 49 b7 67 6d f6 c2 9a e2 73 64 54 1f 92 7d | .WI.gm....sdT..}
65 44 12 7e de 07 c2 85 41 15 9e 32 28 3b c5 3a | eD.~....A..2(;.:
0f 16 3a d9 | ..:.
Мы заранее знаем, что открытый текст делился на блоки по 8 бит каждый, и что мы использовали блоки "шифротекста" по 32 бита.
Первый блок — 4b 82 93 6a
.
SHA256 от него = 486b84b02736885238a0d8ba871a78262362f1dfe7422f1d50b257ed6c99bcc3
.
Младшие 8 байт этого хэша в little endian = 0x48
, т.е. "H"
в ASCII.
Следующий блок — b5 0f 39 9b
.
SHA256 от него = 6546ec1ccea61e68c70671b6a04d9a074c0bf024f92d72d9103e78c3641801eb
.
Младшие 8 байт этого хэша в little endian = 0x65
, т.е. "e"
в ASCII.
Продолжая декодирование таким же образом, получим строку "Hello, world!"
.
Q: Хотя ваш алгоритм и «трудозатратный», но с другой стороны он не увеличивает количество ложнопозитивных срабатываний, а наоборот уменьшает их.
Что я имею в виду. Если мы знаем алгоритм и применяем его ко всем пакетам, то с очень большой вероятностью только «ваши» пакеты на выходе дадут что-то осмысленное, т.к. вероятность что что-то осмысленное получится после 1000 раундов SHA256 очень мала, а умножив это на количество блоков мы получим вообще исчезающе малую величину.
Мне кажется чтобы увеличить количество ложноположительных срабатываний нужно наоборот использовать «нестойкие» алгоритмы которые с большей вероятностью будут выдавать нечто «осмысленное».
A: Вы не совсем правы. В предложенной мной схеме речь не идет о поиске такого прообраза, после хэширования которого мы получим "осмысленный пакет" (т.е. некую фиксированную битовую последовательность) — вероятность угадать такой прообраз, учитывая, что выхлоп сильной хэш-функции можно полагать случайным, составляет 2**(-N), где N — длина искомого "смысла". 100-битный осмысленный пакет можно искать неимоверно долго, и абсолютно впустую — добывать биткоины при таком количестве свободного времени и ресурсов явно выгоднее :)
Предложенную схему не стоит рассматривать как средство сокрытия информации — очевидно же, что если ваш пакет начинается с "Lorem ipsum" (88 бит), то каждый 309485009821345068724781056-й в среднем пакет должен будет "расшировываться" в "Lorem ipsum", и если наблюдаемая частота таких сообщений значительно превышает ожидаемый среднестатистический, то это "бжжж" тут явно неспроста.
Суть же предложенной мной схемы как раз заключается в том, чтобы сделать слежку невозможной именно в глобальных масштабах, основываясь на, скажем, эдаком proof-of-work. Если невозможно заранее, глядя только на мусорные блоки, отличить их от настоящего мусора, то атакующей стороне в любом случае потребуется потратить энное количество ватт (времени, денег) на вычисление хэш-функции от этого мусорного блока.
И если поток сквозных данных превысит возможности атакующей стороны по вычислению хэшей, им придется либо пропускать часть трафика, либо в принципе отказаться от идеи вычислять хэши для произвольных данных. Причем инициатору соединения даже необязательно использовать истинно случайные блоки — можно притворяться чем-то другим, лишь бы все еще было достаточно степеней свободы для подбора хэша с требуемыми свойствами.
Утрируя, мы можем передавать 1 бит данных в 128 битах мусора. Уже даже с такой избыточностью невозможно составить таблицу соответствия мусорных данных истинным данным, значит, DPI-фильтру придется "играть честно", и чем сложнее будет для вычисления хэш-функция (pbkdf2? scrypt? bcrypt?), тем меньшее количество сообщений выйдет декодировать, потратив 1 кВт, и тем быстрее правительству^W атакующей стороне это надоест.
Ну а процент "ложноположительных срабатываний" у этой схемы и так статистически неотличим от шума, куда уж лучше?