Дмитрий Сергеевич (axshavan) wrote,
Дмитрий Сергеевич
axshavan

Немного стеганографии, и почему JPEG для неё не подходит

Стеганография - это передача тайного послания с сохранением в тайне самого факта передачи, типа как пердеть азбукой Морзе или зашифровывать тайны вселенной в полёте птиц. Меня больше интересует практическое применение стеганографии в изображении. Для экспериментов я избрал наиболее простой способ, даже описанный в "википедии".

Каждый пиксель изображения имеет три составляющих трёх разных цветов (красный, зелёный и синий), и значение каждой составляющей может меняться от 0 до 255. Разница между, например, 140 и 150 заметна простым глазом, но очень невелика. А в промежуток между 140 и 150 можно запихать ещё десять разных чисел (включая ноль)! Можно взять одно изображение, и все значения всех составляющих каждого пикселя округлить до десятков. А у второго изображения все значения всех составляющих поделить на 26, чтоб получились числа от 0 до 9. И всё это сложить точка за точкой и цвет за цветом, таким образом запихав одно изображение в щели в другом.

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


А вот эту картинку я буду прятать.


Промежуточный этап - базовое изображение с округлёнными значениями составляющих всех цветов.


А вот базовое изображение, которое уже содержит в себе скрытое.

Видите, если присмотреться, то видно местами, что там что-то ещё просвечивает? Также советую обратить внимание, что это формат PNG. Дело в том, что JPEG - формат с компрессией с потерями, и высокий уровень сжатия как раз достигается за счёт потерь. А в качестве потерь теряется как раз малозначительная и малозаметная информация - в которой как раз второе изображение и спрятано! Извлечение скрытого изображения: обратная операция. Для каждого пикселя для каждой составляющей взять остаток от деления на десять, и умножить его на 26.

Извлечённое изображение.


А теперь - примеры того, почему нельзя использовать JPEG.
Что получится, если извлечь скрытое изображение из картинки, сохранённой в джипеге с качеством 100:


95:


80:


Примеры кода.
encode.py
#!/bin/env/python

import sys
import math
from PIL import Image

if len(sys.argv) != 3:
    print("Usage: encode.py <base image> <image to hide>")
    exit(0)

try:
    base_image = Image.open(sys.argv[1])
    base_w, base_h = base_image.size
except:
    print("cannot open image " + sys.argv[1])
    exit(0)

try:
    hide_image = Image.open(sys.argv[2])
    hide_w, hide_h = hide_image.size
except:
    print("cannot open image " + sys.argv[2])
    exit(0)

for y in range(0, base_h - 1):
    for x in range(0, base_w - 1):
        if x < hide_w and y < hide_h:
            hp = list(hide_image.getpixel((x, y)))
            hp[0] = math.floor(float(hp[0]) / 26)
            hp[1] = math.floor(float(hp[1]) / 26)
            hp[2] = math.floor(float(hp[2]) / 26)
            bp = list(base_image.getpixel((x, y)))
            bp[0] = max(0, min(255, bp[0] - bp[0] % 10 + hp[0]))
            bp[1] = max(0, min(255, bp[1] - bp[1] % 10 + hp[1]))
            bp[2] = max(0, min(255, bp[2] - bp[2] % 10 + hp[2]))
            base_image.putpixel((x, y), tuple(bp))

base_image.save('encocded_image.png', 'PNG')


decode.py
#!/bin/env/python

import sys
from PIL import Image

if len(sys.argv) != 2:
    print("Usage: decode.py <encoded image>")
    exit(0)

try:
    base_image = Image.open(sys.argv[1])
    base_w, base_h = base_image.size
except:
    print("cannot open image " + sys.argv[1])
    exit(0)

for y in range(0, base_h - 1):
    for x in range(0, base_w - 1):
        p = list(base_image.getpixel((x, y)))
        p[0] = max(0, min(255, 26 * (p[0] % 10)))
        p[1] = max(0, min(255, 26 * (p[1] % 10)))
        p[2] = max(0, min(255, 26 * (p[2] % 10)))
        base_image.putpixel((x, y), tuple(p))

base_image.save('decoded_result.jpg', 'JPEG', quality=95)


Оригинал записи http://blog.axshavan.cz/2021/04/steganography.html
Tags: хабр
Subscribe

  • Post a new comment

    Error

    Comments allowed for friends only

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 6 comments