Steganalysis/README.md

135 lines
8.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Steganography
# 空域编码图像
* 空域编码是指在图像空间域进行编码,也就是直接针对图像像素进行编码
* 对像素进行编码,如 LSB 算法,主要有下面两种方式
* 光栅格式
* 调色板格式 GIF(graphics interchange format)
* 一个图像编码标准往往包括多类编码方法,一个图像仅仅是其一类方法的实例。例如,常见的 BMPBitmap、 TIFF
Tagged Image File Format、 PNGPortable Network
Graphics均支持光栅格式与调色板格式编码对这两种格式
编码分别又支持多种具体编码方法
## LSB 隐写算法
* LSB 隐写是最基础、最简单的隐写方法,具有容量大、嵌入速度快、对载体图像质量影响小的特点
* LSB 的大意就是最低比特位隐写。我们将深度为 8 的 BMP 图像,分为 8 个二值平面位平面我们将待嵌入的信息info直接写到最低的位平面上。换句话说如果秘密信息与最低比特位相同则不改动如果秘密信息与最低比特位不同则使用秘密信息值代替最低比特位
[代码实现](/LSB)
![](https://www.writebug.com/myres/static/uploads/2021/12/30/d2a334c6057be058e3bdaa79efb202fb.writebug)
嵌入信息前的载体图片
![](https://www.writebug.com/myres/static/uploads/2021/12/30/5ef450e6b4aa705dfab9eaeffb47091f.writebug)
嵌入信息后的载体图片
# 变换域编码图像
## JPEG
* Joint Photographic Experts Group联合图像专家小组的缩写
* JPEG 编码
![](https://www.writebug.com/myres/static/uploads/2021/12/30/e251af7a91f2675226c55b1f2dc29186.writebug)
### JSteg 隐写
* JSteg 的算法的主要思想是将秘密消息嵌入在量化后的 DCT 系数的最低比特位上,但对原始值为 0、+1、-1 的 DCT 系数不进行嵌入,提取秘密消息时,只需将载密图像中不等于 0、l 的量化 DCT 系数的 LSB 取出即可
* JSteg 算法步骤
1. 选择载体图像,并且将载体图像划分为连续的 8×8 的子块。
2. 对每个子块使用离散余弦变换之后,用相应的质量因数的量化表量化,得到对应的 8×8 量化 DCT 子块。
3. 将需要隐藏的信息编码为二进制数据流,对 DCT 子块系数进行 Z 字形扫描,并且使用秘密信息的二进制流替换非 0 和非 1 的 DCT 系数的最低比特位。
4. 进行熵编码等,产生 JPEG 隐密图像。
* JSteg 的具体嵌入过程
1. 部分解码 JPEG 图像,得到二进制存储的 AC 系数,判断该 AC 系数是否等于正负 1 或 0若等于则跳过该 AC 系数,否则,执行下一步
2. 判断二进制存储的 AC 系数的 LSB 是否与要嵌入的秘密信息比特相同,若相同,则不对其进行修改,否则执行下一步
3. 用秘密信息比特替换二进制存储的 AC 系数的 LSB将修改后的 AC 系数重新编码得到隐秘 JPEG 图像
* JSteg 不使用 0、1 的原因
1. DCT 系数中“0”的比例最大一般可达到 60% 以上,取决于图像质量和压缩因子),压缩编码是利用大量出现连零实现的,如果改变 DCT 系数中“0”的话不能很好的实现压缩
2. DCT 系数中的“1”若变成“0”由于接受端无法区分未使用的“0”和嵌入消息后得到的“0”从而无法实现秘密信息的提取
[代码实现](Jsteg.py)
### F3 隐写
* 为了改善大量 DCT 系数不隐藏信息这一状况,人们提出了 F3 隐写
* F3 对原始值为 +1 和-1 的 DCT 系数进行了利用。F3 隐写的规则如下
1. 每个非 0 的 DCT 数据用于隐藏 1 比特秘密信息,为 0 的 DCT 系数不负载秘密信息
2. 如果秘密信息与 DCT 的 LSB 相同,便不作改动;如果不同,将 DCT 系数的绝对值减小 1符号不变
3. 当原始值为 +1 或-1 且预嵌入秘密信息为 0 时,将这个位置归 0 并视为无效,在下一个 DCT 系数上重新嵌入
* 编写代码实现嵌入,并观察 DCT 系数变化
[代码实现](F3.py)
```
JPEG的DCT系数
{0: 32939, 1: 15730, 2: 13427, 3: 11523, 4: 9540, 5: 7957, 6: 6607, 7: 5697, 8: 4834, -1: 15294, -2: 13637, -3: 11479, -4: 9683, -5: 7979, -6: 6878, -7: 5631, -8: 4871}
Jsteg begin writing!
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
经过信息隐藏后JPEG的DCT系数变化
{0: 32939, 1: 15730, 2: 12552, 3: 12398, 4: 8739, 5: 8758, 6: 6165, 7: 6139, 8: 4487, -1: 15294, -2: 12721, -3: 12395, -4: 8891, -5: 8771, -6: 6319, -7: 6190, -8: 4463}
F3steg begin writing!
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
经过信息隐藏后JPEG的DCT系数变化
{0: 47068, 1: 13416, 2: 13519, 3: 10075, 4: 9545, 5: 7077, 6: 6650, 7: 5016, 8: 4754, -1: 13308, -2: 13668, -3: 10124, -4: 9571, -5: 7249, -6: 6591, -7: 5098, -8: 4733}
F4steg begin writing!
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
经过信息隐藏后JPEG的DCT系数变化
{0: 59320, 1: 13618, 2: 11987, 3: 9875, 4: 8328, 5: 6860, 6: 5883, 7: 4910, 8: 4239, -1: 13692, -2: 11976, -3: 9976, -4: 8428, -5: 7007, -6: 5834, -7: 4964, -8: 4190}
```
* 条形图绘制
![](https://www.writebug.com/myres/static/uploads/2021/12/30/7a40002ebbd1e4d6e160bcce7b50f636.writebug)
* 未经过信息隐藏的 DCT 系数,系数近似符合拉普拉斯分布,具有几个典型特点
* 对称性 以 0 为中心达到最大值,两侧分布近似对称
* 单侧单调性 以 0 值为中心达到最大值,两侧单调下降
* 梯度下降性 小值样点较多,大值样点较少,分布曲线在两侧下降梯度逐渐减小
![](https://www.writebug.com/myres/static/uploads/2021/12/30/dd1e5a48b8e006d7456a3ba1f2c4ef35.writebug)
* JSteg 隐写的 DCT 系数
* JSteg 隐写可嵌入信息的 DCT 系数较少,隐写量较小,且相邻数值样点的个数接近,如 2 和 3-2 和-3 形成了值对,卡方特征变化明显,因而提出了 F3 隐写
![](https://www.writebug.com/myres/static/uploads/2021/12/30/5231d6a6b7690459b0c318d62221b60e.writebug)
* F3 隐写的 DCT 系数
* F3 的设计虽然防止了相邻值出现数量接近的现象,也维持了分布函数的对称性,但使得偶数的分布增加,没有满足单调性
* 这是因为载体绝对值为 1 的数值较多,当其被修改为 0 时,嵌入算法继续嵌入直到找到一个偶数值,或者将一个奇数值改为偶数值,这样绝对值为 1 的系数可以支持嵌入 1但是不支持嵌入 0需要使用或制造一个偶数
* 另外0 系数的数量有相应的增加,产生分布曲线向 0 收缩的现象
### F4 隐写
* 为了克服 F3 的缺陷F4 对不同正负号的奇偶系数采用了不同的嵌入与消息表示方法
* **F4 用负偶数、正奇数代表嵌入了消息比特 1用负奇数、正偶数代表嵌入了 0**
* 但仍然通过减小绝对值的方法进行修改,如果减小绝对值后系数为 0 则继续往下嵌入当前比特
* [代码实现](F4.py)
![](https://www.writebug.com/myres/static/uploads/2021/12/30/cf7f25ee63efd8a6f3f3b0688ca49fe1.writebug)
* F4 隐写的 DCT 系数
* F4 显然保持了载体分布函数的对称性,也保持了载体分布函数的单调性与梯度下降性
* 但 F4 依然存在使含密载体分布函数形状向 0 收缩的现象
### F5 隐写
F5 隐写实现了基于汉明码的矩阵编码隐写,在一个分组上最多修改 R=1 次以嵌入 $2^r-1-r$ 比特,采用的基本嵌入方法是基于 F4 隐写的
F5 的嵌入步骤
- 获得嵌入域。若输入的是位图,则进行 JPEG 编码得到 JPEG 系数;若输入的是 JPEG 图像,则进行熵编码的解码得到 JPEG 系数
- 位置置乱。根据口令生成的密钥位一个伪随机数发生器,基于伪随机数发生器置乱 JPEG 系数的位置
- 编码参数确定。为了提高嵌入效率,一般希望 n 尽可能大,因此,根据载体中可用系数的数量与消息的长度确定参数 r并计算$n=2^r-1$
- 基于($n=2^r-1,r$)的汉明分组码得到编码校验矩阵,开始嵌入消息:
- ① 按置乱后的顺序取下面 n 个非零系数,在其中的 LSB 序列中按照以上编码嵌入 n-r 比特的消息;
- ② 如果未发生修改,并且还有需要嵌入的消息,则返回 ① 继续嵌入下一分组;
- ③ 如果进行了修改,则判断是不是有系数值收缩到 0如果没有并且还有需要嵌入的消息则返回 ① 继续嵌入下一分组,如果有,取出一个新的非零系数组成新的一组 n 个非零系数,在其中的 LSB 序列中按照以上编码重新嵌入以上 n-r 比特的消息,直到没有修改或收缩,最后,如果还有需要嵌入的消息,则返回 ① 继续嵌入下一分组
- 位置逆置乱。恢复 DCT 系数原来的位置顺序
- 熵编码。按照 JPEG 标准无损压缩 DCT 量化系数,得到 JPEG 文件
# 参考资料
* 隐写学原理与技术 By 赵险峰
* 数字媒体中的隐写术 By J.Fridrich