LSB最低有效位隐写

LSB隐写


LSB全称leastsignificant bit,是一种基于图片最低有效位修改储存信息的隐写方法,为什么会有这种隐写方法的产生呐,其实很简单,我们都知道三原色,即:红绿蓝。就是大多数的颜色都可以通过三原色的不同比例调剂出来。

RGB

图片的图像像数一般都是由RGB三原色(红绿蓝)组成,每一种颜色占8位,取值为0x00~0xFF,就是256种,一共包含了256的3次方种颜色,即16777216种颜色

但是人类的眼睛只可以分辨大概1000万种不同的颜色,还有很多种细微的变化人类的眼睛是觉察不到的


而LSB隐写就是通过修改RGB颜色分量的最低位二进制(LSB),来进行信息的储存,人类的眼睛并不能感知到前后的变化

每个像数可以携带3bit的信息

PYthon脚本实现LSB隐写

# -*- coding: UTF-8 -*-

from PIL import Image

def plus(str):

      #Python zfill() 方法返回指定长度的字符串,原字符串右对齐,前面填充0。

    return str.zfill(8)

def get_key(strr):

      #获取要隐藏的文件内容

    tmp = strr

    f = file(tmp,"rb")

    str = ""

    s = f.read()

    for i in range(len(s)):

        #逐个字节将要隐藏的文件内容转换为二进制,并拼接起来

        #1.先用ord()函数将s的内容逐个转换为ascii码

        #2.使用bin()函数将十进制的ascii码转换为二进制

        #3.由于bin()函数转换二进制后,二进制字符串的前面会有"0b"来表示这个字符串是二进制形式,所以用replace()替换为空

        #4.又由于ascii码转换二进制后是七位,而正常情况下每个字符由8位二进制组成,所以使用自定义函数plus将其填充为8位

        str = str+plus(bin(ord(s[i])).replace('0b',''))

        #print str

    f.closed

    return str

def mod(x,y):

    return x%y;

#str1为载体图片路径,str2为隐写文件,str3为加密图片保存的路径

def func(str1,str2,str3): 

    im = Image.open(str1)

    #获取图片的宽和高

    width = im.size[0]

    print "width:"+str(width)+"\n"

    height = im.size[1]

    print "height:"+str(height)+"\n"

    count = 0

    #获取需要隐藏的信息

    key = get_key(str2)

    keylen = len(key)

    for h in range(0,height):

        for w in range(0,width):

            pixel = im.getpixel((w,h))

            a=pixel[0]

            b=pixel[1]

            c=pixel[2]

            if count == keylen:

                break

            #下面的操作是将信息隐藏进去

            #分别将每个像素点的RGB值余2,这样可以去掉最低位的值

            #再从需要隐藏的信息中取出一位,转换为整型

            #两值相加,就把信息隐藏起来了

            a= a-mod(a,2)+int(key[count])

            count+=1

            if count == keylen:

                im.putpixel((w,h),(a,b,c))

                break

            b =b-mod(b,2)+int(key[count])

            count+=1

            if count == keylen:

                im.putpixel((w,h),(a,b,c))

                break

            c= c-mod(c,2)+int(key[count])

            count+=1

            if count == keylen:

                im.putpixel((w,h),(a,b,c))

                break

            if count % 3 == 0:

                im.putpixel((w,h),(a,b,c))

    im.save(str3)

#原图

old = "E:\Users\\test.png"

#处理后输出的图片路径

new = "E:\Users\\LSBencode.png"

#需要隐藏的信息

enc = "E:\Users\\flag.txt"

func(old,enc,new)

参考链接:LSB隐写算法 - 扣扣白白 - CSDN博客

链接中还有介绍到Python脚本实现LSB解码提取隐藏的文本信息,在此不再详细表述

在此我们以一道例题为例:


这是从网上获取的一张照片,我们运行LSB_encode.py脚本来将flag.txt 中 zhangyuxiaowanzi 的内容加密到这张图片中。

加密成功,获取图片LSBencode.png


为了获取图片最低位的有效隐藏信息,我们在这里介绍一个神器 Stegsolve 下载地址:Stegsolve下载

Stegsolve不但可以图片每个颜色通道的关闭开启的效果,而且可以指定通道的内容用HEX来显示进行预览,也可以将不同的颜色通道进行XOR、OR、AND、ADD等操作来发现通道中隐藏的内容。

我们使用Stegsolve将加密前和加密后的图片进行XOR、OR、AND、SUB等比较

在比较时候,我们发现在进行SUB的操作的时候

说明两张图片是不一样的,但是我们的肉眼并不能观察出来,

然后我们通过关闭和开启每个颜色不同的通道来观察HEX码是否有我们想要的内容。

最后在RGB三原色都在0通道的时候发现了隐藏的信息

但是这只是Stegsolve 的简单应用和LSB隐写的简单加密,而且有些题目中还可以将图片或者二维码隐藏到另一张图片中。比如说在试验吧中的一道题 最低位的吻 图片链接: http://ctf5.shiyanbar.com/stega/01.bmp

这道题目就比较好玩了因为如果你直接把图片放到Stegsolve中,你什么信息都得不到,什么都得不到.......

以为题目中给的图片为位深度为8位的.bmp图片,但是StegSolve解析8位的BMP存在一些问题

所以会产生一些错误,我们只需要将其修改为位深度为24 的.png图片即可

通过Stegsolve打开,在Red palne 0的通道中发现了一个二维码

扫描就可得到flag{i love you}

但是我一直不会的就是怎样将图片隐藏的另一张图片中,就像这道题目将二维码隐藏到了一张图片中

如果有知道的大佬不妨高抬贵手分享给我 坐等大佬指点

你可能感兴趣的:(LSB最低有效位隐写)