Теория хороша только в случае подтверждения практикой. Так и в вопросах стеганографии знать, что скрываемое сообщение можно поместить в НЗБ (наименее значимые биты), не значит уметь это сделать. Существует несколько готовых стеганографических программ, как платных, так и бесплатных, которые спрячут файл в изображение или аудио. Однако использование таких программ не дает полного контроля над процессом. Куда происходит встраивание? Насколько оно стойко к обнаружению? Насколько изменяется файл?.. На многие подобные вопросы ответа не будет.
Для начала сделаем простой стеганографический скрипт в системе математического моделирования Matlab.
Почему Matlab? Просто эта система позволяет сконцентрировать внимание на алгоритме сокрытия. Не нужно уметь открывать файл, распознавать его формат, показывать изображение на экране… Все это Matlab уже умеет. Так же он умеет работать с изображением как с матрицей, выполнять битовые операции (and, or, xor…) и многое, многое другое. Язык написания скриптов же очень прост и становится интуитивно понятным для любого кто хоть немного знаком с программированием.
Будем считать, что Matlab у вас уже установлен и запущен. Об основных окнах и приемах работы в matlab можно почитать в http://matlab.exponenta.ru/ml/book1/index.php
- в рабочем каталоге создаем папку, «images». Помещает в папку цветное изображение, в которое будем прятать данные;
- создаем пустой M-File
- назовем этот файл sample_embedding
Загружаем в Matlab изображение, которое будет служить контейнером для скрываемого сообщения:
emb_IMG_name='./images/murzik.bmp';
emb_IMG = imread(emb_IMG_name);
В Workspace появилась переменная IMG <1024xl024x3 uint3>. Это трехмерный массив цветовых компонент RGB (red, green, blue).
В Matlab принята особая система работы с матрицами, которая несколько отличается от привычной для программистов работы с массивами. К элементам матриц можно обращаться как традиционным способом :
RedComponentPixel=IMG(1,1,1);
или
GreenComponentPixel=IMG(1,1,2);
так и с помощью линейной индексации:
RedComponentPixel=IMG(1);
или
GreenComponentPixel=IMG(1048577).
в приведенных строках переменным RedComponentPixel и GreenComponentPixel. присваиваются значения яркости красной и зеленой компоненты левого верхнего пикселя рисунка 1024х1024.
Рис. 2. Представление индексации массивов в Matlab |
Понять линейное индексирование цветовых компонент можно из рисунка 2.
Подробнее о работе с матрицами в matlab можно почитать на http://matlab.exponenta.ru/ml/book1/matlab/chapter3/3_5.php. Определим размер рисунка в пикселях:
emb_IMG_size_y=size(emb_IMG,1);
emb_IMG_size_x=size(emb_IMG,2);
Рассчитаем количество информации которую можно внедрить в НЗБ:
emb_max_Bytes=emb_IMG_size_y*emb_IMG_size_x*3/8;% Bytes
Определяем сколько бит необходимо для хранения максимально возможного размера файла.
emb_num_bits=ceil(log2(emb_max_Bytes));% bits
Загружаем в переменную emb_FILE файл, который будем встраивать.
fid = fopen(emb_FILE_name);
emb_FILE = fread(fid);
status =fclose(fid);
emb_FILE_size=size(emb_FILE,1);% Bytes
Для примера объемности встраиваемых данных был взят RAR-архив первого тома «Войны и мира» в текстовом формате. Пароль архива: Password.
Проверяем, не превышает ли встраиваемый файл максимально допустимый размер.
if (emb_FILE_size*8+emb_num_bits<=emb_max_Bytes*8)
emb_possible=true;
else
emb_possible=false;
end;
Если стеганографическое встраивание возможно, кодируем длину скрываемого файла последовательностью бит.
% FILE size -> bit's row
emb_FILE_size_arr=zeros(emb_num_bits,1);
for ind =0:1:emb_num_bits-1,
emb_FILE_size_arr(ind +1)=bitand(bitshift(emb_FILE_size,-ind ),1);
end;
Так же разделяем байты файла который будем встраивать на биты. Этот шаг нужен так как встраивание будет происходить побитно.
% hidded FILE -> bit's row
emb_DATA_bits = uint8(im2bw([bitand(emb_FILE,128),...
bitand(emb_FILE,64), ...
bitand(emb_FILE,32), ...
bitand(emb_FILE,16), ...
bitand(emb_FILE,8), ...
bitand(emb_FILE,4), ...
bitand(emb_FILE,2), ...
bitand(emb_FILE,1)],0.6));
Объединяем битовую последовательность в которой закодирован размер файла с битовой последовательностью самого файла.
%FILE size bits + FILE data bits
emb_BITs=[emb_FILE_size_arr; emb_DATA_bits(:)];
Формируем индекс для встраивания битовой последовательности:
emb_BITs_ind=1:size(emb_BITs,1);
emb_BITs_ind=emb_BITs_ind';
Долгожданный момент! Встраиваем битовый ряд файла в НЗБ изображения.
emb_new_IMG(emb_BITs_ind)=bitshift(emb_IMG(emb_BITs_ind),-1);
emb_new_IMG(emb_BITs_ind)=bitshift(emb_new_IMG(emb_BITs_ind),1)+emb_BITs;
Записываем стеганоизображение в файл и показываем его пользователю.
imwrite(emb_new_IMG,'stego_murzik2.bmp','bmp');
imshow(emb_new_IMG);
В той же папке, где располагается скрипт для встраивания появится BMP-файл. Наименее значимые биты которого содержат скрытое сообщение.
Для тех у кого нет желания собирать весь скрипт из текста сообщения, искать файл для изображения и файл который можно спрятать, а попробовать как это все работает хочется, даю ссылку на архив со всеми файлами.
Для тех у кого нет желания собирать весь скрипт из текста сообщения, искать файл для изображения и файл который можно спрятать, а попробовать как это все работает хочется, даю ссылку на архив со всеми файлами.
Доброго времени суток!
ОтветитьУдалитьВо время тестирования мною данного скрипта, вылетают ошибки о совместимости размерностей матриц(конкретнее emb_new_IMG(emb_BITs_ind)=bitshift(emb_new_IMG(emb_BITs_ind),1)+emb_BITs; тут)
Если в исходнике таких казусов нет, то, прошу Вас, перезалейте пожалуйста архив.
Заранее благодарен.
Архив перезалил. Код проверил. Все должно работать. Спасибо за проявленный интерес.
ОтветитьУдалитьПРивет всем во время, теста проги,вылетает такаже ошибка emb_new_IMG(emb_BITs_ind)=bitshift(emb_new_IMG(emb_BITs_ind),1)+emb_BITs из чего могу предположить что архив не был перезалит и ли у автора данное проги просто ривые руки, прога всетаки нужная спасибо)
ОтветитьУдалитьОпишите, пожалуйста, подробно ваши действия. Какого формата файлы? Какой глубины цвета? Какого размера? Какая версия Matlab? Выложите, пожалуйста, полное сообщение об ошибке.
ОтветитьУдалитьС мнением о своих кривых руках категорически несогласен :-)
Спасибо, вы мне очень помогли.
ОтветитьУдалитьПожалуйста. Спасибо за комментарий.
ОтветитьУдалитьВы большой молодец,Gr1g0ry. Скажите, пожалуйста, Gr1g0ry, будет ли работать Ваш скрипт для встраивания стегоинформации в файлы формата jpeg 2000 и не будет ли встроенная информация при дальнейшей обработке потеряна.
ОтветитьУдалитьСпасибо за лестный отзыв.
ОтветитьУдалитьПо поводу вопроса могу сказать, что осуществить с помощью Matlab встраивание и извлечение данных из jpeg 2000 возможно. Однако, для сохранения целостности данных нельзя применять к файлам изображения сжатие с потерями. Но, именно, высокое качество сжатия с потерями является одним из основных достоинств jpeg 2000.
Для встраивания скрытой информации в форматы данных с потерями, рекомендую посмотреть стеганографические алгоритмы, которые работают в частотной форме представления изображения (сокрытие в коэффициентах вейвлет преобразования и т. п.).
Я последовал Вашему совету(спасибо!) и несколько проанализировал файл jp2 на предмет встраивания инфы. Встраивание возможно только после этапа квантования в вевлет-коэффициенты, иначе часть встоенной инфы потеряется. Я программирую на С, там как бы всё возможно задавай какие хошь параметры и всё тако. А в матлабе не юзал, вот интересно, можно ли разложить файл jp2 по шагам и вытащить вейвлет-коэффициенты коэффициенты
ОтветитьУдалитьМощно..а есть какой нибудь алгоритм для встраивания данных в видео файл,а не в изображение? Заранее спасибо
ОтветитьУдалитьСпасибо, за проявленый интерес, но стеганографией для встраивания в видео я не занимался. Хотя очевидно, что встраивание в видео возможно.
ОтветитьУдалитьА сложнее чем с изображением, как думаете?
ОтветитьУдалитьздравствуйте, тоже вылетает ошибка emb_new_IMG(emb_BITs_ind)=bitshift(emb_new_IMG(emb_BITs_ind),1)+emb_BITs и никак не могу разобраться
ОтветитьУдалитьСпасибо огромное, очень пригодилось)
ОтветитьУдалитьСкажи пожалуйста пароль к архиву Война и Мир
ОтветитьУдалитьПароль архива:
ОтветитьУдалитьPassword
:-)
ОХ ОГРОМНЕЙШЕЕ СПАСИБО
ОтветитьУдалитьЗдравствуйте, тоже вылетает ошибка emb_new_IMG(emb_BITs_ind)=bitshift(emb_new_IMG(emb_BITs_ind),1)+emb_BITs и никак не могу разобраться. Подскажите в чем проблема?
ОтветитьУдалитьТ.к. появилось много сообщений об ошибках, то я решил проверить работоспособность скрипта: скачал архив и запустил встраивание.
ОтветитьУдалитьНикаких проблемм обнаружить не смог - stego_murzik2.bmp успешно создается.
Опишите ожалуйста проблемму подробнее, дайте полный текст ошибки, дайте изображение, на котором проводилось встраивание и файл, который встраивался. Подробно опишите последовательность действий по запуску скрипта. Спасибо за проявленный интерес.
Спасибо, Григорий! Всё отлично работает, программа пригодилась
УдалитьПочему увеличивается размер файла?
ОтветитьУдалитьМожно подробней?
ОтветитьУдалитьЗдраствуйте! Ви случайно не знаете как наложить свою информацию в уже имеющийся аудиофайл, именно методом фазовой модуляции?
ОтветитьУдалитьУважаемый Григорий,у меня та же проблема,что и у предыдущего "анонимщика"поэтому отвечаю на ВАШИ ОТВЕТЫ АДРЕСОВАННЫЕ ЕМУ-фОРМАТ ФАЙЛА БМП,размер контейнера (изображение) 345600 байт,версия матлаб 6.4.1.размер внедряемого изображения 6980 байт. После этой операции появляется сообщение что операция + не определена для UINT 8 emb_new_IMG(emb_BITs_ind)=bitshift(emb_new_IMG(emb_BITs_ind),1)+emb_B
ОтветитьУдалитьITs А при обозначении типов данных на double выдаёт еррор и советует привести в соответствие размеры матриц