Привет, Хабр. Некоторое время назад решил разобраться, что такое стеганография, в чем её смысл и какая она бывает. И спустя несколько ссылок наткнулся на интересную статью про хэш-стеганографию. Возник вопрос — а почему бы не попробовать реализовать такой способ передачи на практике? Для начала — в виде proof of concept.
image


Хэш-стеганография?


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


Тут на помощь приходит хэш-стеганография. Смысл прост — мы берем контейнер (лучший вариант — картинку с котиками) и берем от неё хэш. Отрезаем от хэша 1 (2,5,10) символ — допустим, получили букву z. Берем еще 25 картинок и если нам повезло, то мы получили некий словарь, содержащий в себе 26 записей вида "буква" — "картинка". Если не повезло, придется перебрать больше картинок. Таким образом, имеем алфавит, который можно использовать для отправки сообщений. Загружаем на сервер 10 определенных котиков, получатель их загружает с сервера, получает хэш, отрезает по 1 символу и получает "HelloWorld". А если еще и зашифровать это...


image


Что из этого получилось и причем здесь vkapi?


Итак, задача ясна — нужна программа, которая будет получать на вход сообщение, сжимать его, шифровать, превращать в котиков, отправлять на сервер. На той стороне нужно получать картинки, превращать в буквы, расшифровывать, "разжимать".


Теперь нужен удобный интернет сервис, который давал бы возможность свободно (в известной степени) загружать картинки на сервер и обратно. Я выбрал vk.com. Все нужно для нас там есть — удобные альбомы, которые сохраняют порядок загруженных фотографий, приятный api.


И последнее — нам где-то нужно хранить очень много картинок. Была выбрана MongoDB. Там хранятся записи вида "путь к картинке — хэш картинки — дата последнего использования". Находим нужный хэш, выбираем картинку, которая использовалась давно, загружаем, используя представленный путь.


И это работает?


Да, и это действительно работает. После загрузки и установки запускаем программу:


python vkhs.py -e -l [login] -aid [album id] -m HelloHabr

Password:
message = HelloHabr
len = 10

chip = b'....'
len = 18

upload message?
Total uploaded: 18

Бежим смотреть, что у нас получилось:



Мы получили сообщение, состоящее из 18 картинок. Это не вызывает подозрений — особенно если картинки на одну тему.


Теперь нужно получить наше сообщение:


python vkhs.py -l [login] -aurl [albumxxxxxxxx_xxxxxxxxx]

Password:
Login success
1
2
3
4
...
message: HelloHabr
очистить папку с фалами?

Вуаля, скрытый чат работает.


Проблемы


Вот некоторые из них:


  1. Алгоритм сжатия — как видно на предоставленных скринах, сообщение длинной в 11 символов превращается в сообщение длинной в 18 символов. На большой длине сообщения, этот алгоритм работает прекрасно, уменьшая больше чем в два раза исходный текст. На маленькой — ужасно.
  2. БД. Её нужно регулярно обновлять. Однако vk использует весьма интересный способ хранения фотографий. Когда мы заливаем туда фотографию, сервер автоматически её сжимает — значит изменяется и хэш. Однако, есть фотографии, хэш которых не изменяется. Причины я так и не понял. И поэтому заполнение БД происходит по следующему алгоритму — загружаем из интернета картинки (в идеале — сами фотографируем красивые пейзажи в парке). Затем заливаем их на сервер вк, загружаем обратно. Теперь снова заливаем, сохраняя хэши в бд, снова загружаем обратно. Проверяем изменившиеся, удаляем и повторяем процедуру. После "просеивания" остаются те фотографии, которые "нравятся" серверу. Их и загружаем в БД.
    Как можно увидеть, операция не очень приятная, нужно подумать, как сделать получше. Однако существуют так называемые сравнимые хеши. Например на хабре была классная статья. Для обхода данной "случайной атаки" вместо обычного хеша можно брать сравнимый хеш.

Заключение


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


Все материалы, касающиеся этого проекта представлены в моем репозитории.


Хочу выразить благодарность пользователю PavelMSTU за помощь в разработке концепции программы и данной статьи.

Комментарии (18)


  1. alekseev_ap
    21.03.2018 22:36

    Всё это очень интересно, но КПД такой системы чрезвычайно низкий. Сколько надо отправить десятков (а то и сотен) килобайт чтобы передать строку из нескольких слов?!


    1. PavelMSTU
      22.03.2018 11:05

      Истинно так. Нужно заменить контейнер на что-то более «лёгкое». Например на строку в *.csv датасетах…
      Тогда скорость будет на полтора-три порядка выше.
      Вечером пост накатаю.


  1. Ockonal
    22.03.2018 00:09

    Куда интересней вшивать в картинку информацию


    1. sdore
      22.03.2018 00:33

      А ещё интересней генерировать из данных неподозрительную картинку по определённому алгоритму.


      1. sdore
        22.03.2018 14:31
        +1

        Вижу плюсики моей идее. Что, закодить, что ли? Да, пожалуй. С меня пост.


        1. PavelMSTU
          22.03.2018 17:26

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

          Думаю классный пост получиться!!!


        1. alekseev_ap
          22.03.2018 20:42

          Было бы интересно посмотреть. Вроде и программы такие уже есть, но, я вот, тоже пытался изобрести велосипед. Думаю, всем понятно, что инъекция полезной информации в картинки принципиально отличается для BMP, JPG, GIF и PNG. Самое интересное (по моему мнению) — это стеганография в JPEG, т.к. это самый популярный формат. В связи с этим предлагаю соревнование в этой области, кто больше сможет зажать полезной информации в заранее подготовленный набор JPEG изображений.


  1. Sklott
    22.03.2018 09:05

    Проблема вашего алгоритма как всегда у новичков в криптографии в том что это «security through obscurity». Плюс к этому если в одном сообщении использовать картинки более одного раза, можно напороться на частотный анализ.
    Т.е. «безопсный чат», будет безопасен ровно до тех пор, пока не известен алгоритм. Нормальную стеганографию нельзя обнаружить/сломать даже если известен алгоритм, но неизвестен ключ.


    1. Gorthauer87
      22.03.2018 10:43

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


    1. jahr
      22.03.2018 16:06

      Я, возможно, не совсем правильно все это понимаю, но мне кажется, ключем здесь будет выбор альбома в vk. Знание описанного алгоритма никак не поможет вам отличить альбом со скрытым сообщением от просто альбома, а это и будет максимально возможной security в случае стеганографии, разве не так?


      1. Sklott
        22.03.2018 16:22

        В некотором смысле да. Но этого мало. Как вы думаете насколько сложно найти одно осмысленное предложение в гигабайте мусора?
        На самом деле не очень.
        Тут как с историей про неуловимого Джо… Пока ты никому нафиг не упал, можно и без стеганографии обойтись. А как кому-то понадобился — этого уже мало…


        1. jahr
          22.03.2018 17:05
          +1

          Насколько я вижу в коде примера — сообщение шифруется при помощи AES перед кодировкой, т.е. «осмысленное предложение» будет неотличимо от этого «гигабайта мусора», найти его не получится в принципе ни у ФСБ, ни у АНБ. Так что неуловимый Джо здесь не при чем, никакой security through obscurity здесь нет, чат будет безопасным.

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


  1. semen-pro
    22.03.2018 11:11

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


    1. ToshiruWang
      22.03.2018 12:14
      +1

      «А вечером в танце я передаю сообщение» (Ц)


  1. KorDen32
    22.03.2018 17:29

    Однако, есть фотографии, хэш которых не изменяется. Причины я так и не понял.

    Ориентировочно — если размеры jpeg-картинки меньше каких-то (что-то около 2000 px по каждой стороне) и bits per pixel меньше какого-то значения — как минимум "загрузить оригинал" возвращает исходное изображение.


    Так, скажем, картинка 1200x1150 размером в 180 кб не будет изменена. А размером в 900кб — сожмется.