DarkJPEG: cтеганография для всех



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

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

Сервис использует стойкие методы стеганографии для сокрытия самого факта сокрытия информации вместе со стойкими методами криптографии для защиты данных, передаваемых по открытым каналам, от компрометации (факта доступа посторонних лиц). Исходные тексты проекта распространяются в рамках лицензии MIT.

Основные особенности:

  • Использование SHA-3 для генерации ключей;
  • Симметричное шифрование AES-256;
  • JPEG (DCT LSB) стеганография;
  • Поддержка RarJPEG и двойного сокрытия;
  • Подбор случайного контейнера;
  • Вычисления без участия сервера;
  • Гарантия полной конфиденциальности.


Intro


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

Как всё началось


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

Метод


Для начала было изучено около десятка научных статей, раскрывающих то, какие вообще бывают методы стеганографии, их особенности реализации, анализ и детектирование. В качестве контейнеров было решено использовать изображения в формате JPEG, как самый распространённый тип контента в Интернете. На проверку, как оказалось, одни методы довольно легко выдают себя, используя нестандартные матрицы квантования, другие не проходят гистограммный тест, третье дают полезный объём порядка 9-13% размера контейнера, то есть если бы мы хотели спрятать 500Кб полезной информации, контейнер бы пришлось искать размером не менее 5Мб, а это довольно грустно.

В итоге, исследовав принцип работы довольно новых стеганографических методов F5 и на основе ошибки квантования, было решено использовать простой и банальный LSB (least significant bits), дополнив его предварительным шифрованием данных AES-256, что помимо возможности использования 256-битного ключа для кодирования, даёт на выходе псевдослучайную последовательность бит, чего как раз и добиваются в F5, путём случайных перестановок блоков данных. Таким образом, вот схематичное представление работы метода:

  1. берём 256-битную SHA-3 хэш-сумму введённого пользователем пароля + случайно сгенерированной соли;
  2. шифруем данные + заголовок (сигнатура, имя и размер вкладываемого файла) с помощью AES-256, добавляем в начало соль, в конец 0xFFD9 — маркер JPEG End of Image (о том зачем это сделано будет чуть ниже);
  3. подбираем контейнер, размером подходящий под наши данные, переводим цвета из RGB в YCbCr;
  4. над каждым блоком 8х8 пикселей производим дискретное косинусное преобразование;
  5. в последние два бита каждого ненулевого коэффициента понемногу записываем наши данные;
  6. коэффициенты сжимаются с использованием кодирования серий и кодов Хаффмана.

Как видно, в процессе JPEG-кодирования был пропущен шаг квантования коэффициентов с использованием соответствующих матриц, вместо которых в файл записываются одни единички — тем самым имитируется сжатие изображения с качеством 100%, что с одной стороны, конечно, заметно раздувает размер файла (прибавляя полезный объём для данных), с другой уменьшает подозрения, так как подобные единичные матрицы квантования совсем не редкость. Ура! Всё получилось! Полученный файл является полностью валидным JPEG с порядка 20% объёма, занимаемого нашими данными, его и смело отдаём пользователю. Декодирование осуществляется по подобной, обратной схеме.

Склейка и RarJPEG


На деле оказалось, что подобный метод даже довольно избыточен, на практике обычно хватает (если только не прячем что-то действительно серьёзное!) обычного добавления в конец JPEG файла наших зашифрованных данных. Вот здесь-то и пригождается фальшивый маркер конца картинки, который мы добавляем вручную — он хоть немного, но убирает подозрения от нашего приклеенного хвоста. Конкатенация файлов даёт ещё такую забавную возможность, как создание и обработка RarJPEG`ов, необходимо лишь приклеивать ZIP или RAR-файл и пропустить шаг с шифрованием, указывая пустой пароль, тогда до скрытого контента можно легко добраться, если полученную картинку открыть практически любым архиватором (но эта картинка по-прежнему валидный JPEG!)

Что в итоге


Таким образом, у нас есть три доступных варианта стеганографии: auto, join и steg. Авто по умолчанию (мной так было решено) использует join для кодирования, склеивая файлы воедино (не обязательно с архивом — с чем угодно), единственное отличие, что только с join можно использовать пустой пароль для создания RarJPEG, а с auto и steg по соображениям безопасности нет. Существует ещё одна хитрая возможность: файл можно закодировать в контейнер steg методом, а потом к нему же прицепить что-нибудь join методом, это позволяет в случае «прижатия к стенке» выдать пароль от join-части, не скомпрометировав при этом steg-часть — получается такой контейнер с «двойным дном». К слову, если картинка будет хоть как-то изменена (обрезана, пережата etc.), никакая стеганография по определению, увы, не выживет, JPEG — формат сжатия с потерями качества.

Контейнеры


Что касается контейнеров, то здесь тоже три опции: rand, grad и image. Но тут всё гораздо проще: использующийся по умолчанию rand выкачивает случайную картинку с викимедии, grad используется в силу невозможности работы первого метода (например, когда нет интернета или объём данных слишком велик), image позволяет пользователю выбрать своё собственное изображение для контейнера. Существует ещё опция unsafe, включать которую рекомендуется исключительно владельцам слабеньких компьютеров, если у них по причине нехватки памяти не будет ничего работать, но до тех пор её использовать не рекомендуется всё по тем же соображениям безопасности.

Конфиденциальность


Перейдём к самой интересной и самой спорной части: конфиденциальность и анонимность. Вообще говоря, я согласен, что выражения «веб-сервис» и «конфиденциальность» в одном предложении звучат, мягко говоря, довольно странно. На самом деле всё далеко не так плохо. Весь код сервиса исполняется исключительно на клиенте, все вычисления никуда не вылезают за открытую вкладку браузера, никакая информация о действиях пользователей не отслеживается, не кешируется, не сохраняется, не логируется, никуда никак не передаётся. Более того, для его работы-то и веб-сервер, по большому счёту, никакой и не нужен, достаточно сохранить проект (или склонировать репозиторий) на диск и открыть index.html просто так, без установки какого-либо веб-сервера. Единственное, хром (или хромиум и его производные) нужно запускать с опциями -allow-file-access-from-files -disable-web-security для доступа к локальной ФС при кодировании и кросс-доменным загрузкам по ссылке при декодировании.

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

Безопасность


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

Что касается детектирования darkjpeg`ов на разных сайтах, так это будет немного затруднительно в случае использования join метода и, вообще говоря, довольно сложно при использовании steg. Например, для детектирования последнего подойдёт только ресурсоёмкий хи-квадрат тест, так что на счёт этого можно особо не переживать.

Если кому-то захочется раскодировать закодированные данные, не зная шифра, то следует помнить, что крипто-алгоритм использует 256-битный ключ, и если в качестве пароля не использовать всякие qwerty, 123 и прочие легко генерируемые по словарям сочетания, то остаётся только идти с раскалённым паяльником к отправителю (которого, к слову, ещё нужно умудриться найти, что совсем не тривиально в случае использования того же TOR; пожалуйста, используйте TOR), так как брутфорс в пару триллионов лет кажется сомнительным занятием.

Поддержка App Engine


Не менее, возможно, спорная часть — это использование Google App Service для получения картинок при вводе ссылки вместо указания самого файла. Так как у нас нет сервера (github pages, который умеет отдавать только статичные странички, не в счёт), нам нужно каким-то образом уметь загружать картинки (для декодирования) с разных сайтов. Существует ограничение, запрещающее выполнять кросс-доменные загрузки, если иное явно не указано тем сервером, с которого мы пытаемся загрузить контент, и это ограничение никак с наскоку, увы, не преодолеть. Существует четыре обходных пути, если мы всё-таки очень сильно хотим использовать кросс-доменную загрузку:

  • сохранение файла на диск вручную и уже выбор его с локальной файловой системы — неудобно;
  • использование локальной копии проекта, открытого с локальной файловой системы (file:///home/...) — не стоит того;
  • автоматическое использование сервисом, в случае неудачи прямой загрузки, двух прокси-сервисов на App Engine платформе — удобно, но ограничение пересылаемой информации в 2Гб в день;
  • использование уже написанных расширениий для браузеров, доступных с главной страницы проекта, для декодирования изображений напрямую с любых сайтов, через контекстное меню просто кликая по ним — идеально.

Тем не менее, не смотря на паранойю от слова «Google», прокси-сервис ровно так же самописный, он ничего не сохраняет, не кеширует, а просто принимает ссылку, закодированную base64, и выдает содержимое с дополнительным заголовком CORS, используется только если кросс-доменные загрузки на сайте или отключены, или просто не поддерживаются; исходники «обнимашек» — сервисов hugs-01 и hugs-02 — так же есть на гитхабе.

Разработчикам


Ядро проекта, dark.js, может быть использован вами в любых сторонних разработках. Он оформлен в виде асинхронного web worker`а и принимает следующие запросы:
- {action: "encrypt", name: "file.ext", pass: "password", buffer: ArrayBuffer}
- {action: "encode", method: "join", width: 0, height: 0, buffer: ArrayBuffer}
- {action: "encode", method: "auto | join | steg", width: image.width, height: image.height, buffer: ImageData}
- {action: "decode", method: "auto | join |steg", buffer: ArrayBuffer}
- {action: "decrypt", pass: "password"}

Ответы должны быть обработаны функцией worker.onmessage и выглядят так:
- {type: "encrypt", size: encrypted}
- {type: "encode", time: duration, isize: res.length, csize: enc.length, rate: 100*isize/csize, buffer: ArrayBuffer}
- {type: "decode", time: duration, isize: res.length, csize: dec.length, rate: 100*isize/csize}
- {type: "decrypt", name: "file.ext", buffer: ArrayBuffer}
- {type: "progress", name: "encrypt | decrypt | encode | decode", progress: percent}
- {type: "error", name: "encrypt | decrypt | encode | decode", msg: message}

При этом точный формат кодированного файла следующий:
- container: [ JPEG <+> encoded data ] or [ JPEG ][ encoded data ]
- encoded:   [ 16-bit encryption salt ][ AES256 encrypted data ][ 0xFFD9 ]
- encrypted: [ 0x3141593 ][ 32-bit file size ][ 16-bit file name length ][ UTF-16 file name ][ DATA ][ zero padding ]

Почитать на досуге



Summary


  • работает только с современными браузерами (Safari 6, Chrome 25, Firefox 21, Opera 15 и все новее);
  • да, Opera 12.xx, увы, не поддерживается по причине отсутствия поддержки в Presto многих html5-возможностей (таких как Blob URLs, download attribute, transferable objects etc.);
  • рабочие скрипты минифицированны с помощью unglifyjs, для проверки отсутствия «закладок» можно запустить git clone, make и затем diff того, что получилось и того, что уже было в директории build до сборки — на клиент передаётся всё именно оттуда, напрямую с гитхаба;
  • все вычисления действительно выполняются на клиенте, без малейшего участия сервера, можно сохранить проект себе на диск и просто открыть index.html без всяких апачей — всё будет работать;
  • да, всё действительно конфидециально, ничто нигде не сохраняется, ничто не трекается, логи не ведутся — сервер github pages умеет отдавать только статичные странички;
  • есть три метода кодирования: auto, join и steg, по умолчанию используется auto, который в своей основе использует join;
  • join склеивает файлы — размер вставляемых данных ограничен только здравым смыслом, безопасность средняя;
  • steg использует самую настоящую DCT LSB стеганографию — допустимый размер вставляемых данных порядка 20% размера контейнера, безопасность высокая;
  • отличие auto от join ещё в том, что в join можно кодировать пустым паролем, это даёт возможность создавать и обрабатывать RarJPEG;
  • есть три типа контейнера: rand, grad и image, первый подбирает подходящую по размерам случайную картинку с викимедии, второй используется при невозможности первого, третий позволяет использовать любую указанную пользователем картинку, загружаемую с локальной ФС;
  • файлы можно прикреплять с локальной ФС нажатием enter, кликом на плюсик, драг-и-дропом или по URL;
  • все разноцветные стрелочки (и не только они) кликабельны;
  • надпись «darkjpeg» так же кликабельна, действует как аналог обновления страницы без перезагрузки;
  • в случае указывания URL для декодирования используются два прокси-сервиса на Google App Engine из-за ограничений CORS;
  • для разработки можно использовать dark.js, содержащий JavaScript-реализации JPEG-энкодера и декодера, AES-256, SHA-3 и реализованный в виде асинхронного web worker`а;
  • как будет использоваться мой сервис: для постинга ли пони на имиджбордах, или для координации каких-нибудь активистов — это на вашей совести, я всё разрешаю.

Лицензия


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

Благодарности


  • Emily Stark, Mike Hamburg, Dan Boneh, Stanford University за их реализацию AES-256 на JavaScript;
  • Chris Drost за его реализацию SHA-3 Keccak;
  • Yury Delendik, Brendan Dahl, notmasteryet за части их JavaScript JPEG декодера;
  • Andreas Ritter за его удивительный порт JPEG энкодера на JavaScript;
  • Dan Gries за его примеры очень красивых фрактальных градиентов;
  • Brsev за иконку шестерёнки из его набора Token Dark;
  • Fabrizio Panattoni за его Premade Background 019;
  • Моей девушке за вдохновение;
  • Вам за прочтение, не судите строго :3
Поделиться публикацией
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама
Комментарии 76
  • +8
    Для тех, кто как и я не нашел в посте ссылку на потестить: darkjpeg.github.io/
    • +1
      Не хватает на данном ресурсе возможности проверить декодирование информации
      • +1
        Виноват:
        все разноцветные стрелочки (и не только они) кликабельны;
        • 0
          вообще оно там есть
        • 0
          В «Опере» сайт перенаправляет на другую страницу, на которой предлагают скачать «Оперу».
          • НЛО прилетело и опубликовало эту надпись здесь
            • –1
              Вот и я говорю, так бы и писали: «Работает только в Chrome и Firefox».
              • +2
                Обновить 11 осла до 10? о_О
                image
                • –6
                  Там ошибка. Должно быть «Не использовать вообще». Вы же криптософт использовать собираетесь. Ну какой же IE?
                  • +1
                    Да господи, как же задолбали IE-ненавистники, которые не могут признать, что у MS получился браузер.
                    • 0
                      Меньше агрессии. Специально для Вас: «У MS получился броузер». (Ни разу его не юзал с 9 версии, но все может быть :-D ) Просто мы говорим про криптософт и движок для его выполнения. И надежность тут реальная только в случае использования открытого софта, как самого криптософта, так и платформы. Так что сафари, опера, хром (не хромиум) и т.п. тут очевидно нежелательны.
                      • –1
                        Что-то мне подсказывает, что в случаях, когда вопрос безопасности и защищённости данных лежит вне плоскости экспериментов, браузером и джаваскриптом не пользуются. А проверять совместимость кода по юзерагенту, а не реальным возможностям нехорошо.
                        • 0
                          Что-то мне подсказывает, что в случаях, когда вопрос безопасности и защищённости данных лежит вне плоскости экспериментов, браузером и джаваскриптом не пользуются


                          На самом деле это так, но не совсем. Безопасность понятие поэтапное. Начинаем с неиспользования паролей вида «GoraKrut» и далее поэтапно. Так вот использование стеганографии, мне кажется, где-то после «используем открытое прикладное ПО», но до «не пользуемся браузером». А если подходить к безопасности абсолютно, то до сети «Гонец» вместо интернет можно доподходиться… Вопрос только стоит ли игра свеч.
                        • 0
                          Хохо.
                          Хром, между прочим, следит за вами.
                          Всякие надстройки типа гугловских/яндексовских/мейлрушных плагинов — тоже.
                          • 0
                            Перечитайте то, на что отвечаете, пожалуйста.
                      • –1
                        А ничего, что политика безопасности многих компаний не спроста запрещает использование браузеров, отличных от IE?
                        Chrome и Firefox — не панацея, и весьма дырявы.
                        • +1
                          Ничего. Я в такой работаю. И воочию имею возможность наблюдать успешность этого.

                          И количество уязвимостей броузеров к теме никак не относится. Речь об открытости криптографического ПО и платформы, на которой оно работает.

                          И читайте же то, на что отвечаете внимательно. Так как я не ставил в один ряд Chrome и Firefox. Первый закрытый, второй нет.
                • 0
                  Можно пояснить как пользоваться плагином для браузера?
                  • 0
                    Да, конечно! Устанавливаете расширение, заходите на любой сайт, кликаете правой кнопкой мыши на любом изображении, пункт darkjpeg, вводите пароль, получаете результат.
                    • 0
                      Понятно, просто плагин значит не работает с локальными HTML-страничками. Соответствующий пункт меню отображается только для внешних страниц.
                  • 0
                    сайтик умер походу
                • +5
                  насчет нового поколения я бы поспорил( технологии сто лет в обед) Но за такую реализацию все равно спасибо
                  • 0
                    Зашибись. Сам когда-то над подобным проектом задумался. Но до реализации не дошло…
                    • 0
                      Круто, а заодно не пробовали рассматрива контрмеры по обнаружению и порче изображения?
                      • 0
                        Вы статью читали?
                        По обнаружению:
                        Что касается детектирования darkjpeg`ов на разных сайтах, так это будет немного затруднительно в случае использования join метода и, вообще говоря, довольно сложно при использовании steg. Например, для детектирования последнего подойдёт только ресурсоёмкий хи-квадрат тест, так что на счёт этого можно особо не переживать.


                        А защита от порчи — не задача стеганографии, тут проще разместить 100 картинок с одним сообщением, и надеяться, что хотя-бы одна найдет адресата.
                        • +4
                          Если сервис принудительно пережимает картинки — шансы скрытого сообщения выжить стремятся к нулю.
                          • 0
                            При этом например watermark может быть устойчив к пережатию, вопрос тогда в объеме контейнера.
                      • –3
                        На opennet вроде после экспериментов решили, что это не стенография ( www.opennet.ru/openforum/vsluhforumID3/90885.html#17 )

                        Так что, если кто собирается использовать, имейте в виду.
                        • +3
                          На opennet неверно решили, и спустя пяток постов поняли свою ошибку. Просьба не дезинформировать.
                        • +2
                          Сервис использует стойкие методы стеганографии для сокрытия самого факта сокрытия информации

                          Для полной секретности надо только скрыть факт сокрытия самого факта сокрытия информации…
                          We need to go deeper.
                          • 0
                            Не совсем уж всё и сокрыто:

                            if (sum != 128)
                            throw new Exception('decode', «File not encrypted»);

                            Как видно из данного кода (https://github.com/darkjpeg/darkjpeg.github.io/blob/master/source/jpeg-decoder.js#L673), есть более менее приемлемый способ обнаружить наличие стенографии.
                            • 0
                              А, ну то просто все коэффициенты квантования обеих матриц (Y и UV) в единицу выставлены, ровно такое же получается, когда jpeg кодируется с качеством 100%
                              • 0
                                Достаточно редкий вариант качества для JPEG как мне кажется
                                • 0
                                  Не такой уж не редкий, на самом деле. В любом случае, это наименьшее из зол, более того, я бы даже сказал, лучшее, что можно сделать при jpeg-стеганографии, т.к. чаще всего используются просто модифицированные матрицы, которые как раз и вызывают наибольшее подозрение.
                          • +4
                            Надеялся, что в заглавной картинке будет что-то зашифровано, но видимо нет :(
                            • 0
                              Сама идея классная, и большое спасибо за реализацию. Но пользоваться таким сервисом нужно будет только если уж совсем прижмут(все таки, нужно учитывать много нюансов, если пытаться общаться таким образом с большим количеством участников)
                              • 0
                                И чем это лучше, чем steghide?
                                • 0
                                  Когда заработает кодирование url'ов?
                                  • 0
                                    Зачем кодировать по урлу? Если что-то и так выложено в сети, то зачем стеганография?
                                    • 0
                                      В таком случае, не стоит допускать варианта «encode», если пользователь изначально ввел url.
                                      • 0
                                        В общем-то справедливо, да. После работы поправлю.
                                  • –2
                                    Ужас. Ни единого теста в кодбазе.
                                    • 0
                                      Тесты пока не приведены в нормальный вид, приведу — выложу.
                                    • 0
                                      Стабильно валится на Chrome 30.0.1568.2 при наборе опций в steg-file-rand. Доходит до третьего энкода, и всё, aw snap.
                                      В качестве пейлода цеплялся .doc-файл.
                                      • 0
                                        Заметил, что хрому на больших файлах тупо не хватает памяти. И это, увы, никак не исправить, проблема именно в хроме — вот они и недостатки server-less подхода :(
                                        • 0
                                          Файл был в районе тридцати килобайт, а памяти на машине — 32 Гб.
                                          • 0
                                            Вот это тогда действительно странно, нужно изучить.
                                            • 0
                                              К сожалению, не получается на Chrome/30.0.1572.0 повторить Ваш опыт. Можете прислать трейс или хотя бы coredump упавшего хрома?
                                              • 0
                                                Напомните, для кордампа — флаг --no-sandbox в атрибуты запуска, и где его искать (винда)?
                                                • 0
                                                  Если честно, не знаю, я как-то больше через gdb.
                                        • +3
                                          Когда увидел про lsb и стеганографию, сразу захотелось сделать простейшую проверку.

                                          Сразу хочу попростить прощения за ее качество, мне честно было лень тратить время на качественный анализ.
                                          Я закодировал случайный текст в два изображения, потом нашел в гугле их оригиналы и привел к исходному размеру и перевел оригиналы и изображения со стенгоконтейнером в bmp. Потом изменил все байты на lsb. И вот что получилось:
                                          image

                                          Слева оригинальное сообщение, по центру — lsb его bmp, справа — изображения со стенгоконтейнером. Мне кажется, разница налицо. Если мои выводы верны, то предложенный метод можно назвать стеганографией с трудом — обнаружить факт передачи сообщения довольно легко.
                                          • 0
                                            Ну и так, на всякий случай, код для получения lsb: www.govnokod.com/7297
                                            • 0
                                              Э… так на любой стеганографии будет подобная разница. Другой вопрос, Вы пробовали брать исходное изображение и ещё раз пережать его jpeg? Разница между картинками будет обратно пропорциональна качеству сжатия, это нормально. Вообще говоря, подобный метод не является правильным, необходимо хотя бы уж тогда замерять энтропию в одном случае и в другом, и желательно сразу на DCT-коэффициентах, т.к. JPEG, т.к. пиксели ни о чём не скажут толковом. Ну а так в идеале-то, да, конечно, если передавать что-то действительно серьёзное, то лучше использовать уникальные, впоследствии уничтожаемые изображения.
                                              • 0
                                                Ну не настолько же явно будет видна разница? Посмотрите, на второй картинке — у оригинала в lsb хорошо просматривается силует человека, а в изображении с контейнером он уже размыт (и артефакты, да). LSB почти всегда всплывет при поверхностном анализе. Так что насчет любой — не соглашусь.

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

                                                P.S. я уже отметил, что не хотел тратить много времени на хороший анализ.
                                                • 0
                                                  Насколько я понял, проблема не в том, что разница есть (и она заметна глазом), а в том, что слева наблюдаются большие пусты области, то есть имеется отчетливо различимый подозрительный признак. Полагаю, что пустые области вызваны тем, что длина криптосообщения меньше размера контейнера. Если так, то легко лечится добавлением качественного мусора к сообщению, чтобы длина была такой, какая нужна.

                                                  Насчет уникальных картинок — факт: скачивание оных из Сети открывает потенциальную уязвимостью. Стало бы надо прикрутить генератор «осмысленных» картинок.
                                                  • 0
                                                    Настоящая проблема в том, что мы оцениваем совсем не то, что нужно, отсюда и домыслы подобные, пустые области, скорее всего, банально от сильного пересжатия (хотя, я не уверен). Во-первых, мусор, разумеется, всегда добавляется, во-вторых, LSB у нас применяется не к пикселам, а к DCT-коэффициентам, и это совсем-совсем меняет дело.
                                                    • 0
                                                      Изображение со стегоконтейнером я никак не изменял, только открыл в редакторе и сохранил в bmp. Оригинал ужимал по размеру до изображения со стегоконтейнером.
                                                      • 0
                                                        Вообще-то, насколько я понимаю, коэффициенты из верхней части спектра сильно коррелируют именно с пикселами (в отличие от низкочастотных коэффициентов, на которых сильно проявляется эффект голографичности).

                                                        Про пустые области непонятно: в алгоритмах JPEG при восстановлении изображения выброшенные lsb заменяются нулями или мусором? В любом случае обе картинки сжаты примерно одинаково в том смысле, что содержат равное количество графической информации (это верно?). Тогда все дефекты от пережатия должны проявляться примерно одинаково.
                                                        • 0
                                                          > содержат равное количество графической информации
                                                          Из предыдущего комментария ov7a понял, что это неверно.

                                                          Тогда стеганографический инструмент должен прикидываться плохим JPEG-компрессором. (Хотя, возможно, имеющаяся реализация и так обладает этим свойством.)
                                                          • 0
                                                            Всё именно в точности, как Вы описали.
                                                      • 0
                                                        Генератором осмысленных картинок наверное может быть поток с вебкамеры, направленной на улицу на дерево что-то еще постоянно меняющееся?
                                                        • 0
                                                          Зачем все усложнять? Уверен, что было бы достаточно актуально создать мобильное приложение, которое:
                                                          1. Имело бы один глобальный пароль доступа
                                                          2. Позволяло сформировать и обменяться пароля с другими пользователями (для каждого пользователя, с которым предполагается обмен, свой пароль)
                                                          3. При попытке отправить кому-либо сообщение, предлагалось бы создать сообщение и сделать фото камерой.
                                                          4. Стеганографическое изображение постится в Facebook, Twitter или любое заранее обговоренное места.
                                                          5. Пользователь с другой стороны отправляет изображение из Facebook, Twitter и т.п. в данное приложение (насчет iPhone не знаю, а Android спокойно поддерживает такой функционал). При открытии происходит запрос глобального пароля, отправителя и получаем зашифрованное сообщение.
                                                          • 0
                                                            Ваш список из пяти пунктов несомненно проще, чем поток с камеры.
                                                            • 0
                                                              Не надо передергивать. Надеюсь вы сами понимаете, что для реального использования в жизни данных изображений нужен пользовательский интерфейс, делающий работу с данной стеганографией удобной. Я предложил конкретную реализацию, которая может сделать данный функционал востребованным не только гиками, готовыми:
                                                              1. Сделать текстовый файл с посланием
                                                              2. Пройти процедуру стеганографии на сайте с сохранением изображения на компьютере. И при этом где-то ещё надо держать пароли для всех адресатов
                                                              3. Ручная отправка изображения адресату
                                                              4. Получение изображения адресатом и сохранение его на компьютере (как видно из сообщений, возможность использовать плагин есть не у всех)
                                                              5. Открытие изображения на сайте, вспоминание пароля отправителя

                                                              Как минимум те же пять пунктов, но с кучей недостатков:
                                                              1. Во-первых, выполнять каждый раз эту последовательность действий не совсем удобно
                                                              2. Для пользователей нужно где-то хранить список паролей для адресатов
                                                              3. Если в отправляемых картинках всегда будет одно и то же «дерево», то это будет достаточно странно выглядеть со стороны
                                                              • 0
                                                                Суммарное число пунктов выросло до 13, и идея потерялась в них окончательно.
                                                                Сервис в качестве картинки-донора грузит фото из google images. Я всего лишь предположил, что неограниченным источником неинтересных разных изображений может служить поток с вебкамеры. Или вебкамер. Эдакий сервис «дай мне скучную фотку», который имеет список линков на несколько тысяч живых вебкамер по миру и отдает случайный кадр с одной из них. Это несоменно проще, чем принуждение пользователя делать снимок камерой (которая у него не обязательно есть вообще) на КАЖДОЕ сообщение (данное требование присутствует в третьем пункте Вашего списка).
                                                                • 0
                                                                  Что-ж, идея с Google Images замечательная. Она может решить проблему получения изображения как на darkjpeg.github.io, так и в любом другом приложении, использующем данный функционал. Но, по-моему, это не решает вопроса простоты использования данного сервиса. Я ничего не имею против web-приложения, но у него недостаёт функционала для выхода в массы.
                                                  • +2
                                                    А чем обусловлен выбор SHA-3 для Key Derivation? Насколько я знаю, стандартным выходом в такой ситуации (вводимые пользователем пароли, которые будут подбираться по словарю) является использование hash-функции N раз, чтобы вычислять ее было долго. Ну т.е. мне, как пользователю, не жалко подождать 1 лишнюю секунуду, пока программа генерит мне зашифрованную моим паролем картинку, а вот потенциальному взломщику это проблем прибавит. При этом SHA-3, на сколько я понимаю, на данный момент не имеет никаких преимуществ перед SHA-2. SHA-3 считается дольше чем SHA-2 при програмной реализации, но в аппаратной реализации SHA-3 быстрее чем SHA-2.
                                                    В общем я рекомендую сменить SHA-3 на ru.wikipedia.org/wiki/PBKDF2 + SHA-256, параметр «количество раундов» подобрать по вкусу, ну чтобы хоть секунду тормозило :)
                                                    PBKDF2 специально создан для того, что Вам нужно — получить ключ из пароля, введенного пользователем. А в шифровании всегда лучше использовать стандарты.
                                                    • +1
                                                      Автору спасибо за интересное начинание. Однако у меня есть пара замечаний.

                                                      Во-первых, несколько странной кажется идея сделать всё на javascript'е. Я бы ожидал увидеть библиотеку плюс приложение (гуёвое или консольное). Причем приложение достаточно лишь для демонстрационных целей, а там, глядишь, народ бы подтянулся и понаделал бы на основе библиотеки своих приложений, плагинов на все случаи жизни. Примерно как с PGP. Что касается переносимости, то тоже преимуществ веб-реализации особых нет: вон с зоопарком браузеров какая морока, а популярных ОС вряд ли больше чем популярных браузеров. Ну и, само собой, кажется подозрительным предложение делать что-либо через веб, когда таковая функциональность не нужна и, более того, может быть вредна.

                                                      Во-вторых, чтобы этим инструментом пользоваться и доверять ему так же как, например, PGP, нужна отрецензированная вдоль и поперек статья с матаном и не одна. Потому что возникает много вопросов, в частности, о том, как распределены lsb у нормальных картинок и текста в AES.
                                                      • –1
                                                        Feature request: версия для Node.js или node-webkit, чтобы не требовался отдалённый сайт.
                                                        • 0
                                                          Может я туплю, но так и не понял где на сайте ввести шифруемый текст и как скачать зашифрованную картинку?
                                                          • 0
                                                            Текст вводите в ворде, блокноте — где угодно. Не обязательно текст. Можно картинку и т.д. Сохраняете файл. Заходите на сайт. Жмете "+" и выбираете нужный файл. Шифровать будет именно его.
                                                          • 0
                                                            было бы классно ещё по двум картинкам получать зашифрованный текст, т.е. использовать одно из изображений как пароль, а пароль как передаваемую информацию.
                                                            • 0
                                                              Какой-то слишком усложненный интерфейс. Доставило хлопот разобраться, что к чему. Но раскодировать секретный файл, скрытый в выбранной мной фотографии что-то не получается: «Oops, file not ecrypted». В случайных фото нормально, а в своем нет (пробовал как jpeg, так и png). Что я делаю не так?
                                                              • 0
                                                                Интерфейс ужасен. Я так и не понял — могу я в свою картинку что-то встроить или нет
                                                                • 0
                                                                  Ну что же поделать, проектировщик интерфейсов из меня, наверное, не очень хороший, да. Я понадеялся, что пользователь сообразит по наитию «пощёлкать» по стрелочкам, догадается вместо источника wiki выбрать file, тем самым задав свою картинку. Не удалось, как погляжу, увы.

                                                              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.