用MATLAB实现一个数字图像加密解密系统


需要源码的加我Q:1064611704
演示视频:https://www.bilibili.com/video/BV1uV4y167VL/?spm_id_from=333.999.0.0&vd_source=3460d1368793cd2c00d01c15b2cfcaaa



摘要&思维导图

本项目是基于MATLAB实现的数字图像加密解密系统,加密算法由笔者自主设计。此加密系统可以百分百无损恢复到原图,支持对单通道、三通道数字图像图像的加密及解密,支持对jpg、jpeg、png、tif、tiff、bmp等众多主流图像格式加密及解密。此外,用户可以自己选择加密次数,加密次数越多,像素越混乱,安全系数越高。但对于接收方而言,无需知道加密次数,一键解密图像,方便又快捷。
同时,该项目算法简单,易于学习,是个不错的数字图像处理练手项目。
算法整体思维导图如下:
思维导图

图像加密算法

笔者认为,所谓加密,就是“有规律的破坏”。即要在能保证复原的前提下尽可能地去“破坏”。这个“破坏”的程度越大,与原信息相关性越低,被攻破的难度就越大,加密效果就越好。
因此,为了尽可能的“破坏”原图像,在此加密系统中,加密算法先后进行了像素数值加密和像素分布加密两部分,从两方面先后“破坏”原图,加密效果更好。

像素值加密

像素值加密分为两步。
第一步,由于RBG三通道图像以及单通道灰度图的像素取值范围是[0,255],所以可以先用255减去各个像素值做第一次像素值变换。
测试图像如下所示:
测试图像

经过像素值第一步变换,结果如下:
像素值加密第一步后

第二步,打乱RGB三通道顺序,将RGB变换为BRG。这一步只针对RGB三通道图像,如果传入图像是灰度图就只完成第一步。
在MATLAB中,传入的三通道彩色图像存储格式是无符号整形8位(uint8)的三维矩阵。R(Red)通道的值存放在(*,*,1),G(Green)通道的值存放在(*,*,2),B(Blue)通道的值存放在(*,*,3)。经过变换,将R(Red)通道的值存放在(*,*,2),G(Green)通道的值存放在(*,*,3),B(Blue)通道的值存放在(*,*,1)。下图是在第一步输出图像的基础上进行第二步变换后的图像,也是测试图像完成像素值加密后的结果:
像素值加密完成图像

至此,像素值加密已经完成。

像素分布加密

从像素值加密完成后输出的图像来看,虽然颜色上已经与原图有较大偏差,但我们仍能从中很明显的看出原图的轮廓线信息。所以接下来我们要做的工作是打乱像素的秩序排列,破坏轮廓线信息。
为了打乱像素的排列,类似于拧魔方,我们可以先后打乱每一行、每一列的像素分布。那么,行或者列的打乱要依照怎样的打乱规则才能保证像素分布的混乱和可复原性呢?这里我设计了一个秘钥矩阵:(下列秘钥矩阵是目前系统中的秘钥矩阵)
distriKey=

矩阵第一行是索引,第二行是行偏移秘钥,第三行是列偏移秘钥。秘钥正负号决定了偏移方向,绝对值决定了偏移的程度,一行代表了一个平移周期。偏移操作使用的是MATLAB循环移动函数circshift。
在进行行偏移或列偏移时,由于传入图像的尺寸都不同,为保证一致的打乱效果,秘钥值的绝对值不能代表偏移的位数。而应该将其转换成在所在列或行中的比例,所以要先对秘钥矩阵进行预处理,即将第二、三行的秘钥值的绝对值换算成在该行的比例,然后再带上原先的符号。

预处理后秘钥矩阵distriKey=
预处理后的秘钥矩阵
如何根据第一行的索引获取当前行或列对应的秘钥值?

  • 当前行号或列号对秘钥矩阵长度取余
  • 在秘钥矩阵第一行找与取余结果相同的值
  • 找到对应索引值后,索引所在列的第二行是行变换秘钥值,第三行是列变换秘钥值

如此循环,取完秘钥矩阵最后一列的值后,下一次会再回到第一列的值。一行就是一次偏移周期。
因此,我们可以通过增大偏移周期长度来扩大偏移的自由度,提升安全系数
下面将对像素值加密后的图像先后进行一次行变换和列变换:
行变换后:
行变换后

行变换+列变换后:
行变换+列变换后

至此,我们已经完成了像素值加密和一次像素分布加密。
当然,这个加密一次的图像的加密效果体现的是使用的刚刚列举的秘钥矩阵,不是最优秘钥。
我们可以改变秘钥值和秘钥矩阵长度来优化打乱规则。例如:

  • 相邻两个秘钥值的绝对值相差要大
  • 相邻的间隔要避免相同
  • 秘钥值的正负号设置要尽可能无规律
  • 增加长度增大偏移周期
  • ··· ···

因此,秘钥矩阵为加密算法带来了很大的自由度,不易被攻破。

像素迭代加密

虽然我们从上图中基本上无从得出原图是什么样了,但是模模糊糊地仍可以看到不同区域的像素颜色不同。为了保证更高的安全系数,我们在不再更改秘钥矩阵的前提下可以进行像素迭代加密
迭代加密就是重复多次进行像素分布加密。之所以不带上像素值加密是因为像素值加密迭代的话会复原回原先的像素值,故迭代没有意义。

迭代加密2次的图像:
迭代2次
迭代加密3次的图像:
迭代3次
迭代加密5次的图像:
迭代5次
从这些结果来看,基本可以满足我们对加密的需求了。
但是为了解密时可以一键解密,不用输入解密次数,迭代加密后图像要携带迭代次数信息。
为了使输出图像携带迭代次数信息,我们可以在最左侧添加一冗余列,冗余列数值和相邻列相同,这样冗余列就很好地隐蔽到加密图像中了。然后将加密次数存放在第一行第一列第一页处,即输出图像的(1,1,1)。
通过以下图示可一目了然:
添加冗余列
迭代加密完成后,对图像的加密即已完成。

图像解密算法

加密完成后,解密就很简单了。图像解密是图像加密的逆过程。主要有以下几步:

  • 第一步,先获取(1,1,1)处的迭代次数信息,然后将第一列删除
  • 然后进行像素值解密,和加密时一样,先用255减去像素值,如果三通道图像的话再复原RGB通道顺序,将BRG变换回RGB
  • 最后再进行像素分布解密,在偏移方向上乘-1即可按照与加密时相反的方向,相同的位数进行复原,在外层套for循环,循环次数为已经获取的迭代次数,如此即可恢复原图

下面对迭代5次加密图像进行解密:
解密
可以无失真复原。

图像解密主函数:
(加密的逆过程,调用像素值变换函数和像素分布变换函数)

function imSrc = Digital_Image_Decryption(imSrc)
%该函数对传入已加密图像进行解密
%imSrc:传入三通道或单通道图像

count=imSrc(1,1,1);%获取加密次数
imSrc(:,1,:)=[];%删除冗余列
% %-----------------第一次解密:恢复像素值-----------------%
imSrc=Figure_Transform(imSrc,1);%调用封装好的函数

for time=1:count
    %-----------------第二次解密:恢复像素排列-----------------%
    imSrc=Distribution_Transform(imSrc,-1);
end

end

UI界面设计

此系统的UI界面是用MATLAB的APP Designer制作的。具体操作在此不多赘述,下面图像是UI界面的展示:

目录界面:
目录界面

加密系统界面:
加密系统界面

解密系统界面:
解密系统界面

logo设计

软件图标:
图标
原图:
logo原图

由于本人水平有限,算法和代码还有很多纰漏及不合理之处,还望大家多多批评指正!

  • 15
    点赞
  • 139
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值