Время прочтения: 3 мин.
Для подтверждения достоверности аудиторских доказательств, представленных в виде изображений в формате «со сжатием без потерь» (lossless compression) png, bmp, tiff, помимо криптографических методов возможно применять алгоритмы стеганографии – способы передачи или хранения информации, которые позволяют скрыть определенное сообщение в медиа файле, сохраняя при этом втайне сам факт такой передачи (хранения) этой информации (метки-сообщения).
Сохраненная таким образом в файле изображения информация служит своего рода водяным знаком (stego watermarking) или цифровым отпечатком (digital fingerprint). Файл, не содержащий такой метки, не может считаться подлинным.
В этой статье я продемонстрирую, как с помощью языка программирования Python (ПК с ОС Windows) можно разместить необходимое нам, визуально незаметное текстовое сообщение в файле picture.bmp, используя метод Least Significant Bit.
Начнем с установки библиотеки OpenCV
pip install requests bs4
Импортируем необходимые модули
import cv2
import numpy as np
Создаем функцию toBin, которая выполнит преобразование любого типа данных в двоичные данные.
def toBin(data):
# Преобразуем данные в двоичный формат
if isinstance(data, str):
return ''.join([ format(ord(i), "08b") for i in data ])
elif isinstance(data, bytes) or isinstance(data, np.ndarray):
return [ format(i, "08b") for i in data ]
elif isinstance(data, int) or isinstance(data, np.uint8):
return format(data, "08b")
else:
raise TypeError("Тип не поддерживается.")
Функция code выполняет кодирование необходимой метки-сообщения (hiddeninf). Например, такой: «Attention! For internal use only!», в файл picture.bmp.
def code(imgName, hiddeninf):
# Читаем изображение
img = cv2.imread(imgName)
# Максимум байт для кодирования
nBytes = img.shape[0] * img.shape[1] * 3 // 8
print("[!] Количество байт для кодирования:", nBytes)
if len(hiddeninf) > nBytes:
raise ValueError("[!] Недостаточно байт, требуется большее изображение или меньше данных кодирования.")
print("...кодируем...")
# Добавляем критерии остановки
hiddeninf += "====="
dataIndex = 0
# Преобразовываем данные в двоичный формат
binSecretData = toBin(hiddeninf)
# Размер данных, которые необходимо скрыть
dataLen = len(binSecretData)
for row in img:
for pixel in row:
# Преобразовываем RGB в двоичный формат
r, g, b = toBin(pixel)
# Если есть еще данные для хранения, тогда изменить младший бит данных
if dataIndex < dataLen:
# Red-пиксель: младший значимый бит
pixel[0] = int(r[:-1] + binSecretData[dataIndex], 2)
dataIndex += 1
if dataIndex < dataLen:
# Green-пиксель: младший значимый бит
pixel[1] = int(g[:-1] + binSecretData[dataIndex], 2)
dataIndex += 1
if dataIndex < dataLen:
# Blue-пиксель: младший значимый бит
pixel[2] = int(b[:-1] + binSecretData[dataIndex], 2)
dataIndex += 1
# Выйти из цикла, если данные закодированы
if dataIndex >= dataLen:
break
return img
Следующая функция- decode выполняет декодирование изображения picture.bmp.
def decode(imgName):
print("...декодируем...")
# Читаем изображение
img = cv2.imread(imgName)
binData = ""
for row in img:
for pixel in row:
r, g, b = toBin(pixel)
binData += r[-1]
binData += g[-1]
binData += b[-1]
# Разбивка по 8 бит
allBytes = [ binData[i: i+8] for i in range(0, len(binData), 8) ]
# Преобразование в символы
decodedData = ""
for byte in allBytes:
decodedData += chr(int(byte, 2))
if decodedData[-5:] == "=====":
break
return decodedData[:-5]
В итоге, применив созданные функции,
if __name__ == "__main__":
inImg = "C:\\Users\\User\\picture.bmp"
outImg = "C:\\Users\\ User\\coded_picture.bmp"
hiddeninf = "Attention! For internal use only!"
# Кодируем данные в изображение
encodedImg = code(imgName=inImg, hiddeninf=hiddeninf)
# Сохраняем изображение с закодированными данными
cv2.imwrite(outImg, encodedImg)
# Декодируем данные из изображения
decodedData = decode(outImg)
print("[!] Декодированные данные:", decodedData)
получаем следующий результат:
[!] Количество байт для кодирования: 40313
...кодируем...
...декодируем...
[!] Декодированные данные: Attention! For internal use only!
Внешне, после обработки, изображение-контейнер не будет отличаться от оригинала и только при его декодировании можно прочесть сохраненную в нем информацию (метку-сообщение).
Стеганография также применяется для защиты авторского (исключительного) права, скрытой передачи информации в файле-контейнере, отслеживании незаконной передачи (слива) информации недобросовестными сотрудниками сторонним лицам.