После моей первой публикации на Хабре о стеганографии, у меня было много мыслей и в результате много интересных идей. На некоторые идеи меня натолкнули комментаторы предыдущей статьи, к некоторым я пришел сам.
Я видел проблемы стеганографии на примере предыдущего алгоритма, а именно:
Искажение контейнера при больших размерах стегосообщения. В случае, если контейнер слишком мал (или через какие-то другие его характеристики), то его первоначальный вид искажается. В случае с картинкой появляется много шумов, искажается изображение.
Большой размер контейнера. Чтобы скрыть более или менее большое стегосообщения без значительного искажения контейнера нужно выбирать и контейнер побольше. Это может нести различные проблемы. Например, если нужно передать сверхбольшое сообщение, то и размер контейнера должен быть во много раз (сотни, возможно тысячи) раз больше скрытого сообщения. А это в свою очередь может нести угрозу стеганостойкости, так как вероятный противник будет в первую очередь проверять большие изображения. Хотя это можно обыграть и в свою пользу, отправляя много больших файлов. Таким образом противник будет загружен пустой работой и анализом.
Это всегда было главной проблемой стеганографии. И я всерьез задумался над ее решением. Поделюсь с читателями своими результатами.
Ключ. Начну с того, что задумал создавать стеганографические программы с наличием ключа. Первая мысль связана с ключом и стеганографией была в том, чтобы ключ менял неравномерно координаты следующего пикселя (если это изображение), где будет содержится следующая часть информации. Но тут я подумал о другом… А если координаты, которые подходят под следующую часть информации будут формировать ключ. То есть не человек вводит ключ, а алгоритм выдает ключ? Я сразу сел за реализацию.
Сделаю небольшую ремарку о том, что буду в процессе статьи описывать алгоритм теоретически со ссылкой на мою реализацию в Интернете. Одна из причин: охватить и ту часть аудитории, которая не является программистами. Но в конце статьи дам исходный код моих программ.
Также прошу обратить внимание, что беру за контейнер два примера: изображение, текст.
Сначала я подумал о том, чтобы давать координаты по двум осям х и у. Но имея наборы трех цветов в RGB нужно еще и третью ось z, где будет значение от 0 до 2. «Лишняя координата — лишнее значение ключа» — подумал я и сделал как показано на иллюстрации.
Таким образом я расширил ось х втрое, разделив значение RGB по ширине. Наконец я подумал, что и значение y можно перенести в х разместив все по ширине.
Таким образом имеем лишь одну ось х и соответственно только одну координату.
Но это не принципиально. Можно и 2, и 3 координаты. Мне показалось, что с одной координатой размер ключа будет меньше.
Как и в предыдущей, опубликованной на Хабре, программе я хотел бы, чтобы одно из значений цвета соответствовало значению символа в таблице ASCII. Я считаю, что так контейнер может поместить больше информации, впоследствии так оказалось удобнее и по другим причинам. Но в то же время, использование ASCII служат только для наглядности. В более сложных алгоритмах нужен другой подход.
Весь смысл алгоритма будет упираться в то, что он будет искать координату, значение которой будет соответствовать значению символа. То есть, ключ — это последовательность координат.
В случае с сокрытия текста в тексте, то аналогично весь текст-контейнер можно представить как одну строку, каждый элемент которого будет иметь свою координату по оси х.
Можно взглянуть на стеганографическую программу и увидеть ее в действии (спрятать текст в рисунок, спрятать текст в тексте).
Вводим URL изображение и сообщение. В результате получаем ключ. Можно оставить тот же URL изображения, ввести ключ и получить на выходе стегосообщения. Таким образом контейнер совсем не менялся! Значит обнаружить в нем влияния со стороны стегоалгоритмов невозможно, так как их и не было!
Когда я начал тестировать программу, то меня смущали два момента.
Во-первых, меня волновали большие размеры ключа. Они больше стегосообщения. Но сжав ключ любым архиватором меня перестали смущать размеры ключа. Ключ текстовый и поэтому даже, если ключ ~ 60кб, то после сжатия около 500 байт (архивация zip).
Во-вторых, так как ключ пользователь не придумывает, а его выдает алгоритм, то получается так, что при каждой новой передаче информации нужно передавать новый ключ, что является плохим тоном в стеганографии. Но тут я потом увидел больше плюсов, чем минусов.
Первое. Несмотря на то, что алгоритм выдает ключи — их можно использовать бесконечное количество раз, ограниченную лишь опасением их разоблачение. Для этого достаточно брать другой контейнер таким образом, чтобы каждый раз в заданных координатах оказалось другое сообщение. Это можно сделать любым удобным для пользователя способом: перебирать из свободного доступа изображение или создать такое изображение самому. В случае, если контейнер является текстом, то аналогично можно взять тексты из общего доступа или написать его самому. Подумайте только, каждый невинный блог может быть параллельно источником секретной информации. Каждая иллюстрация, каждая статья (даже обычный SEO-текст) может содержать по ключу секретное сообщение!
Второе. Для того же сообщения в заданном изображении может быть множество количество ключей. Моя показательная программа выбирает первую попавшуюся координату, но алгоритм можно изменить так, чтобы избиралась координата из набора доступных случайным образом. Таким образом, можно сформировать много ключей на то же сообщение.
Это можно использовать для различных целей. Приведу несколько примеров.
Пример первый: выявить источник утечки информации. Это можно также разделить на несколько вариантов, но я рассмотрю один. Допустим с первым сообщением и контейнером всем передали разные ключи, но одно сообщение. Со вторым контейнером по тем же ключам каждый, кто имеет ключ получит вариацию того же сообщения, но с определенными изменениями. Утечка информации укажет на владельца ключа «сливающего информацию» (ну или ключ был банально украден). Дальше для этого ключа будет направляться дезинформация для того чтобы поместить злоумышленника в информационный карантин.
Пример второй. Он вытекает из первого. Возможно нам необходимо иногда отправлять различную информацию. Чем это вызвано (разным уровнем доступа, различными задачами итд) не важно, но это может пригодиться. Ключ как-никак соответствует различным координатам и по разным координатами может быть как одинаковая — так и совершенно разная информация.
Кроме того сообщение может передаваться не только одним контейнером и даже не одним типом контейнера. Если стегосообщения передается, например через блог, то часть сообщения может быть в картинке, часть в тексте итд (видео, аудио ...).
Таким образом у данного стеганографического метода есть удивительные преимущества:
Контейнеры являются неограниченными. В одно изображение (например фото) или большой текст (например реферат) может поместиться бесконечное количество сообщений. Конечно надо чтобы изображение было разноцветным чтобы там было все многообразие вариантов. В «Черном квадрате» Малевича стегосообщения передать будет тяжело. Хотя… для других стеганографических методов это и раньше было тяжело.
Например, в таком маленьком изображении как это поместилось сообщение «Привет!». Думаю может поместиться и больше. Правда в целях усиления стеганостойкости следует контейнер брать значительно больше.
Контейнер не поддается деформации. Согласитесь, что это большое преимущество. Как узнать перед нами контейнер или просто изображение / текст / аудио / видео ..., если контейнер не подвергается никаким изменениям?
Теперь нет необходимости уничтожать оригинал, потому что именно оригинал как контейнер и используется!
Наличие многих ключей улучшает стеганостойкость. Как узнать передается в контейнере слово «Да» или «Нет», если как первое, так и второе там можно найти?
Привожу две учебные веб-приложения согласно описанному мной алгоритму. Первая как контейнер использует изображения, а вторая текст.
Скачать 1 (прячем текст в рисунок)
Скачать 2 (прячем текст в текст)
Автор: RDSergij