Logistic混沌序列加密
Logistic函数是源于一个人口统计的动力学系统,其系统方程形式如下:
X(k+1) = u X(k) [1 - X(k)],(k=0,1,…,n)
初值:X(0)
参数:u
为什么这个方程可以称作混沌呢?它什么时候是一个混沌系统呢?这个也是有条件的:
-
0 < X(0) < 1
-
3.5699456... < u <=4
当满足上述两个条件时,Logistic函数工作于混沌状态。
当迭代n次后,我们就得到了X(1)、X(2)、…,X(n)这么n个值。那么这就是一个混沌序列,是一维的暂且称作序列A,也就是我们想要得到的序列,在MATLAB中,可以看出X(i)(i=1,2,…,n)的取值是在(0,1)之间的——这是一个很好地特性,就像图像灰度值是在(0,255)之间一样。那么我们把这个一维序列归一化到(0,255)之间得到序列B。
再来看加密过程。对于一幅MN大小的图像(暂且称为Picture),我们需要产生一个同样大小的矩阵来对其进行加密。如此说来,只需要迭代MN次得到序列A,再转成序列B,此时序列B是一维的,将其转化成M*N的二维矩阵(暂且称为F)。因此,用F与Picutre进行异或,便可得到一幅新的图像,称作Rod,如此便完成了一次图像加密,加密后的图像为Rod。
Rod=Picture⊕F(⊕表示异或)
这样我们手中的秘钥是:u,X(0)
此种加密方式称作序列加密,可以看出这种加密方式改变了下像素的灰度(直方图变了),没有改变位置。
简单的matlab代码表示混沌加密如下:
%利用Logistic混沌映射,对灰度图像进行序列加密
function v=lock_logistic_gray(picture,x0,u)
[M,N]=size(picture);
x=x0;
%迭代500次,达到充分混沌状态
for i=1:500
x=u*x*(1-x);
end
%产生一维混沌加密序列
A=zeros(1,M*N);
A(1)=x;
for i=1:M*N-1
A(i+1)=u*A(i)*(1-A(i));
end
%归一化序列
B=uint8(255*A);
%转化为二维混沌加密序列
F=reshape(B,M,N);
Rod=bitxor(picture,F);%异或操作加密
v=Rod;
figure;
imshow([picture,v]);
%完
图像灰度直方图
一阶统计量特征,或者说灰度直方图特征,主要思想是对整张图像,或者图像中的感兴趣区域进行一些统计学计算,求得相应的统计量,用于在灰度层面描述图像。需要注意的是,一阶统计量特征仅适用于单通道的灰度图像,如果想对彩色图像提取一阶统计量特征,需要先对彩色图像进行灰度化操作。
衡量加密效果的指标
左暗右亮,高多低少
横轴:代表从黑到白的影调;
纵轴:代表像素量。
也就是说,直方图统计的是“照片中”不同影调的像素量多少。
直方图只统计多少,不统计在哪儿
Arnold变换置乱图像
由于Arnold本人最初对一张猫的图片进行了此种变换,因此它又被称为猫脸变换(cat映射)。Cat映射可以把图像中各像素点的位置进行置换,使其达到加密的目的,多应用在多媒体混沌加密中。
Arnold变换直观、简单、具有周期性,使用非常方便。Arnold变换的原理是先作x轴方向的错切变换,再作y轴方向的错切变换,最后的模运算相当于切割回填操作
- 公式
Cat映射的表达式如下:
式中,a、b、N为正整数。把(x,y)视为矩阵(长与宽相等)的坐标的时候,N即为矩阵的宽度
图示是Cat映射的变换示意图,从中很容易发现其产生密图的两个因素:拉伸和折叠。Cat映射通过与矩阵C相乘使x、y都变大,相当于拉伸;而取模运算使x、y又折回单位矩形内,相当于折叠。同时Arnold映射是一一映射,单位矩阵内的每一点唯一地变换到单位矩阵内的另一点。
对于数字图像来说,可以将其看成是一个函数在离散网格点处的采样值,这样就得到了一个表示图像的二维像素矩阵。矩阵中元素的值是对应点处的灰度值或RGB颜色分量值。对于数字化图像而言,这里所说的位置移动实际上是对应点的灰度值或者RGB颜色值的移动,即将原来点(x, y)处像素对应的灰度值或RGB颜色分量值移动至变换后的点(x′, y′)处。如果对一个数字图像迭代地使用离散化的Arnold变换,即将左端输出的(x′, y′)作为下一次Arnold变换的输入,则可以重复这个过程一直做下去。当迭代到某一步时,如果出现的图像呈现出杂乱无章、无法辨识的情况,那么就得到了一幅置乱图
- 周期性
需要注意的是,Arnold变换具有周期性,即多次应用Cat映射迭代以后,又会回到原始的状态。图像的大小不同,重复出现原始图像的迭代次数就不一样。因此可以把图像大小作为密钥。
F.J.Dyson和H.Falk在分析离散Arnold变换的周期性时,给出了这样的结论:对于任意的N>2,Arnold变换的周期L≤N^2/2。这是迄今为止最好的结果。计算Arnold周期的方法,对于给定的自然数N>2,下式的Arnold变换周期M是使得它成立的最小自然数n。
图片隐写
jpg图片是经过有损的压缩。png是无损的压缩,bmp是将数据原样储存
-
各种格式头文件类型
一般来讲,我们在拿到图片后都会看到一个后缀名,大部分人在看到后缀名后就会下意识的认为这个就是图片本身的后缀,但有些时候并不是。所以我们在这时需要对图片头部进行分析,精确的确认图片到底是什么图片类型。以下是各个头文件类型:
而想要查看图片的头文件的话,可以尝试用binwalk查看,而且还可以找出是否有其他图片在该文件下。
-
lsb隐写
lsb也就是最低有效位 (Least Significant Bit),一般用于bmp图片。
原理就是图片中的像数一般是由三种颜色组成,即三原色,由这三种原色可以组成其他各种颜色,例如在PNG图片的储存中,每个颜色会有 8bit,LSB隐写就是修改了像数中的最低的1bit,在人眼看来是看不出来区别的,也把信息隐藏起来了。譬如我们想把’A’隐藏进来的话,如下图,就 可以把A转成16进制的0x61再转成二进制的01100001,再修改为红色通道的最低位为这些二进制串。
-
jpeg
jpeg分为压缩数据和标记码两部分。如果在标记码中间加入数据,不会影响文件的打开,标记码如下
-
隐写工具
数据分析
原始图片:4.png
隐写了的图片:yxh1.bmp
混沌加密隐写的图片:imyxh1.bmp
置乱加密的图片:zltu1.bmp
-
加密前后的相关性
yxh1.bmp
与zltu1.bmp
:-0.04452yxh2.bmp
与zltu2.bmp
:-0.01624 -
直方图对比
yxh1.bmp
:zltu1.bmp
:yxh2.bmp
:zltu2.bmp
: -
信息熵分析
yxh1.bmp
: H_x =7.6685zltu1.bmp
: H_x =7.7109yxh2.bmp
: H_x =7.4395zltu2.bmp
: H_x =7.4931 -
秘钥空间分析
置乱加密:
xx=mod((x-1)+b*(y-1),N)+1; yy=mod(a*(x-1)+(a*b+1)*(y-1),N)+1;
秘钥:n a b
HxW的矩阵
混沌加密:
X(i+1)=X(i)*u*(1-X(i));
秘钥:u X(0)
1000x1000的矩阵
MATLAB演示代码
-
加密过程
ptr11=imread('C:\Users\KyleBear\Desktop\image-encryption-master\image-encryption-master\src\4.jpg'); ptr22=imread('C:\Users\KyleBear\Desktop\image-encryption-master\image-encryption-master\src\5.jpg'); mingwen1=fopen('C:\Users\KyleBear\Desktop\image-encryption-master\image-encryption-master\mingwen1.txt'); mingwen2=fopen('C:\Users\KyleBear\Desktop\image-encryption-master\image-encryption-master\mingwen2.txt'); ptr1=ptr11; ptr2=ptr22; %-----------------------进行第一次加密 %------------------------明文处理 data1=textscan(mingwen1,'%s','delimiter','\n'); fclose(mingwen1); data2=textscan(mingwen2,'%s','delimiter','\n'); fclose(mingwen2); data1=data1{1,1}; data2=data2{1,1}; txt1=cell2mat(data1);%将cell型转为char型 txt2=cell2mat(data2);%将cell型转为char型 lmw1=length(txt1); lmw2=length(txt2); lptr1=length(ptr1); lptr2=length(ptr2); txt1h=dec2bin(txt1(:),16); txt2h=dec2bin(txt2(:),16); txt1h=uint8(txt1h)-48; txt2h=uint8(txt2h)-48; lmw1h=dec2bin(lmw1(:),16); lmw2h=dec2bin(lmw2(:),16); %---------------------获取混沌序列 u=3.75; X=0.5; m=1; n=1;- hd=zeros(1000,1000); for i=1:1000*1000 X(i+1)=X(i)*u*(1-X(i)); if m>1000 m=1; n=n+1; end hd(n,m)=X(i+1)*100; hd1(n,m)=fix(hd(n,m)/1); hd2(n,m)=uint8(hd1(n,m)); m=m+1; end %------------------------取混沌序列中的数 for i=1:1000 gain(i,1)=hd2(1,i); gain1=dec2bin(gain,16); gain2=uint8(gain1)-48; end %---------------所取混沌数与文字进行按位异或得到密文 m=1; n=1; for i=1:1000 for j=1:16 if m<=lmw1*16 jmtxt1(i,j)=dec2bin(bitxor(gain2(i,j),txt1h(i,j))); m=m+1; end if n<=lmw2*16 jmtxt2(i,j)=dec2bin(bitxor(gain2(i,j),txt2h(i,j))); n=n+1; end end end %----------------------将文字长度写入图片最后一行 for i=1:16 pixels1= dec2bin(ptr1(lptr1,i),16);%提取图片中像素位置并将其转化成16位的二进制数 pixels2= dec2bin(ptr2(lptr2,i),16); pixels1(16)=lmw1h(i);%将字符串每一个字符依次存入所提取像素的最低位 pixels2(16)=lmw2h(i); ptr1(lptr1,i)=bin2dec(pixels1);%将改变后的二进制数转回十进制放回图片b中 ptr2(lptr2,i)=bin2dec(pixels2); end %--------------------将密文写入图片 m=1; n=1; x=1; y=1; for i=1:1000*16 if n==17 m=m+1; n=1; end if x<=lmw1*16 ptr=dec2bin(ptr1(m,n),16); ptr(16)=jmtxt1(m,n); ptr1(m,n)=bin2dec(ptr); x=x+1; end if y<=lmw2*16 ptr=dec2bin(ptr2(m,n),16); ptr(16)=jmtxt2(m,n); ptr2(m,n)=bin2dec(ptr); y=y+1; end n=n+1; end imwrite(ptr1,'yxh1.bmp'); imwrite(ptr2,'yxh2.bmp'); %-------------用MLNCML序列进行二次加密 %-------------获取MLNCML序列 %本质还是混沌 % alpha=4; % alpha=3.9; alpha=3.8; yita=0.6; epslon=0.3; % epslon=0.4; %%%%%%%%%%%%%%% p=1; q=3; M=2; %%%%%%%%%%%%%%%% lattice=5; times=256*256; digits(14); cs=zeros(lattice,times); %zeros()函数用来生成全0矩阵 ks=cs; cs_cml=zeros(lattice,times); c=zeros(1,lattice); % c(1)=0.40565487923280; c(1)=0.30565487923280; for i=2:lattice*4 c(i)=alpha*c(i-1)*(1-c(i-1)); end for i=1:lattice cs(i,1)=c(i*3); cs_cml(i,1)=c(i*3); end %%%%%%%%%%%%%%%%%%%%%%%%%%%arnold %%%%%%%%%%%%%%%%%%%%%% for n=2:times for i=1:lattice % x=mod(((i-1)+p*(i+1)),lattice); % y=mod(q*(i-1)+(p*q+1)*(i+1),lattice); x=mod(((i)+p*(i)),lattice); y=mod(q*(i)+(p*q+1)*(i),lattice); if x==0 x=lattice; end if y==lattice+1 y=1; end if y==0 y=lattice; end if x==lattice+1 x=1; end xx=i-1; yy=i+1; if xx==0 xx=lattice; end if yy==lattice+1 yy=1; end cs(i,n)=(1-epslon)*alpha*cs(i,n-1)*(1-cs(i,n-1)) +(1-yita)*((epslon/2)*( alpha*cs(xx,n-1)*(1-cs(xx,n-1)) + alpha*cs(yy,n-1)*(1-cs(yy,n-1)) ))+yita*(epslon/2)*( alpha*cs(x,n-1)*(1-cs(x,n-1)) + alpha*cs(y,n-1)*(1-cs(y,n-1)) ); cs1(i,n)=fix(10*cs(i,n)/1); cs2(i,n)=uint8(cs1(i,n)); end end %------------获取明文加密的图片并与MLNCML序列进行按位异或 hptr1=imread('yxh1.bmp'); hptr2=imread('yxh2.bmp'); m=1; n=1; for i=1:lptr1*lptr1 if n>lptr1 m=m+1; n=1; end jmtu1(m,n)=bitxor(cs2(1,i),hptr1(m,n)); n=n+1; if m>lptr1 break; end end m=1; n=1; for i=1:lptr2*lptr2 if n>lptr2 m=m+1; n=1; end jmtu2(m,n)=bitxor(cs2(2,i),hptr2(m,n)); n=n+1; if m>lptr2 break; end end imwrite(jmtu1,'jmyxh1.bmp'); imwrite(jmtu2,'jmyxh2.bmp'); %-------------------------------------------截止至此,隐写完毕,混沌加密完毕,下面进行置乱加密 % %-------------------将图片置乱 zptr1=imread('jmyxh1.bmp'); zptr2=imread('jmyxh2.bmp'); [h w]=size(zptr1); [h w]=size(zptr2); %------------置乱与复原的共同参数 n=10; a=3;b=5; N=h; %----------------------置乱 for i=1:n for y=1:h for x=1:w xx=mod((x-1)+b*(y-1),N)+1; yy=mod(a*(x-1)+(a*b+1)*(y-1),N)+1; zltu1(yy,xx)=zptr1(y,x); zltu2(yy,xx)=zptr2(y,x); end end end imwrite(zltu1,'zltu1.bmp'); imwrite(zltu2,'zltu2.bmp');
-
解密过程
jptr11=imread('zltu1.bmp'); jptr22=imread('zltu2.bmp'); lptr1=length(jptr11); lptr2=length(jptr22); %------------------------获取混沌序列 u=3.75; X=0.5; m=1; n=1; hd=zeros(1000,1000); for i=1:1000*1000 X(i+1)=X(i)*u*(1-X(i)); if m>1000 m=1; n=n+1; end hd(n,m)=X(i+1)*100; hd1(n,m)=fix(hd(n,m)/1); hd2(n,m)=uint8(hd1(n,m)); m=m+1; end %----------------------获取MLNCML序列 % alpha=4; % alpha=3.9; alpha=3.8; yita=0.6; epslon=0.3; % epslon=0.4; %%%%%%%%%%%%%%% p=1; q=3; M=2; %%%%%%%%%%%%%%%% lattice=5; times=256*256; digits(14); cs=zeros(lattice,times); ks=cs; cs_cml=zeros(lattice,times); c=zeros(1,lattice); % c(1)=0.40565487923280; c(1)=0.30565487923280; for i=2:lattice*4 c(i)=alpha*c(i-1)*(1-c(i-1)); end for i=1:lattice cs(i,1)=c(i*3); cs_cml(i,1)=c(i*3); end %%%%%%%%%%%%%%%%%%%%%%%%%%%arnold %%%%%%%%%%%%%%%%%%%%%% for n=2:times for i=1:lattice % x=mod(((i-1)+p*(i+1)),lattice); % y=mod(q*(i-1)+(p*q+1)*(i+1),lattice); x=mod(((i)+p*(i)),lattice); y=mod(q*(i)+(p*q+1)*(i),lattice); if x==0 x=lattice; end if y==lattice+1 y=1; end if y==0 y=lattice; end if x==lattice+1 x=1; end xx=i-1; yy=i+1; if xx==0 xx=lattice; end if yy==lattice+1 yy=1; end cs(i,n)=(1-epslon)*alpha*cs(i,n-1)*(1-cs(i,n-1)) +(1-yita)*((epslon/2)*( alpha*cs(xx,n-1)*(1-cs(xx,n-1)) + alpha*cs(yy,n-1)*(1-cs(yy,n-1)) ))+yita*(epslon/2)*( alpha*cs(x,n-1)*(1-cs(x,n-1)) + alpha*cs(y,n-1)*(1-cs(y,n-1)) ); cs1(i,n)=fix(10*cs(i,n)/1); cs2(i,n)=uint8(cs1(i,n)); end end %-------------------将置乱图片解密 [h w]=size(jptr11); [h w]=size(jptr22); %置乱与复原的共同参数 n=10; a=3;b=5; N=h; for i=1:n for y=1:h for x=1:w xx=mod((a*b+1)*(x-1)-b*(y-1),N)+1; yy=mod(-a*(x-1)+(y-1),N)+1 ; jptr1(yy,xx)=jptr11(y,x); jptr2(yy,xx)=jptr22(y,x); end end end %--获取MLNCML加密后的图片并与MLNCML序列进行按位异或 %---进行第一次解密 m=1; n=1; for i=1:lptr1*lptr1 if n>lptr1 m=m+1; n=1; end ptr1(m,n)=bitxor(cs2(1,i),jptr1(m,n)); n=n+1; if m>lptr1 break; end end m=1; n=1; for i=1:lptr2*lptr2 if n>lptr2 m=m+1; n=1; end ptr2(m,n)=bitxor(cs2(2,i),jptr2(m,n)); n=n+1; if m>lptr2 break; end end %---------------------------进行第二次解密 %---------提取文字长度 tlong1=0; tlong2=0; for i=1:16 pixels1= dec2bin(ptr1(lptr1,i),16); pixels2= dec2bin(ptr2(lptr2,i),16); tlong1=tlong1+(pixels1(16)-48)*2^(16-i); tlong2=tlong2+(pixels2(16)-48)*2^(16-i); end %------------提取密文 m=1; n=1; x=1; y=1; for i=1:1000*16 if n==17 m=m+1; if m>256 break; end n=1; end if x<=tlong1*16 pixels= dec2bin(ptr1(m,n),16); mw1(m,n)=pixels(16); x=x+1; end if y<=tlong2*16 pixels= dec2bin(ptr2(m,n),16); mw2(m,n)=pixels(16); y=y+1; end n=n+1; end mw1=uint8(mw1)-48; mw2=uint8(mw2)-48; %------------------------取混沌序列中的数 for i=1:1000 gain(i,1)=hd2(1,i); gain1=dec2bin(gain,16); gain2=uint8(gain1)-48; end %---------------所取混沌数与文字进行按位异或得到明文 m=1; n=1; for i=1:1000 for j=1:16 if m<=tlong1*16 mingwen1(i,j)=dec2bin(bitxor(gain2(i,j),mw1(i,j))); m=m+1; end if n<=tlong2*16 mingwen2(i,j)=dec2bin(bitxor(gain2(i,j),mw2(i,j))); n=n+1; end end end %-----------------------将提取文字输出 txt1=bin2dec(mingwen1);%转回十进制 txt2=bin2dec(mingwen2); txt1=char(txt1);%转换成对应的文字 txt2=char(txt2); fprintf('%s\n',txt1) fprintf('%s\n',txt2)