Вступление Вшить текст в картинку нам поможет стеганография. Но что это такое? Стеганография является ответвлением от криптографии, но тут мы не просто шифруем информацию вследствие чего мы можем понять что текст зашифрован как тут: YmlnIGJyb3RoZXIgaXMgd2F0Y2hpbmcgeW91, а прячем сам факт такой передачи. Все это значит что даже в обычную картинку можно спрятать текст, и сейчас я вам покажу разницы между ними, по крайне мере для обычного человеческого глаза - нет. сырое изображение: изображение с вшитым текстом: Думаю вы даже и не заметили изменений, тут даже не меняется формат и разрешение. Теперь когда я вас ввел в курс дела, можно перейти к теоретической части. Как текст вставляется картинку? Будем разбирать на самом популярном и простом методе стеганографии - LSB (Least Significant Bit) или наименьший значащий бит. Не бойтесь таких определений, сейчас я расскажу принцип работы как можно легче. Начнем из далека, у каждой картинки есть своя цветовая модель и их существует достаточно много (RGB, RGBА, CMYK, HSB), для работы я возьму RGB (она включает красный, зеленый и синий каналы). Так как в нашей цветовой модели 3 канала, то и в 1 пикселе нашего изображения будет 3 байт. То есть 1 пиксель нашей пикчи будет нести в себе следующую информацию: Красный канал: 10001000 Зеленый канал: 01111011 Синий канал: 10010010 Ну и как же можно всунуть информацию, если ты хоть 1 цифру поменяешь и пиксель измениться в цвете? Метод LSB решает эту проблему тем, что берет наименьшие значащие биты и заменяет их на биты нашего сообщения. (Мы возьмем последние 2) В пример возьмем числа 500.000 и 500.000, думаю вы согласитесь что если прибавить число 38 ко второму, то особо ничего не измениться, но разница уже будет. Такой же принцип мы будем использовать для замены последних битов пикселей. Возьмем двоичную версию нашего сообщения: "The story of a young programmer, Elliot, who suffers from social anxiety and decides that the only acceptable way for him to interact with people is to become a hacker. Thus, he quickly finds himself in the very place where the interests of his employer, a cybersecurity firm, intersect and the underground organizations that are trying to recruit him with the aim of bringing down the most powerful American corporations." / 1010100 1101000 1100101 100000 1110011 1110100 1101111 1110010 1111001 ....... 100000 1100011 1101111 1110010 1110000 1101111 1110010 1100001 1110100 1101001 1101111 1101110 1110011 101110 (Сократил полную версию бинарной версии текстa.) Берем первый байт пикселя и нашего текста, получим в итоге: байт пикселя пикчи: 10001000 (фиолетовым выделены наименее значимые биты в которые мы будет вставлять фиолетовую часть битов текста снизу) байт текста: 1010100 (фиолетовым выделены биты которые мы хотим вставить) Tеперь просто вставляем в часть бита пикселя биты текста и получаем: 10001010 (мы уже внесли пусть и маленькую, но часть нашего сообщения с минимальным визуальным изменением пикселя) Теперь меняем байт пикселя на следующий, но продолжаем вставлять биты того же байта текста имеем: байт пикселя пикчи: 01111011 байт текст остался тот же: 1010100 получаем: 01111010 спустя пару итераций получим: 10001010 01111010 1101010 11001101 1110110 1111010 1110100 1110011 1110100 1100110 1100111(зачеркнуто так как это уже часть пробела)....... Соединим последние 2 бита каждого байта и получим: 1010100 1101000 1100101 В итоге мы смогли спрятать первое слово в байтах пикселей картинки при минимальных, незаметных визуальных изменениях! Думаю теперь мы разобрали как это работает, но это сухая теория, нужно сделать реализацию всего этого: в этом нам поможет python Реализация на python Думаю когда речь заходит о программах на этом ЯП то тут нельзя без библиотек, в нашей реализации мы используем всего лишь одну либу: stegano. для начала установим нашу библиотеку (в ней много зависимостей, а также на версии питона 3.12 не ставится, лучше ставьте на более ранних версиях: 3.9; 3.8): pip install stegano и пропишем следующий код (работает только с png): from stegano import lsb def hide_text_to_image(): text = "The story of a young programmer, Elliot, who suffers from social anxiety and decides that the only acceptable way for him to interact with people is to become a hacker..." hide_obj = lsb.hide("keka.png", text) hide_obj.save("hide_keka.png") def reveal_image(): text = lsb.reveal("hide_keka.png") print(text) if __name__ == "__main__": hide_text_to_image() reveal_image() Python from stegano import lsb def hide_text_to_image(): text = "The story of a young programmer, Elliot, who suffers from social anxiety and decides that the only acceptable way for him to interact with people is to become a hacker..." hide_obj = lsb.hide("keka.png", text) hide_obj.save("hide_keka.png") def reveal_image(): text = lsb.reveal("hide_keka.png") print(text) if __name__ == "__main__": hide_text_to_image() reveal_image() Тут все достаточно просто, импортируем из stegano модуль lsb. Позже вызываем метод lsb.hide() с параметрами: исходной картинки и сообщения. Потом сохраняем объект: lsb.save() с параметром нового имени изображения. Метод lsb.reveal() с параметром названия пикчи возвращает текст изображения. Теперь разберем что делать с jpg файлами: код: from stegano import exifHeader def hide_text_to_image(): text = "The story of a young programmer, Elliot, who suffers from social anxiety and decides that the only acceptable way for him to interact with people is to become a hacker..." hide_obj = exifHeader.hide("keka.jpg", "hide_keka.jpg", text) def reveal_image(): text = exifHeader.reveal("hide_keka.jpg") print(text.decode()) if __name__ == "__main__": hide_text_to_image() Python from stegano import exifHeader def hide_text_to_image(): text = "The story of a young programmer, Elliot, who suffers from social anxiety and decides that the only acceptable way for him to interact with people is to become a hacker..." hide_obj = exifHeader.hide("keka.jpg", "hide_keka.jpg", text) def reveal_image(): text = exifHeader.reveal("hide_keka.jpg") print(text.decode()) if __name__ == "__main__": hide_text_to_image() Тут уже другой модуль - exifHeader. Чтобы засунуть текст вызываем метод exifHeader.hide() с параметрами имени исходной картинки, названия новой и текстом сообщения. Декодинг проходит также через reveal(), но полученный текст нужно декодировать функцией decode(). Прячем текст с ключём Есть более продвинутая библиотека которая нам с этим поможет: steganocryptopy. Пишем в терминал: pip install wheel steganocryptopy И пишем следующий код: from steganocryptopy.steganography import Steganography def crypt_text(): Steganography.generate_key("") secret_obj = Steganography.encrypt("key.key", "pathfile.png", "yourtext.txt") secret_obj.save("hideobj.png") def decrypt_text(): decrypt = Steganography.decrypt("key.key", "hideobj.png") print(decrypt) if __name__ == "__main__": crypt_text() decrypt_text() Python from steganocryptopy.steganography import Steganography def crypt_text(): Steganography.generate_key("") secret_obj = Steganography.encrypt("key.key", "pathfile.png", "yourtext.txt") secret_obj.save("hideobj.png") def decrypt_text(): decrypt = Steganography.decrypt("key.key", "hideobj.png") print(decrypt) if __name__ == "__main__": crypt_text() decrypt_text() Импортируем модуль Steganography. Методом generate_key("") генерируем ключ без которого будет невозможно получить содержимое картинки(он появляется в папке нашей проги). encrypt() принимает в себя путь ключа, путь картинки, и наш текст в файле .txt. save() сохраняет нашу картинку и принимает в себя название картинки. decrypt() же декодит наше сообщение с нашим ключом и картинкой. Заключение Сегодня мы поняли что такое стеганография, как зашифровать текст в картинку с ключом и без на python. (Форумчане, пожалуйста напишите конструктивную критику моей статьи, а так всем желаю всего хорошего)
Мне кажется на форуме Садама Хуссейна, Ким Чен Ына и других нет, чтобы прям так изощряться с передачей сообщения, а так интересно
Network, вообще я увидел такой метод шифровки информации в сериале "mr robot", он меня заинтересовал и вот теперь вы видите это.
Network, да, я уже смотрел реализации на c#, но в этой статье я больше хотел теоретическую часть написать. А так этa задача у меня уже стоит.