Стойкое шифрование данных в PNG

    Доброго утра Хабру. Читал вчера статью о хэш-стеганографии через социальные сети, и пришла мне в голову мысль сделать что-то более оптимальное в плане объёма выходных данных. Получилось что-то более-менее работоспособное и даже оптимизированное (в отличие от proof-of-concept romabibi), поэтому, как и обещал, пишу статью.

    Что ж, поздороваюсь с вами ещё раз: , и добро пожаловать под кат.

    Я решил реализовать идею максимально по-тупому просто, поэтому алгоритм шифрования опишу кратко:

    1. Подгонка ключа под длину, кратную 16 (для шифрования AES)
    2. Сжатие исходных данных, используя zlib
    3. Подгонка под кратную 16 длину и шифрование сжатых данных
    4. Повторное сжатие зашифрованных данных
    5. Вычисление MD5-хэша из ключа шифрования для сравнения при дешифрации
    6. Нахождение минимального количества '\0', не встречающихся подряд в тексте, для использования в качестве разделителя данных и белого (буквально) шума
    7. Подготовка grayscale-изображения и заполнение его рандомными данными
    8. Запись строки (длина_данных + длина_MD5_ключа + MD5_ключа + данные) поверх шума

    Строка (в виде байтов) записывается квадратом в левый верхний угол изображения, сливаясь с белым шумом. В итоге получается что-то вроде какой-нибудь текстуры — например, камня из игры Minecraft. Посудите сами:



    Конечно, нетрудно понять, что это шифр, однако, не имея алгоритма, его не так уж и легко расшифровать (ведь нужен AES-ключ, да и формат с префиксами и двойным сжатием зареверсит далеко не каждый).



    Ну, получили мы картинку. Что теперь с ней делать? Отправлять получателю, конечно. Правда, ему заранее должен быть известен ключ и алгоритм (или скрипт) дешифрации. И всё бы даже было хорошо, если бы не одно «но». И это «но» — сжатие.

    Очевидно, что хранить оригиналы картинок соц. сетям не выгодно. ВК, например, даже конвертирует PNG в JPG, используя не самый маленький коэффициент сжатия. А, так как у нас используются конкретные значения байт (0-255), их потеря ни к чему хорошему не приведёт. Решение — отсылать полученные изображения как документы (файлы).



    Я накатал развёрнутый скрипт в 101 строку с исключениями и отображением в stderr прогресса и времени работы. Его вы всегда можете найти в репозитории туть. Скорее всего, я его буду постепенно дорабатывать, хотя в последнее время проектов (в том числе и тянущих на хабрастатьи) у меня развелось достаточно.

    Правда, думаю, эта статья (выросшая из комментария) себя исчерпала. Буду рад выслушать предложения других алгоритмов, и услужливо закодить их для вас, добавив в этот же скрипт.

    Спасибо ещё раз romabibi за идею; adios.

    Средняя зарплата в IT

    120 000 ₽/мес.
    Средняя зарплата по всем IT-специализациям на основании 3 391 анкеты, за 1-ое пол. 2021 года Узнать свою зарплату
    Реклама
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее

    Комментарии 24

      0
      png картинками можно обмениваться много где, через всякие имгур.
      Однако было бы вполне логично натянуть сову на глобус пиксельный шум на целевую картинку пропорционально. И оно станет менее заметным и привлекающим внимание, особенно если белый станет прозрачным.
      Размер шага вычислять или задавать заранее.

      PS:
      Чем серьёзно дополнить?
      Проанализировать вк-сжатие стандартное для jpg, отследив особенности создавать из оригинала фото и шумо-шифровки готовый jpg, который не тронет оптимизатор ВК посчитав картинку уже хорошей. Это правда уже тянет на звездочку(может еще на что) от товарища майора, и возможно запрет на статью об этом на хабре.
        0
        Нет, здесь ничего не поделать. JPG — он сам по себе не loseless, так что при конвертации со 100%-м шансом потеряются исходные байты.
          +1
          Подтверждаю, сам одно время писал конвертер любого файла в изображение и JPG всегда бил файлы. Его тогда просто не использовал в итоге.

          Как решение, можно использовать не все 256 значений цвета, а только 64 значений, которые размазаны от 0 до 255. Получается переизбыток в 4 раза, расстояние между цветами сделает байты «контрастнее» между собой. Так же если за пиксель взять не 1, а 4 пикселя, то есть шанс побороть проблему JPG.

          Правда при чтении из него придется усреднять значения, а объем данных станет в 8 раз меньше помещаться.

          Конечно это теоретически всё, эксперименты помогут найти лучшее решение и параметры.
            0
            Делал где-то в середине написания сего чуда. Аж в 8 раз апскейлил. Не помогло. Насчёт цвета — теряется компактность. А ещё, учитывая, что PNG так широко распространён, да и
            png картинками можно обмениваться много где, через всякие имгур
            можно просто использовать его.
            0
            Спасибо, но я в курсе, что jpg является lossy форматом, но и товарищ майор не раздает плюшки кому попало.
            Повторюперефразирую мысль: сделать свой конвертор изображений в jpg, который и сожмет и расположит точки в нужных местах. А иначе звездочку давать неинтересно.
              0
              Вроде бы ВК даже готовый JPG пережимает, так что врядли получится.
                0
                У товарища майора щас поболее других проблем, чем докапываться до шифрования jpg в ВК.
                +3
                «Вы просто не умеете их готовить» (с)
                Для JPG нужно инфу добавлять не в пиксели, а в коэффициенты фурье (если ничего не напутал, давно про JPG читал), которые вычисляются из картинки в момент сжатия.
                Т.е. по сути нужно брать алгоритм сжатия JPG и внедряться внутрь него.
              0
              del
                +2
                шифрование сжатых данных
                Какой режим используете? Если ECB, то не надо так =)
                Повторное сжатие зашифрованных данных
                Зачем? У шифрованных данных высокая энтропия, они практически не сжимаются.
                Вычисление MD5-хэша из ключа шифрования для сравнения при дешифрации
                Это зачем? Чтобы убедиться, что ключ верный и всё корректно расшифруется? Тогда лучше используйте HMAC.

                  0
                  Да, в конструкторе Crypto.Cipher.AES используется режим по умолчанию, который равен MODE_ECB. Это очень грустно.
                • НЛО прилетело и опубликовало эту надпись здесь
                    +13

                    Не поленился и посмотрел исходник. С точки зрения и криптографии, и стеганографии то, что Вы сделали — это дно. Простите, ничего личного. Теперь что именно делает Ваше решение дном:


                    1. Генерация AES ключа тупым дополнением его до нужной длинны нулями. Ключ Вы используете из командной строки, на практике это значит буквы+цифры+спецсимволы, то есть такой типичный пароль. Энтропия 26-30 бит приблизительно (ожидаемая, можно конечно упороться и ввести все битики, но я говорю об обычных людях, словарных паролях и прочих вещах из мира реальных пользователей). Кроме того, Вы любезно положили MD5 хэш от ключа в передаваемые данные, что сильно упрощает перебор (не надо много расшифровывать, достаточно сравнить хэши). То, что Вы сделали перебирается существенно более быстро, чем позволяет используемое шифрование. Читайте про key derivation functions;
                    2. Повторюсь про MD5 хэш. Никогда не давайте атакующему путь быстро проверить правильность ключа. Всегда надо строить шифрование так, чтобы надо было выполнить как можно больше действий и только потом узнать все ли правильно получилось. В вашем случае, надо было посчитать хэш от plaintext, добавить этот хэш к plaintext и потом все зашифровать. На проверке — расшифровываем и смотрим совпадают ли хэши. MD5 в качестве хэша тут внезапно ок, поскольку коллизии нас тут не интересуют. HMAC, который советовали выше тут вообще ни при чем;
                    3. AES ECB использовать нельзя. Проблема с ним заключается в том, что его выход сохраняет все статистические свойства входа. Кстати, поэтому он у вас немного сжимается; CBC, CTR или GCM на выходе дают практически белый шум;
                    4. Никогда не стройте безопасность на том, что атакующий не знает алгоритм. Это одна из основных аксиом криптографии;
                    5. Что касается «не трудно понять, что это шифр», то вообще говоря, стеганография — это о том, чтобы скрыть сам факт передачи сообщения. Если по картинке не трудно понять, то, извините, стеганографии не получилось.
                      +3
                      А давайте я все эти замечания учту и поправлю код :)
                        0
                        Криптографию Вы поправите легко и просто. Советую PBKDF2+SHA256 c большим числом итераций для key derivation function (KDF), еще можно bcrypt / scrypt. Последние две — более стойкие против атак на GPU, но на практике, любая из этих KDF достаточно хороша. AES советую использовать либо в режиме ECB если надо попроще, либо в режиме CTR или CGM, если надо побыстрее (в counter режимах можно шифровать блоки параллельно). IV — криптографически безопасное случайное число (самый простой источник в питоне — random.SystemRandom().getrandbits), передавайте вместе с шифротекстом. Обратите внимание, в counter режимах нельзя использовать одну и ту же пару ключ-вектор инициализации для двух разных сообщений. Всей вашей безопасности придет кирдык. В GCM кроме всего прочего встроен собственный MAC. Его можно использовать для проверки правильно ли расшифровалось.
                        Что касается стеганографии, просто «поправить» тут мне кажется не выйдет.
                          0
                          Не раз уже отвечал, что стеганографии здесь не планировалось изначально. Остальное на днях поменяю, обновлю в репозитории.
                        +2
                        5-й пункт — краеугольный.
                        +2
                        Прочитал пост. Плюсанул за попытку… Всё-таки кодили… Но это совсем не то, что я имел в виду.

                        Идея была в создании стохастического (не детерменированного) алгоритма, модифицирующего исходное изображение. И тогда можно модифицировать контейнер (картинку) нейронной сетью до тех пор, пока его хеш-код не совпадёт с передаваемым сообщением!

                        Вот простой туториал, как это делать.

                        Тогда вместо большой-большой базы данных с котиками нам потребуется ровно столько изображений, сколько каждое из них передает данных.

                        А то что вы сделали, это не хеш-стеганография… Это вообще не стеганография!!! Это упаковка весьма странного шифротекста в картинку.

                        Сории за резкость!
                          0
                          Так нигде и не сказано о стеганографии! Кроме ссылки на пост, подсказавший мне эту идею. Вот и всё.
                            +1
                            Зачем модифицировать картинку именно нейронной сетью??? Берем 8-12 любых бит картинки модификация которых не сильно скажется на результате, перебираем все возможные комбинации, считаем хэш, находим нужный. Гораздо быстрей чем нейронная сеть и практически никак не отслеживается статистическим анализом при условии отсутствия у злоумышленника оригинала картинки.

                            Кроме того, если взять какую-нибудь менее стойкую реализацию хэша, например CRC32, то можно буквально вычислить какой бит (или 2 или 3, в зависимости от длинны файла) нужно поменять чтобы получить нужный результат.
                              0
                              Да, есть и такая идея.
                              Только любые биты нельзя. Нужно те, которые не влияют на статистику стегоаналитического энтропийного анализатора.

                              Ещё раз. Любое вкрапление в изображение в общем случае может быть обнаружено. Вот очень простой пост об этом: securelist.ru/steganography-in-contemporary-cyberattacks/79090
                                0
                                Интересненько, зловреды и до изображений добрались. PavelMSTU, спасибо за ссылку на статью. Теоретическое применение этого обычными преступниками где-то обсуждалась, но вот реальное применение, как-то прозевал.
                                Этот самый «стегоаналитический энтропийный анализатор» можно где-то скачать?
                                что б пробежаться по всем картиночкам на компе?

                                Когда доберутся до gif'ок по 10-100mb которыми любят перекидываться в vk будет наконец-то их запретитьсовсем не хорошо. Тем более, что у гифок есть свои артефакты которые усложнят анализ.
                                  0
                                  Ну я и написал, любые которые не сильно влияют на картинку.
                                  Я думаю никакой анализатор не найдет отклонение в младших битах пикселя lossless картинки если их будет всего 8-12 на всю картинку. При этом ведь из этих 8-12 бит мы поменяем-то в среднем всего 4-6!!!

                                  ЗЫ: Естественно речь не идет о картинках на которых любое изменение сразу заметно, типа контрастных геометрических узоров. Речь скорее про фотографии и т.п. где и так шума за глаза.
                              +5
                              Вся суть стеганографии потерялась же.
                              Осталось обычное шифрование, только зачем-то обернутое в изображение.

                              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                              Самое читаемое