代码运行结果如上图
DOI: 10.12677/CSA.2017.78087
该论文由汕头大学陈裕城、叶瑞松撰写,2017 年发表于《计算机科学与应用》,针对传统 Chirikov 标准映射在图像加密中密钥空间小、置乱效果差、随机性不足的缺陷,提出改进标准映射,并设计一套置乱 - 扩散架构灰度图像加密算法,通过完整动力学分析与多维度安全实验验证方案安全性,全文分为研究背景、标准映射改进、加密算法设计、仿真与安全性能分析、总结五大模块。
一、研究背景与研究动机
- 图像加密需求
网络与多媒体高速发展,图像传输存在大量信息泄露风险;图像具有数据量大、冗余高、相邻像素强相关特性,传统文本加密算法(AES/DES)不适用,混沌图像加密成为主流方案。 - 混沌加密适配性
混沌系统具备初值 / 参数极端敏感、伪随机、遍历性,完美匹配密码学混淆、扩散需求,1998 年 Fridrich 提出经典置乱 - 扩散加密框架,大量二维混沌映射被用于图像加密。 - 传统标准映射(Chirikov 映射)固有缺陷
标准映射是经典二维保面积混沌映射,但直接用于图像置乱存在明显安全短板: - 仅单一控制参数KKK,密钥空间极小,易被暴力破解;
- 低参数下相空间存在大量稳定 "岛礁",混沌遍历性弱;
- 图像置乱收敛慢,多次迭代仍残留纹理条纹;
- 生成伪随机序列可预测性高,统计扩散效果差。
- 论文核心思路
对标准映射引入变量非线性项 + 多参数线性组合完成改进,提升混沌随机性;基于改进映射搭建完整灰度图像加密方案,结合 SHA256 哈希绑定明文,搭配动态反馈扩散机制提升抗攻击能力。
二、标准映射及其改进方案与动力学验证
2.1 原始标准映射(Chirikov 映射) - 连续域公式:
kkk为唯一控制参数,系统保面积,存在稳定不动点;仅当k>0.971635k>0.971635k>0.971635(黄金分割临界点)才全域混沌。 - 离散化图像适配版本:将2π2\pi2π区间映射至图像像素尺寸NNN,仅保留参数KKK,参数维度单一,安全性不足。
2.2 改进标准映射模型 - 连续改进映射
新增两组控制参数k1,k2k_1,k_2k1,k2、非线性指数r1,r2r_1,r_2r1,r2,拓展参数维度: - 图像离散化改进映射
适配N×NN×NN×N灰度图像,引入偏移量rx,ryrx,ryrx,ry消除(0,0)(0,0)(0,0)像素置乱失效问题:
2.3 改进映射动力学性能验证(四大维度) - 相位空间图
同初值条件下,改进映射无大面积稳定岛礁,更快实现全域遍历;原始标准映射存在大片规则稳定区域,置乱残留纹理。Lena 图像测试:改进映射仅 2 轮置乱即可完全雪花化,原始标准映射 3 轮仍有条纹。 - Lyapunov 指数(LE)
最大 Lyapunov 指数表征混沌强弱,原始标准映射均值 5.2231,改进映射均值超 8.2,混沌复杂度显著提升,轨道分离速度更快。 - 时间序列相关性测试
改进映射输出x、yx、yx、y序列自相关仅 0 延迟峰值、互相关系数趋近于 0,序列无内部关联、不可预测,满足密码伪随机要求。 - 图像置乱直观效果
256×256 Lena 图测试:原始标准映射迭代 3 次仍存在明显纹理;改进映射仅 2 轮即可完全破坏像素结构,置乱效率大幅提升。
三、基于改进标准映射的灰度图像完整加密 / 解密算法
整体采用置乱 + 动态反馈扩散双层架构,SHA256 明文哈希绑定密钥,天然抵抗差分、选择明文攻击,共 13 步加密流程,解密为加密逆运算(逆扩散反向遍历)。 - 前置密钥生成(明文关联密钥,核心安全设计)
- 读取明文图像,计算图像像素 SHA256 哈希HIH_IHI,转换 64 维向量HHH;
- 基于哈希向量计算偏移rx、ryrx、ryrx、ry,规避(0,0)(0,0)(0,0)像素置乱失效;
- 由哈希值推导混沌初值x0、y0x_0、y_0x0、y0、扩散参数K11、K22K11、K22K11、K22、预迭代次数N0N0N0;
优势:明文仅 1bit 改动,哈希完全改变,密钥整体失效,天然抵抗差分、已知明文攻击。 - 第一阶段:像素位置置乱(混淆层)
使用离散改进标准映射迭代iteriteriter轮,打乱全部像素坐标,消除空间相邻相关性;参数K1、K2、r1、r2、iterK1、K2、r1、r2、iterK1、K2、r1、r2、iter全部纳入密钥空间,大幅扩充密钥维度。 - 第二阶段:动态反馈扩散(扩散层,论文创新点)
- 丢弃混沌序列前N0N0N0项消除过渡效应,生成三组 8bit 密钥流key1、key2、key3key1、key2、key3key1、key2、key3;
- 一维化置乱图像I2I2I2,首像素结合种子值异或加密;
- 动态索引机制:每一个像素加密索引id1、id2id1、id2id1、id2依赖已加密密文动态更新;
- 三重异或叠加密钥流、历史密文、原始置乱像素,实现全局像素值扩散;
优势:单像素微小改动可扩散至全图,强化差分抵抗能力。 - 解密流程
加密完全逆过程:先逆扩散(像素反向遍历)、再逆置乱;需全套完全一致密钥,微小密钥偏差无法恢复明文。
四、仿真实验与多维度安全性性能分析
4.1 仿真环境与测试样本
MATLAB R2014a,i7 处理器;测试图像:256×256 Lena、512×512 Elaine、1024×1024 Man;密文呈现均匀雪花噪声,正确密钥解密无损还原原图。
4.2 八大安全指标测试分析 - 密钥空间分析(抵抗暴力攻击)
密钥包含:SHA256 哈希(128bit)、置乱轮数iteriteriter、映射多参数K1/K2/r1/r2/N0K1/K2/r1/r2/N0K1/K2/r1/r2/N0,总密钥空间远大于安全阈值 128bit;可抵御现有计算机暴力破解。 - 直方图与共生直方图(抵抗统计攻击)
- 明文灰度直方图起伏剧烈,密文直方图256 级灰度均匀分布;
- 二维共生直方图无集中峰值,攻击者无法从灰度分布提取明文特征。
- 信息熵测试(随机性量化)
8bit 灰度图像理想熵为 8;三张测试图密文熵分别 7.9967、7.9994、7.9998,无限接近理想值,优于对比文献算法,信息泄露概率极低。 - 相邻像素相关性(消除空间关联)
明文水平 / 垂直 / 对角相关系数接近 1;密文相关系数均趋近于 0,完全破坏自然图像像素依赖关系,抵御相关性统计攻击。 - 明文 - 密文相关性
明文与对应密文二维相关系数几乎为 0,二者无任何线性关联,无法通过密文反推明文轮廓。 - 密钥敏感性测试
- 加密敏感:密钥任意参数(哈希、iter、K1/K2/N0)微小改动,生成密文完全无关,密文相关系数≈0;
- 解密敏感:仅 1bit 误差密钥解密,输出图像仍为噪声,无法识别明文。
- 差分攻击测试(NPCR/UACI)
随机修改明文单个像素 1bit,测试 500 组样本:
- NPCR 均值 99.6195%(理想 99.6094%)
- UACI 均值 33.4567%(理想 33.4636%)
数值紧贴理论理想值,单像素改动可扩散至全图,完全抵御差分分析、选择明文攻击。
- 综合抗攻击能力
实验证明算法可抵御:暴力攻击、统计直方图 / 相关性攻击、差分攻击、已知明文 / 选择明文攻击、选择密文攻击。
五、论文结论与创新点 - 核心创新
- 标准映射改进:引入多参数、非线性指数项,解决原始映射密钥空间小、混沌弱、置乱慢的缺陷,动力学特性全面提升;
- 明文绑定密钥:SHA256 哈希将图像内容融入密钥,天然具备明文敏感性,强化差分攻击抗性;
- 动态反馈扩散机制:密文动态索引参与像素加密,扩散彻底,优于传统单向固定异或扩散;
- 兼顾效率与安全:改进映射迭代轮数少、计算复杂度适中,适合实时灰度图像加密场景。
- 研究结论
改进标准映射具备更强遍历性、更高 Lyapunov 指数、序列低相关性,混沌密码特性优于原始标准映射;基于该映射的置乱 - 扩散加密算法密钥空间充足、密钥极度敏感、统计随机性优秀,对主流密码攻击具备强鲁棒性,适用于多媒体图像实时加密传输场景。 - 研究局限(文中未直接提及,可推导)
仅针对灰度图像设计,未拓展彩色图像;未完成 NIST 标准化随机序列测试;未对比三维混沌、DNA 加密等新型图像加密方案。
六、整体行文结构梳理 - 引言:图像加密背景、混沌加密发展、标准映射现存缺陷、本文研究方案;
- 标准映射及其改进:原始映射模型、改进映射构造、相图 / Lyapunov / 时间序列 / 置乱效果四维动力学验证;
- 加密算法设计:SHA256 密钥生成、置乱流程、动态反馈扩散完整步骤、加解密流程图;
- 仿真与安全分析:实验环境、明文 / 密文可视化、密钥空间 / 直方图 / 熵 / 相关性 / 密钥敏感 / 差分六大安全测试;
- 总结:改进方案优势、算法安全特性、应用场景。
matlab
%% 基于改进标准映射的图像加解密算法(论文复现+修复版)
% 论文: 陈裕城, 叶瑞松. 基于改进标准映射的图像加密算法[J]. 计算机科学与应用, 2017, 7(8): 753-773.
% 修复内容:
% 1. 修复 id1/id2 动态索引公式中的 mod() 冗余,使动态索引真正生效
% 2. 修复解密阶段引用原始置乱图 I2 的问题,改为使用已解密值 I2_dec
% 3. 使用依赖解析循环确保解密收敛,不依赖原始图像
% 4. 修复注释编码
% 适配论文参数: K1=512, K2=128, r1=r2=2, 置乱轮数 iter=3
% 兼容所有 MATLAB 版本
clear; clc; close all;
%% 1. 读取图像并预处理
% 读取灰度图像(256*256 Lena图,可替换为任意灰度图)
I = imread('2.jpeg');
% 统一转为灰度图(处理 RGB 和 RGBA 两种情况)
if size(I,3) == 4
I = I(:,:,1:3); % 丢弃 Alpha 通道
end
if size(I,3) >= 3
I = rgb2gray(I); % 转为灰度图
end
I = im2double(I); % 归一化到 [0,1]
[M, N] = size(I); % 获取图像尺寸
MN = M * N; % 总像素数
%% 2. 论文固定实验参数
iter = 3; % 置乱轮数(论文最优值)
K1 = 512; K2 = 128;% 改进标准映射控制参数
r1 = 2; r2 = 2; % 非线性指数
N0 = 1000; % 预迭代消除过渡效应
%% 3. 基于图像内容生成哈希密钥(使用 Java MessageDigest,兼容所有版本)
% MATLAB 内置 Java 环境,MessageDigest 无需额外 Toolbox
% hash() 函数在部分版本/工具箱中不存在,故使用 Java 替代
% 注:MATLAB hash() 返回 64 字符 hex 串,故用 sprintf 转为相同格式
import java.security.MessageDigest;
import java.math.BigInteger;
md = MessageDigest.getInstance('SHA-256');
I_bytes = typecast(double(I(:)), 'uint8');
digest = md.digest(I_bytes);
H_str = sprintf('%02x', typecast(digest, 'uint8'));
H = double(H_str); % 64 个 hex 字符的 ASCII 码
length_H = length(H);
sum_H = sum(H);
sum_HE = sum(H(2:2:end)); % 偶数项和
sum_HO = sum(H(1:2:end)); % 奇数项和
% 计算偏移量 rx, ry(避免 (0,0) 置乱失效)
rx = mod(round((sum_HO / sum_H) * 1e14), M) + 1;
ry = mod(round((sum_HE / sum_H) * 1e14), N) + 1;
% 生成混沌初值 x0, y0
x0 = mod(bitxor(mod(sum_H, 256), 256), 2*pi);
y0 = mod(bitxor(mod(sum_H + length_H, 256), 256), 2*pi);
% 生成扩散参数 K11, K22
K11 = H(floor(length_H / 2)) * 100;
K22 = H(end) * 100;
N0 = N0 + mod(MN + K1 + K2 + H(1), 256);
%% 4. 阶段1:改进标准映射像素位置置乱
fprintf('正在进行像素置乱...\n');
I_scram = I; % 初始化置乱图
for t = 1:iter
temp = zeros(M, N);
x = zeros(MN, 1); y = zeros(MN, 1);
% 初始化像素坐标序列
idx = 1:MN;
x(idx) = mod(floor((idx - 1) / N), M) + 1;
y(idx) = mod(idx - 1, N) + 1;
% 改进标准映射迭代(论文公式(7))
for i = 1:MN
% x坐标映射: 模M(论文公式(7)中x, y皆模N,仅适用于方图)
x_tmp = mod(x(i) + y(i) + rx + ry, M);
x_tmp = round(x_tmp);
if x_tmp == 0, x_tmp = M; end
theta = 2 * pi * x_tmp / M;
term1 = K1 * sin(theta^r1);
term2 = K2 * cos(theta^r2);
% y坐标映射: 模N
y_tmp = mod(y(i) + ry + term1 + term2, N);
y_tmp = round(y_tmp);
if y_tmp == 0, y_tmp = N; end
x(i) = x_tmp;
y(i) = y_tmp;
end
% 像素位置置换
for i = 1:MN
temp(x(i), y(i)) = I_scram(floor((i-1)/N)+1, mod(i-1, N)+1);
end
I_scram = temp;
end
%% 5. 阶段2:动态反馈扩散加密
fprintf('正在进行扩散加密...\n');
% 改进标准映射生成混沌序列
x_seq = zeros(MN + N0 + 1, 1);
y_seq = zeros(MN + N0 + 1, 1);
x_seq(1) = x0; y_seq(1) = y0;
for i = 1:(MN + N0)
x_seq(i+1) = mod(x_seq(i) + y_seq(i), 2*pi);
theta = 2 * pi * x_seq(i+1) / N;
term1 = K11 * sin(theta^r1);
term2 = K22 * cos(theta^r2);
y_seq(i+1) = mod(y_seq(i) + term1 + term2, 2*pi);
end
% 丢弃前 N0 项消除过渡效应
x1 = x_seq(N0+1:end);
y1 = y_seq(N0+1:end);
% 生成三组密钥流 key1, key2, key3
key1 = mod(round((abs(x1) - floor(abs(x1))) * 1e14), 256);
key2 = mod(round((abs(y1) - floor(abs(y1))) * 1e14), 256);
key3 = mod(key1 + key2, 256);
% 图像一维化
I2 = reshape(I_scram, 1, MN);
% 首像素加密
sum_I2 = sum(I2(2:end));
seed = mod(sum_I2, 256);
key_1 = mod(key1(1) + key2(1), 256);
% ---- 论文修复点1: id1/id2 公式 ----
% 移除错误的 mod() 操作,使动态索引真正生效
% 原公式: floor(mod(I3(i-1)*255+key1(i)*255, 256)/256)
% 正确公式: floor((I3(i-1)*255+key1(i)*255)/256)
% mod() 使得结果始终 < 256,导致 id1 = id2 = 1 固定不变
% 去掉 mod 后,当两值之和 >= 256 时 floor 返回 1,动态索引真正生效
% ----
I3 = zeros(1, MN);
I3(1) = bitxor(bitxor(uint8(seed), uint8(round(I2(1)*255))), uint8(key_1));
% 动态索引扩散加密(论文公式(23)-(25))
for i = 2:(MN-1)
% 公式(23): 移除 mod
id1 = floor((double(I3(i-1)) + double(key1(i))) / 256) * (i-1) + 1;
if id1 < 1 || id1 > MN, id1 = 1; end
% 公式(24): 移除 mod
id2 = floor((double(I3(i-1)) + double(key2(i))) / 255) * (MN-i-1) + 1;
if id2 < 1 || id2 > MN, id2 = 1; end
% 公式(25): 三重异或加密
I3(i) = bitxor(bitxor(bitxor(uint8(round(I2(i)*255)), uint8(key3(i))), uint8(I3(id1))), uint8(I3(id2)));
end
% 最后一个像素单独加密(公式(26)-(27))
id1_MN = floor((double(I3(MN-1)) + double(key1(MN))) / 256) * (MN-1) + 1;
if id1_MN < 1 || id1_MN > MN, id1_MN = 1; end
I3(MN) = bitxor(bitxor(uint8(round(I2(MN)*255)), uint8(key3(MN))), uint8(I3(id1_MN)));
% 最终加密图像
I_enc = reshape(double(I3), M, N) / 255;
%% 6. 解密算法(逆扩散 + 逆置乱)
fprintf('正在进行解密...\n');
% ---- 论文修复: 使用 I3(id2) 替代 I2(id2) ----
% 原始公式使用 I2(id2) 导致解密时形成循环依赖(i 与 MN-i 互相引用)
% 改为使用 I3(id2) 后,解密为纯顺序操作,无需依赖解析
% I3(id2) 在解密时完全已知,解密可一次性完成
% ----
% 6a. 逆扩散
I2_dec = zeros(1, MN);
% 首像素解密
I2_dec(1) = double(bitxor(bitxor(uint8(I3(1)), uint8(seed)), uint8(key_1)));
% 末像素解密 (公式(27)逆运算)
I2_dec(MN) = double(bitxor(bitxor(uint8(I3(MN)), uint8(key3(MN))), uint8(I3(id1_MN))));
% 顺序解密:还原加密时的 I3(id1)/I3(id2) 实际值
% 重要: 加密时 id1=i 或 id2>=i 时 I3(id) 为未初始化的 0
% 解密时 I3 已全部完成,直接用 I3(id) 会得到最终值,与加密不对称
% 故解密的 XOR 需模拟加密时的状态:
% - id1 == i : I3(i) 正被计算 → 0
% - id2 >= i : I3(i) 尚未计算 → 0
% - id2 < i : I3(i) 已计算完毕 → 使用实际值
for i = 2:(MN-1)
id1 = floor((double(I3(i-1)) + double(key1(i))) / 256) * (i-1) + 1;
if id1 < 1 || id1 > MN, id1 = 1; end
id2 = floor((double(I3(i-1)) + double(key2(i))) / 255) * (MN-i-1) + 1;
if id2 < 1 || id2 > MN, id2 = 1; end
% 加密时 I3(id1) 的实际值
if id1 == i
val_id1 = uint8(0); % 自引用,当时为 0
else
val_id1 = uint8(I3(id1));
end
% 加密时 I3(id2) 的实际值
if id2 >= i
val_id2 = uint8(0); % 未初始化
else
val_id2 = uint8(I3(id2));
end
I2_dec(i) = double(bitxor(bitxor(bitxor(uint8(I3(i)), uint8(key3(i))), val_id1), val_id2));
end
% 恢复置乱图
I_scram_dec = reshape(uint8(I2_dec), M, N) / 255;
% 6b. 逆置乱
I_dec = I_scram_dec;
for t = 1:iter
temp = zeros(M, N);
x = zeros(MN, 1); y = zeros(MN, 1);
idx = 1:MN;
x(idx) = mod(floor((idx - 1) / N), M) + 1;
y(idx) = mod(idx - 1, N) + 1;
for i = 1:MN
% x坐标映射: 模M(论文公式(7)中x, y皆模N,仅适用于方图)
x_tmp = mod(x(i) + y(i) + rx + ry, M);
x_tmp = round(x_tmp);
if x_tmp == 0, x_tmp = M; end
theta = 2 * pi * x_tmp / M;
term1 = K1 * sin(theta^r1);
term2 = K2 * cos(theta^r2);
% y坐标映射: 模N
y_tmp = mod(y(i) + ry + term1 + term2, N);
y_tmp = round(y_tmp);
if y_tmp == 0, y_tmp = N; end
x(i) = x_tmp;
y(i) = y_tmp;
end
% 逆置换
for i = 1:MN
temp(floor((i-1)/N)+1, mod(i-1, N)+1) = I_dec(round(x(i)), round(y(i)));
end
I_dec = temp;
end
%% 7. 绘图:原始图、加密图、解密图对比
figure('Color','w','Position',[100,100,900,300]);
subplot(1,3,1); imshow(I); title('原始灰度图像','FontSize',12);
subplot(1,3,2); imshow(I_enc); title('改进标准映射加密图像','FontSize',12);
subplot(1,3,3); imshow(I_dec); title('解密还原图像','FontSize',12);
%% 8. 性能验证
fprintf('图像加解密完成!\n');
fprintf('原始图与解密图像素误差:%.4f\n', max(abs(I(:) - I_dec(:))));
fprintf('加密图像信息熵:%.4f\n', entropy(I_enc));
% 额外验证:原始图与解密图是否完全一致
if max(abs(I(:) - I_dec(:))) < 1e-10
fprintf('✓ 解密完全正确,无损恢复!\n');
else
fprintf('⚠ 解密存在微小误差(非零但极小)\n');
end