Перевод поста Джона Маклуна (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)
boeing777
29.07.2015 23:05Картинка с увеличенным контрастом разности похожа на результат работы фильтра noise в Photoshop. Интересно, Adobe там тоже что-то закодировали? :)
По делу: для увеличения плотности инкапсуляции можно использовать сокращенный алфавит вместо 8-битного ASCII. Например, base64-кодирование или нечто подобное. Разумеется, такой способ применим только для текста, а не двоичных данных.
SneakyJoe
А есть ещё и такие штуки как rarjpeg. Тоже способ начального уровня сокрытия.
Alexufo
есть еще плагин в фотошопе называющийся «Digimarc»