Как я с LSB баловался

в 20:24, , рубрики: маркировка изображений, Стеганография

В свете того, что тема маркировки генераций ИИ все набирает обороты, я вспомнил про такую штуку, как стеганография. Опыта с ней я не имел, только краем уха слышал на парах, когда еще был студентом, что это способ положить в фото, аудио или видео какую то информацию.

Немного полазив в интернете я понял, что стенографические методы достаточно неустойчивы, и от сильных изменений не защитят. И тут я наткнулся на статью о методе, устойчивом к повреждениям данных.

Данный метод основан на схеме Шамира, и записывает в изображение не одно зашифрованное сообщение, а несколько, что позволяет восстановить данные даже при повреждениях изображения. Ну я и решил попробовать реализовать этот метод.

Первый этап

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

def shamir_split_secret(secret: str, required_shares: int, distributed_shares: int): secret = pad(secret.encode("utf-8"), 16) return Shamir.split(k=required_shares, n=distributed_shares, secret=secret)

Разбиение представляет собой список кортежей из порядкового номера и строки байтов.

[(1, b'xfdL?xfbx08-x12gxda%xa5cxf7r?xac'), (2, b'Rx93xbeDxf3xebx99xf8PHfxe1Hxeaxd3x9b'), (3, b'xdcxb0xf2xd6xf7xcax87x93x86axcfx8exb3x94xe0;'), (4, b'xc6x7fxb9x15-Ux83ktxd89x1cMxabRb'), (5, b'H\xf5x87)tx9dx00xa2xf1x90sxb6xd5axc2')]

Второй этап

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

Выглядит это так:

𝑐𝑜𝑙𝑠 = 𝑐𝑒𝑖𝑙(𝑛*𝑛), 𝑟𝑜𝑤𝑠 = 𝑐𝑒𝑖𝑙 (𝑛/𝑐𝑜𝑙𝑠)

где ceil - функция, которая возвращает наименьшее целое число, не меньшее, чем аргу- мент, n - количество частей секрета

Я, конечно, реализовал все как указано в статье, но при таком подходе число строк всегда будет равняется 1, а значит мы шифруем только маленькую часть изображения. Возможно число колонок должно высчитываться иначе.

Третий этап

Третий этап самый интересный и именно на нем я не доработал. Метод, описанный в статье называется SSRC: (Share (делить), Secret (секрет), Rotation (поворот), Color (цвет))

Если первые две S уже были разобраны, остались R и C.

Начну с цвета - обычно секрет вставляют в изображение путем изменения наименьших значащих битов в одном-трех цветовых каналах r, g и b в цветовой кодировке RGB соответственно. Но любое изменение этих каналов может повлечь за собой существенные визуальные изменения пикселя. Но в данном случае изменяться будет только бит канала v в кодировке HSV. Небезосновательно полагается, что именно такой подход имеет ряд преимуществ. HSV обеспечивает хороший баланс между незаметностью изменений в изображении и высокой пропускной способностью стегоканала, а так же устойчив ко многим видам изменения изображения.

Поэтому при работе с очередным пикселем мы сначала переводим его из RGB в HSV, затем вставляем нужную нам информацию и переводим обратно в RGB.

Теперь R - поворот предлагается осуществлять на угол, кратный 90°.

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

Расшифровка

Для расшифровки секрета необходимо иметь: изображение со встроенными данными и ключ, который содержит количество частей секрета, на которое изображение было разделено. Ключ передается в зашифрованном виде, для шифрования использовался алгоритм RSA.

Вместе с информацией о количестве частей секрета я решил передавать и число k - количество частей секрета, нужное для расшифровки исходного сообщения.

Возможно количество строк всегда равно 1 для того, чтобы получив число блоков мы всегда знали, как разбить изображение, но это решается передачей еще одного числа в зашифрованном виде.

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

Изображение разбивается на блоки, а затем из них по очереди извлекаются данные.

  1. Поворот

  2. Перевод из RGB в HSV

  3. Извлечение данных.

  4. При удачном восстановлении передаем сообщение пользователю.

Примечание

После знакомства со стеганографией стало понятно, что для маркировки она едва ли подойдет. Пока нет универсального способа защиты от атак на изображение, а стеганография может быть легко удалена или изменена без обнаружения, тогда как маркировка ИИ-изображений должна быть стойкой и трудно подделываемой.

Кода вышло не очень много, чуть больше 300 строк, но тащить их сюда было бы не очень уместно, как мне кажется, так что:

Ссылка на репозиторий

Автор: Aksel28

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js