实验要求
- 实验报告必须包含对F5 和MME 的原理说明;
- 实验报告必须包含详细的实验步骤描述,并配有相应的截图;
- 实验报告必须详实记录嵌入效率、均方误差等数据;
- 最终上传的压缩包中,除实验报告外,还应包含:秘密信息文件,F5、MME、Jsteg 和OutGuess 隐写样本。
实验提示
- 从网址http://www.java.com/zh_CN/可下载JRE;
- 在命令行参数下,输入“java -jar mme.jar Embed”(不包括引号,下同),可以查看使用mme.jar 进行消息嵌入的控制台参数;
- 在命令行参数下,输入“java -jar mme.jar Extract”,可以查看使用mme.jar进行消息提取的控制台参数;
- 在命令行参数下,输入“java -jar f5_embed.jar” ,可以查看使用f5_embed.jar 进行消息嵌入的控制台参数;
- 在命令行参数下,输入“java –jar f5_extract.jar” ,可以查看使用f5_extract.jar 进行消息提取的控制台参数;
- 在命令行参数下,输入“cjpeg.exe”,可以查看使用cjpeg.exe 进行消息嵌入的控制台参数;
- 在命令行参数下,输入“djpeg.exe”,可以查看使用 djpeg.exe 进行消息提取的控制台参数;
- 在命令行参数下,输入“outguess.exe”,可以查看使用outguess.exe 进行消息嵌入或提取的控制台参数;
- 将提供的“jpeg_read.mexw”32 或64 位版本(根据操作系统平台自行选择)放置于Matlab 的搜索路径下,即可使用“imgData_struct = jpeg_read(imgPath)”进行jpeg 图像的读取,其中,imgPath 为jpeg 图像路径,imgData_struct 表示读取的jpeg 图像数据,其为结构体变量。
实验原理
F5方法
F5实现了基于海明码的矩阵编码隐写在一个分组上最多修改一次,基本修改方法基于F4。
F5 方法在 JPEG 图片上的大致嵌入过程如下:
- 开始 JPEG 压缩,在系数量化后进行嵌入
- 基于密钥和系数数量生成固定序列在子空间中置乱系数位置从而进行加密
- 根据载体的容量和秘密消息的长度确定参数
- 计算码字的长度
- 使用 矩阵编码嵌入秘密消息
(a) 用 个非零系数填充缓冲区
(b) 散列这个缓冲区,生成一个具有 位的散列值。
(c) 将消息的下 位与散列值进行异或计算
(d) 如果总和为 ,则缓冲区保持不变。否则总和是缓冲区的索引 ,其对应的位置进行相应修改,同F4修改策略
(e) 如过生成零,调整缓冲区(通过再读取一个非零系数来消除 0,即从相同的系数开始重复步骤 5(a)。如果没有生成零,前进到实际缓冲区后面的新系数。如果仍有消息数据,则继续执行步骤 6(a) - 继续 JPEG 压缩(霍夫曼编码等)
现将F5方法具体的比特嵌入部分转化为一般步骤进行描述:
在 个元素的载体中嵌入 个比特基于F5方法
- (1) 为了在 个元素中嵌入 个比特,首先需要找到合适的 ,其满足
- (2) 读取载体接下来的 个比特 ,并且获取接下来的 个消息比特
- (3) 令,计算
- (4) [嵌入过程] 若 为0,则无需修改,否则将 的第 个比特 修改为
- (5) 如果消息比特还没有提取完,跳转至步骤 继续嵌入,否则嵌入完成
- (6) [提取过程] 每次从载体中提出 个比特 ,计算 从而不断顺序提取出信息
MME方法
扰动计算
修改的矩阵编码方法基于 F5 方法。虽然F5方法保证了嵌入时每 个比特最多修改一次,但是更细致的角度考虑,修改多次的扰动并不一定大,下面进行解释。
设 和 分别为 DCT 系数取整前后的值, 为取整造成的误差,则有
在F5方法下所有的操作都只可能将 加减 ,则扰动可能为 ,显然 有可能大于
在MME方法中,与F5嵌入的方式稍有不同其有四种不同的分布及处理情况,变化策略如图:
将需要对一个系数的 进行修改时,可以得出对不同情况下造成的实际扰动如下( 与 点的距离):
相对扰动 如下( 与 点的距离减去 与 点的距离)
修改方法
- 同F5方法,在嵌入时候求得 ,再计算 ,便可以找到需要修改的位置,通过修改该位置,便可以成功潜入消息。
- 但是通过在前面的分析,修改一个位置虽然次数最少,但是造成的扰动不一定最少。由此,或许可以修改多个位置达到和修改该特定位置达到同样的嵌入效果,并能使得扰动更小。
- 由于该位置是异或计算得出,显然可以由其它位置异或得到,比如等。即实际使用该方法时,可以限制取值的数量,随后遍历每一种情况从而达到最低扰动下的修改修改方案。
下面给出MME比特嵌入部分转化为一般步骤进行描述:
在 个元素的载体中嵌入 个比特基于F5方法
- (1) 为了在 个元素中嵌入 个比特,首先需要找到合适的 ,其满足 ,并选取最大修改次数
- (2) 读取载体接下来的 个比特 ,并且获取接下来的 个消息比特
- (3) 计算出每个比特的修改扰动代价
- (3) 令,计算
- (4) 当 不为0时,找出所有从 个位置中选取 个不同的位置,且其编号异或和恰好等于 的情况,计算每种情况的扰动值 ,找到扰动值最小的位置编号集合
- (5) [嵌入过程] 若 为0,则无需修改,否则将 所有在 集合中的位置的比特 修改为
- (6) 如果消息比特还没有提取完,跳转至步骤 继续嵌入,否则嵌入完成
- (7) [提取过程] 每次从载体中提出 个比特 ,计算 ,从而不断顺序提取出信息
实验过程
制备秘密信息文件:第一行为自身姓名和学号,第二行开始为任意字符,最终制备的秘密信息文件,其大小控制在50字节左右
- 编写文件 base_msg.txt
- 文件内容如下
- 其中一个汉字为两个字节,其余符合均为用一个字节储存,共51个字节
制备F5 隐写样本:以 lopez.bmp 为载体,使用 f5_embed.jar 嵌入制备的秘密信息文件,生成质量因子为90的F5 隐写样本
- 实现命令如下,生产质量因子为 90 的 stego 文件 f5_stego_q90.jpg
- java -jar f5_embed.jar -e base_msg.txt -q 90 lopez.bmp f5_stego_q90.jpg
提取 F5 隐写样本中的秘密信息:对于制备的 F5 隐写样本,使用f5_extract.jar 提取其中的秘密信息,并和原始秘密信息文件进行对比
- 实现命令如下,从 f5_stego_q90.jpg 文件中提取秘密消息,保存在 f5_msg.txt 文件中
- java -jar f5_extract.jar f5_stego_q90.jpg -e f5_msg.txt
制备 F5 载体样本:以 lopez.bmp 为载体,使用 f5_embed.jar,但不嵌入任何秘密信息文件,生成质量因子为90 的F5 载体样本
- 实现命令如下,生成无隐写质量因子为90的文件f5_cover_q90.jpg
- java -jar f5_embed.jar -q 90 lopez.bmp f5_cover_q90.jpg
计算 F5 算法的嵌入效率:对比制备的 F5 隐写和载体样本,计算嵌入效率
- 思路为使用分提取 “f5_cover_q90.jpg” 和 “f5_stego_q90.jpg” 的DCT系数,对比相同位置的值,统计出修改的值的数量
- 实验显示共有 个系数被修改,共嵌入了 个比特,故嵌入效率 ,实际程序在嵌入时候额外添加了 个比特,实际嵌入效率为
制备MME 隐写样本:以lopez.bmp 为载体,使用mme.jar 嵌入制备的秘密信息文件,生成质量因子为90 的MME 隐写样本
- 实现命令如下,生产质量因子为 90 的 stego 文件 mme_stego_q90.jpg
- java -jar mme.jar embed -q 90 -e base_msg.txt lopez.bmp mme_stego_q90.jpg
提取 MME 隐写样本中的秘密信息:对于制备的 MME 隐写样本,使用mme.jar 提取其中的秘密信息,并和原始秘密信息文件进行对比
- 实现命令如下,从 mme_stego_q90.jpg 文件中提取秘密消息,保存在 mme_msg.txt 文件中
- java -jar mme.jar extract mme_stego_q90.jpg -e mme_msg.txt
制备MME 载体样本:以lopez.bmp 为载体,使用mme.jar,但不嵌入任何秘密信息文件,生成质量因子为90 的MME 载体样本
- 实现命令如下,生成无隐写质量因子为90的文件mme_cover_q90.jpg
- java -jar mme.jar embed -q 90 lopez.bmp mme_cover_q90.jpg
计算 MME 算法的嵌入效率:对比制备的 MME 隐写和载体样本,计算嵌入效率
- 思路为使用分提取 “mme_cover_q90.jpg” 和 “mme_stego_q90.jpg” 的DCT系数,对比相同位置的值,统计出修改的值的数量
- 实验显示共有 个系数被修改,共嵌入了 个比特,故嵌入效率 ,实际程序在嵌入时候额外添加了 个比特,实际嵌入效率为
计算并对比 MME 和 F5 算法引入的隐写扰动:对于每种隐写算法,根据制备的隐写和载体样本,计算像素值均方误差,验证 MME 算法引入的隐写扰动较小
- 结果表示,MME 引入的扰动与 F5 相近,这可能是由于图片负载率较低的原因。
制备Jsteg 隐写样本:以landscape.ppm 为载体,使用cjpeg.exe 嵌入制备的秘密信息文件,生成质量因子为90 的Jsteg 隐写样本
- 实现命令如下,生成质量因子为 90 的 stego 文件 land_stego_q90.ppm
- .\cjpeg.exe -quality 90 -steg base_msg.txt landscape.ppm land_stego_q90.ppm
提取 Jsteg 隐写样本中的秘密信息:对于制备的 Jsteg 隐写样本,使用djpeg.exe 提取其中的秘密信息,并和原始秘密信息文件进行对比
- 实现命令如下,从 land_stego_q90.ppm 文件中提取秘密消息,保存在 jsteg_msg.txt 文件中
- .\djpeg.exe -steg jsteg_msg.txt land_stego_q90.ppm after_land_stego_q90.ppm
制备 OutGuess 隐写样本:以 flower.jpg 为载体,使用 outguess.exe 嵌入制备的秘密信息文件,生成OutGuess 隐写样本
- 实现命令如下,生成 stego 文件 outguess_stego.jpg
- .\outguess.exe -d base_msg.txt flower.jpg outguess_stego.jpg
提取OutGuess 隐写样本中的秘密信息:对于制备的OutGuess 隐写样本,使用outguess.exe 提取其中的秘密信息,并和原始秘密信息文件进行对比
- 实现命令如下,从 outguess_stego.jpg 文件中提取秘密消息,保存在 outguess_msg.txt 文件中
- .\outguess.exe -r outguess_stego.jpg outguess_msg.txt