LSB-стеганография за пять минут

Как спрятать байты внутрь картинки, не меняя её внешний вид. Техника, которая лежит в основе Stiger, объяснённая с нуля.


Стеганография — старший родственник криптографии. Криптография говорит: «ты это видишь, но прочитать не можешь». Стеганография: «ты этого не видишь». Их можно использовать одновременно — это и делает Stiger — но часть про «спрятать» стоит понять отдельно.

Самая простая и часто упоминаемая техника — LSB substitution: прятать байты в младших битах изображения. Версия за пять минут ниже.

Пиксель — это три числа

Обычный пиксель PNG — три числа: красный, зелёный, синий, каждое от 0 до 255. Пиксель (220, 100, 50) — какой-то оттенок оранжевого. Поменяй синий с 50 на 51, и пиксель станет (220, 100, 51). На глаз — тот же оранжевый. Изменение ниже порога восприятия.

«Младший значащий бит» (LSB) числа 50 — тот, который меняется при переключении между 50 и 51. Десятичное 50 в двоичной системе — 00110010; 0 справа и есть LSB. Переключи его — получишь 00110011, то есть 51. Бит «младший», потому что переключение меняет число ровно на единицу, тогда как переключение левого бита поменяло бы на 128.

Этот один бит — слот. В него можно положить один бит своих данных вместо имеющегося.

Сколько битов помещается

В стикере 512×512 — 262 144 пикселя. Если прятать один бит на пиксель — скажем, в синем канале — получается 32 768 байт. Минус накладные расходы на фрейминг — и остаются несколько килобайт открытого текста, что в переводе — много абзацев или маленький файл.

Можно жадничать и прятать биты во все три канала, получая 3 бита на пиксель. Или в два нижних бита каждого канала — это 6. Каждый из этих вариантов — больше ёмкости, но и больше визуального отклонения, и в какой-то момент твоя «невинная» картинка начинает выглядеть статистически странно. LSB-1 в одном канале — консервативный выбор. Stiger использует синий, потому что человеческий глаз к нему наименее чувствителен.

Почему важен порядок пикселей

Наивный подход — писать данные начиная с пикселя 0 и далее по порядку. Легко написать, легко обнаружить: первая ~тысяча пикселей картинки внезапно имеет более высокую энтропию, чем остальные, потому что случайные байты не следуют гладким градиентам естественных картинок.

Решение — перестановка порядка пикселей по ключу из пароля. Вместо записи в пиксели 0, 1, 2, 3…, ты пишешь в пиксели 84372, 11, 200001, 99… — детерминированная перетасовка, которую может воспроизвести только владелец пароля.

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

Зачем шифрование сверху

LSB-1 с перестановкой прячет данные от глаза и убирает очевидный паттерн. Само по себе оно не защищает данные, если кто-то угадал технику и ключ.

Поэтому на практике сначала шифруют полезную нагрузку — Stiger использует AES-256-GCM с ключами, выведенными через PBKDF2 (600 000 итераций) — и только потом встраивают шифротекст в LSB. Теперь злоумышленник, угадавший всё про стеганографическую раскладку, всё равно получает поток байт, которые без пароля выглядят как шум.

Это стеганография + криптография в стопке. Криптография скрывает, что говорят байты. Стеганография — что байты вообще есть.

Что ломает LSB-стеганографию

Три вещи, все они — lossy-операции над носителем:

  1. Ресэмплинг. Измени размер картинки даже на 1 пиксель — LSB-слой потерян: новые пиксели интерполированы из старых без отношения к исходным битам.
  2. Пересжатие. JPEG, в частности, выбрасывает высокочастотные детали, включая LSB-шум. Пересохранение PNG в JPEG уничтожает LSB-данные.
  3. Конвертация форматов. Что угодно, что трогает значения пикселей — фильтр, конвертация цветового пространства, «авто-улучшение» — портит LSB.

Носитель должен дойти от отправителя до получателя без изменений. Это ограничивает, где стеганография полезна: чат-платформы с агрессивным пересжатием — плохие носители; платформы, которые передают картинки байт в байт, — хорошие. Вложения-картинки в iMessage в основном передаются так, но не на всех путях: в групповых чатах, при пересылке на другие платформы и при сохранении в «Фото» с повторной отправкой их могут пересжать. Нативные стикеры носителем быть не могут вовсе, они перекодируются в HEIC. Поэтому Stiger отправляет вложения.

Чем это не является

LSB substitution — учебниковая базовая стеганография, не state-of-the-art. Существует целое поле стегоанализа — статистических атак, разработанных для обнаружения скрытых битов в картинках даже с перестановкой. Современным классификаторам не нужны ни много образцов, ни оригинал картинки: они с высокой точностью помечают даже один носитель, и forensic-вендоры их поставляют. Против того, кто их запускает, LSB-1 не невидимая.

Для use case Stiger — выглядеть стикером для того, кто листает чат или ищет по ключевым словам, — этого достаточно. Если против тебя запускают forensic-инструменты на телефоне, считай, что они увидят, что что-то спрятано, — но не что именно, пока держится пароль.

Практическая версия всего этого — читать открытую спеку и пробовать storyteller.


← Назад в журнал