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 пиксель — LSB-слой потерян: новые пиксели интерполированы из старых без отношения к исходным битам.
- Пересжатие. JPEG, в частности, выбрасывает высокочастотные детали, включая LSB-шум. Пересохранение PNG в JPEG уничтожает LSB-данные.
- Конвертация форматов. Что угодно, что трогает значения пикселей — фильтр, конвертация цветового пространства, «авто-улучшение» — портит LSB.
Носитель должен дойти от отправителя до получателя без изменений. Это ограничивает, где стеганография полезна: чат-платформы с агрессивным пересжатием — плохие носители; платформы, которые передают картинки байт в байт, — хорошие. Вложения-картинки в iMessage в основном передаются так, но не на всех путях: в групповых чатах, при пересылке на другие платформы и при сохранении в «Фото» с повторной отправкой их могут пересжать. Нативные стикеры носителем быть не могут вовсе, они перекодируются в HEIC. Поэтому Stiger отправляет вложения.
Чем это не является
LSB substitution — учебниковая базовая стеганография, не state-of-the-art. Существует целое поле стегоанализа — статистических атак, разработанных для обнаружения скрытых битов в картинках даже с перестановкой. Современным классификаторам не нужны ни много образцов, ни оригинал картинки: они с высокой точностью помечают даже один носитель, и forensic-вендоры их поставляют. Против того, кто их запускает, LSB-1 не невидимая.
Для use case Stiger — выглядеть стикером для того, кто листает чат или ищет по ключевым словам, — этого достаточно. Если против тебя запускают forensic-инструменты на телефоне, считай, что они увидят, что что-то спрятано, — но не что именно, пока держится пароль.
Практическая версия всего этого — читать открытую спеку и пробовать storyteller.