Перевод поста Джона Маклуна (Jon McLoone) "Doing Spy Stuff with Mathematica".
Код, приведенный в статье, можно скачать здесь.
Выражаю огромную благодарность Кириллу Гузенко KirillGuzenko за помощь в переводе.

Я читал о IT проблемах недавно арестованных, как заявлялось, русских шпионов. Говорилось, что они пользовались не самыми надёжными инструментами цифровой стеганографии (вики). И мне стало интересно — насколько быстро я смогу реализовать стеганографию через цифровые изображения в Mathematica, используя метод, известный как "вставка младшего бита" (least significant bit insertion).

Идея стеганографии основывается на том, чтобы спрятать сообщения в какой-то другой информации таким образом, чтобы никто факта коммуникации не заметил. Само слово происходит от латино-греческий комбинации, означающей «скрытное письмо»; данным термином назывался процесс нанесения секретного сообщения на лысую голову человека, на которой затем отрастали волосы и, тем самым, прятали сообщение. В случае цифровой стеганографии всё делается посредством математики.

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





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

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

Мы должны заставить Mathematica использовать строго 8 бит на канал, потому что она по умолчанию работает в гораздо более точном цветовом пространстве, то есть будем использовать служебное слово “Byte” в некоторых места нашего кода.



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





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





И только если выкрутить контраст на максимум, то мы увидим, что разница не равна нулю.





Далее мы должны преобразовать наше секретное послание в последовательность битов и вставить их в обнулённые биты в изображении-носителе. Получается по биту на канал, то есть по три на пиксель для RGB изображения.

Для кодирования символов в соответствующие им номера в ASCII будем использовать функцию ToCharacterCode:





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





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

Вот все эти операции вместе:



Для совершения обратного процесса мы должны взять младшие биты из каждого канала пикселя и сгруппировать их в слова по 8 бит, а затем сконвертировать их обратно в текст.



Давайте протестируем:





И обратный процесс:





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

Изображение курицы Матильды состоит из 450*450 пикселей и имеет три цветовых канала. Это означает, что мы можем передать 450*450*3/8 символов. Более 75 000. Более чем достаточно, чтобы передать весь текст Приключений Алисы в стране чудес.

Мы можем добавить информации не больше, чем удалили. Файл по-прежнему будет такого же размера и визуально точно таким же.

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









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







Мы можем использовать преобразование в ASCII для вставки файлов или данных в специальных форматах. Например, мы можем вставить изображение. Тут мы импортируем файл PNG, а затем перекодируем его в строку ASCII формата JPG.



Эта строка, благодаря сжатию JPG, содержит лишь 32000 символов, несколько меньше текста про Алису — удивительно, как легко спрятать целое изображение! Мы можем экспортировать изображение в любой формат без потерь; важно только то, что секретное изображение закодировано в JPG, и при декодировании и интерпретации это следует учитывать.





Изображение-носитель по прежнему выглядит для нас таким же, хотя в нём теперь скрыто секретное изображение агента H и агента B:





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

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


  1. SneakyJoe
    29.07.2015 16:49
    +1

    А есть ещё и такие штуки как rarjpeg. Тоже способ начального уровня сокрытия.


    1. Alexufo
      29.07.2015 21:15
      +1

      есть еще плагин в фотошопе называющийся «Digimarc»


  1. boeing777
    29.07.2015 23:05

    Картинка с увеличенным контрастом разности похожа на результат работы фильтра noise в Photoshop. Интересно, Adobe там тоже что-то закодировали? :)
    По делу: для увеличения плотности инкапсуляции можно использовать сокращенный алфавит вместо 8-битного ASCII. Например, base64-кодирование или нечто подобное. Разумеется, такой способ применим только для текста, а не двоичных данных.