【论文地址】
一种基于两个复杂混沌系统的混合彩色图像加密算法
摘要
本文在复杂Chen和复杂Lorenz系统的基础上,提出了一种新的彩色图像加密算法。与真实混沌系统相比,复杂混沌系统具有更大的混沌范围和更复杂的行为,可以进一步提高彩色图像加密的安全性,扩大密钥空间。加密算法由三个步骤组成。在置乱过程中,对明文图像的像素分别进行二维和一维的RGB通道排列。在扩散过程中,采用异或(XOR)操作来隐藏像素信息。最后,利用混合RGB信道实现多级加密。
引言
在计算机和网络技术飞速发展的今天,数据传输和存储的安全性越来越受到人们的关注。混沌系统的一些基本性质,如对初始条件的敏感性和伪随机性质,满足了一个好的密码系统的要求。从这个意义上说,图像混沌加密作为图像加密的一个新领域得到了迅速的发展,自1989年Matthews提出第一个混沌密码学以来,许多研究者都提出了基于混沌的密码学方案,基于混沌的加密在其他领域也有良好的性能,如视频加密。
但目前研究的密钥空间还有待完善。在大多数理论中,使用一维混沌映射生成伪随机数,而伪随机数的密钥空间小,可能会削弱对潜在攻击的抵抗能力。此外,由于在混沌系统的迭代上花费过多的时间,可能会降低加密速度。
面对这些问题,一些研究者在过去几年里做出了一些贡献,可以概括为四个方向。引入多维或复杂的混沌映射;结合多个混沌映射;设计更复杂的排列-扩散算法;或者增加一些传统的加密方法。
本文提出的基于复杂Chen系统和复杂Lorenz系统的方案可以扩大密钥空间,以应对潜在的攻击。另外,我们对像素混淆部分进行了二维处理,最后增加了一步处理,其主要思想是利用复杂混沌系统产生的伪随机数序列混合RGB通道。该算法的突出特点是具有多级扩散和更大的密钥空间,这些组合过程可以从各个方面保证系统的安全性,抵御攻击,避免上述问题的存在。
伪随机序列生成
伪随机性是混沌系统的基本性质,适用于对信息进行加密覆盖。一维混沌系统(如logistic map)因其简单、高效而被广泛应用于伪随机数序列的生成。然而,他们的缺点,如小的密钥空间,是如此明显以致于许多提出的混沌密码系统已被一些密码分析方法破解。复杂混沌系统中复变量的实部和虚部使实变量的数量增加了一倍,增加了复杂性和随机性。因此,本文采用了复杂的Chen系统和复杂的Lorenz系统来克服系统的不足,提高系统的安全性。
复杂Chen系统
复杂Chen系统公式定义如下:
{
z
1
˙
=
a
1
(
z
2
−
z
1
)
z
2
˙
=
(
c
1
−
a
1
)
z
1
−
z
1
z
3
+
c
1
z
2
z
3
˙
=
1
2
(
z
1
‾
z
2
+
z
1
z
2
‾
)
−
b
1
z
3
\left\{ \begin{array}{lr} \dot{z_1}=a_1(z_2-z_1) \\ \dot{z_2}=(c_1-a_1)z_1-z_1z_3+c_1z_2 \\ \dot{z_3}=\frac{1}{2}(\overline{z_1}z_2+z_1\overline{z_2})-b_1z_3 \end{array} \right .
⎩⎨⎧z1˙=a1(z2−z1)z2˙=(c1−a1)z1−z1z3+c1z2z3˙=21(z1z2+z1z2)−b1z3
其中,
a
1
,
b
1
a_1,b_1
a1,b1和
c
1
c_1
c1是系统的控制参数,都是正实数。
z
1
=
z
1
r
+
j
z
1
i
z_1=z_1^r+jz_1^i
z1=z1r+jz1i和
z
2
=
z
2
r
+
j
z
2
i
z_2=z_2^r+jz_2^i
z2=z2r+jz2i是复变量,
z
3
z_3
z3是实变量。根据论文所说,当
a
1
=
27
,
b
1
=
4.5
a_1=27,b_1=4.5
a1=27,b1=4.5且
c
1
=
23
c_1=23
c1=23时,复杂Chen系统有更复杂和更混沌的表现,但是混沌系统对初始值不敏感,且吸引子图像与论文所述也不一样,反而当
a
1
=
35
,
b
1
=
3
a_1=35,b_1=3
a1=35,b1=3且
c
1
=
28
c_1=28
c1=28时(正是Chen混沌控制参数),吸引子图像与论文相符,且对初值敏感,所以此处存疑???此时吸引子图像如下:
复杂Lorenz系统
复杂Lorenz系统公式定义如下:
{
w
1
˙
=
a
2
(
w
2
−
w
1
)
w
2
˙
=
c
2
w
1
−
w
2
−
w
1
w
3
w
3
˙
=
1
2
(
w
1
‾
w
2
+
w
1
w
2
‾
)
−
b
2
w
3
\left\{ \begin{array}{lr} \dot{w_1}=a_2(w_2-w_1) \\ \dot{w_2}=c_2w_1-w_2-w_1w_3 \\ \dot{w_3}=\frac{1}{2}(\overline{w_1}w_2+w_1\overline{w_2})-b_2w_3 \end{array} \right .
⎩⎨⎧w1˙=a2(w2−w1)w2˙=c2w1−w2−w1w3w3˙=21(w1w2+w1w2)−b2w3
其中,
a
2
,
b
2
a_2,b_2
a2,b2和
c
3
c_3
c3是正实数,
w
1
=
w
1
r
+
j
w
1
i
w_1=w_1^r+jw_1^i
w1=w1r+jw1i和
w
2
=
w
2
r
+
j
w
2
i
w_2=w_2^r+jw_2^i
w2=w2r+jw2i是复数变量,
w
3
w_3
w3是实数。同样,论文中描述当
a
2
=
14
,
b
2
=
3.7
a_2=14,b_2=3.7
a2=14,b2=3.7且
c
2
=
35
c_2=35
c2=35时,复杂Lorenz系统有很好的的混沌表现,但是实验时发现这样的控制参数没有形成混沌,反而当
a
2
=
10
,
b
2
=
28
a_2=10,b_2=28
a2=10,b2=28且
c
2
=
8
/
3
c_2=8/3
c2=8/3时(正是Lorenz混沌控制参数),吸引子图像与论文相符,所以此处也是没想明白???此时吸引子图像如下:
密钥生成
汉明距离是一种表示两个等长序列对应位置的不同元素个数的方法,序列
α
=
(
α
1
,
α
−
2
,
.
.
.
,
α
n
)
\alpha=(\alpha_1,\alpha-2,...,\alpha_n)
α=(α1,α−2,...,αn)和
β
=
(
β
1
,
β
2
,
.
.
.
,
β
n
)
\beta=(\beta_1,\beta_2,...,\beta_n)
β=(β1,β2,...,βn)的汉明距离
H
(
α
,
β
)
H(\alpha,\beta)
H(α,β)定义如下:
{
H
(
α
,
β
)
=
∑
i
=
1
n
h
(
α
i
,
β
i
)
h
(
α
i
,
β
i
)
=
{
0
,
α
i
=
β
i
1
,
α
i
≠
β
i
\left\{ \begin{array}{lr} H(\alpha,\beta)=\sum_{i=1}^{n}{h(\alpha_i,\beta_i)} \\ h(\alpha_i,\beta_i)= \begin{cases} 0, \ \alpha_i=\beta_i \\ 1, \ \alpha_i \neq \beta_i \end{cases} \end{array} \right .
⎩⎪⎨⎪⎧H(α,β)=∑i=1nh(αi,βi)h(αi,βi)={0, αi=βi1, αi=βi
基于上式,可以得到R、G、B三个通道的汉明距离
H
R
G
,
H
R
B
,
H
G
B
H_{RG},H_{RB},H_{GB}
HRG,HRB,HGB,因此生成密钥如下:
{
H
=
[
H
R
G
,
H
R
B
,
H
G
B
,
H
R
G
,
H
R
B
,
H
G
B
]
,
K
e
y
1
=
{
K
e
y
C
h
e
n
K
e
y
L
o
r
e
n
z
K
e
y
2
=
m
o
d
(
H
,
K
e
y
1
)
;
\left\{ \begin{array}{lr} H=[H_{RG},H_{RB},H_{GB},H_{RG},H_{RB},H_{GB}],\\ Key1= \begin{cases} Key_{Chen} \\ Key_{Lorenz} \end{cases} \\ Key2=mod(H,Key1); \end{array} \right .
⎩⎪⎪⎪⎨⎪⎪⎪⎧H=[HRG,HRB,HGB,HRG,HRB,HGB],Key1={KeyChenKeyLorenzKey2=mod(H,Key1);
其中,
K
e
y
C
h
e
n
Key_{Chen}
KeyChen和
K
e
y
L
o
r
e
n
z
Key_{Lorenz}
KeyLorenz是两个大小为6的序列,并且6个元素是由消息发送者选择的。 Key2是两个复杂混沌系统的初始值。
在生成密钥时,对于不同的明文图像,在每个加密过程中汉明距离的值是不同的,消息接收方可以重新计算汉明距离,以保证解密后信息的完整性。因此,以上这些都达到了更高的安全级别。
伪随机序列
采用上文提及的复杂混沌系统生成的混沌序列是浮点数值,不适合直接应用于图像加密方案。有必要将一个通道中的像素值修改为从0到255的整数,整数伪随机数序列转换公式如下:
t
i
=
f
i
x
(
m
o
d
(
s
i
∗
1
0
12
,
256
)
)
t_i=fix(mod(s_i*10^{12},256))
ti=fix(mod(si∗1012,256))
其中,
s
i
s_i
si是 来自两个混沌系统的混沌序列;mod返回除法之后的余数(即取模运算)。
加密方案
明文图像加密的主要思想是对像素的位置进行排列,并通过不同的方法对像素值进行隐藏。本文的算法如下:
- 首先,利用两个复杂的混沌系统生成随机序列对明文图像进行加密,改善了密钥空间,提高了对潜在攻击的安全性。
- 其次,与传统的加密方案相比,我们的加密方案采用了图像的二维特征。
- 第三,我们增加了一步混合RGB通道和混沌序列的过程,在前面的步骤的基础上实现了全方位多级加密。
本文采用512*512的“Lena”图像进行试验,加密步骤如图:
像素置乱
在我们的加密算法中,这部分的目的是混淆像素在每个通道中的位置。为了描述简单,以R通道为例来说明加密过程,其他两个通道类似,只是使用了两个复杂混沌系统中不同的伪随机数序列。
假设明文图像为 P M ∗ N P_{M*N} PM∗N,其R通道的数据是一个M*N的二维数组,两个伪随机序列是 t x t_x tx和 t y t_y ty,大小分别为M和N。 p o s x pos_x posx和 p o s y pos_y posy两个序列用来标定 t x , t y t_x,t_y tx,ty 和 P M ∗ N P_{M*N} PM∗N中元素的位置;然后我们根据元素大小分别对 t x t_x tx和 t y t_y ty进行排序,得到新序列 p o s x pos_x posx, p o s y pos_y posy。最后, P M ∗ N P_{M*N} PM∗N根据新的 t x 、 t y t_x、t_y tx、ty重新排列。
排序过程图如下:
然后, P M ∗ N P_{M*N} PM∗N扁平化为一维数组 P n P_n Pn,对于一个伪随机序列 t z t_z tz,它的大小为n的元素位置标定
序列为 p o s z pos_z posz,使用相同的方法来排列 P n P_n Pn。
异或操作
异或操作是加密和解密信息的一种简单而有用的方法。在此步骤过程中,通过对像素值与伪随机数序列进行异或运算来隐藏像素信息。
用三个整数伪随机序列 t R , t G , t B t_R,t_G,t_B tR,tG,tB在每个通道上执行异或操作。
混沌马尾
最后的加密步骤是用混沌序列混合RGB通道,这个加密步骤过程被生动地称为“混乱马尾”,因为它的过程就像马尾一样。RGB通道之间的界限可以用这种方法打破。因此,从一个通道到另一个通道解密图像是完全不可能的。该部分的加密步骤过程如下所示:
- 为了实现马尾在每一部分的长度是变化的,设计了一个函数用于创建随机元素长度的序列, M m i x M_{mix} Mmix:
M m i x = F u n M i x R G B ( u i , z o o m ) M_{mix}=FunMixRGB(u_i,zoom) Mmix=FunMixRGB(ui,zoom)
u i u_i ui是复杂混沌系统生成的一个序列,这里i设置为5。zoom是最大步长限制。
-
编马尾的步骤如下:
步骤1:用Mmix中第一个元素的长度交换R和G通道中的数据
步骤2:用Mmix中下一个元素的长度交换R和B通道中的数据;
步骤3:用Mmix中下一个元素的长度交换G和B通道中的数据;
步骤4:重复步骤从1到3,直到所有的像素被交换。
”混沌马尾辫“的基本加密原理和处理步骤如图所示
实验结果
实验代码
加解密python代码
import cv2
import numpy as np
import matplotlib.pyplot as plt
#绘制三维图像
import mpl_toolkits.mplot3d as p3d
'''
复杂Chen吸引子生成函数
参数为三个初始坐标,三个初始参数(2个为复数),迭代次数
返回五个一维数组(可以生成5个混沌序列)
'''
def Complex_Chen(x0,y0,z0,a,b,c,T):
h=0.001
#r表示实部,i表示虚部
x_r=[]
x_i=[]
y_r=[]
y_i=[]
z=[]
for t in range(T):
xt=x0+h*(a*(y0-x0))
yt=y0+h*((c-a)*x0-x0*z0+c*y0)
zt=z0+h*(1/2*(x0.conjugate()*y0+x0*y0.conjugate())-b*z0)
#x0、y0、z0统一更新
x0,y0,z0=xt,yt,zt
x_r.append(x0.real)
x_i.append(x0.imag)
y_r.append(y0.real)
y_i.append(y0.imag)
z.append(z0.real)
return x_r,x_i,y_r,y_i,z
'''
复杂Lorenz吸引子生成函数
参数为三个初始坐标,三个初始参数,迭代次数
返回五个一维list
'''
def Complex_Lorenz(x0,y0,z0,p,q,r,T):
#微分迭代步长
h=0.01
x_r=[]
x_i=[]
y_r=[]
y_i=[]
z=[]
for t in range(T):
xt=x0+h*p*(y0-x0)
yt=y0+h*(q*x0-y0-x0*z0)
zt=z0+h*(1/2*(x0.conjugate()*y0+x0*y0.conjugate())-r*z0)
#x0、y0、z0统一更新
x0,y0,z0=xt,yt,zt
x_r.append(x0.real)
x_i.append(x0.imag)
y_r.append(y0.real)
y_i.append(y0.imag)
z.append(z0.real)
return x_r,x_i,y_r,y_i,z
'''
计算图像的三通道之间的汉明距离
params:img-path
'''
def Hamming(img):
#汉明距离
HRG=0
HRB=0
HGB=0
im=cv2.imread(img)
h,w,dim=im.shape
B,G,R=cv2.split(im)
for i in range(h):
for j in range(w):
if R[i][j]!=G[i][j]:
HRG+=1
if R[i][j]!=B[i][j]:
HRB+=1
if G[i][j]!=B[i][j]:
HGB+=1
return HRG,HRB,HGB
'''
加密过程中第一次置乱:行列置乱
'''
def channel_permutation(tx,ty,channel):
h,w=channel.shape
#标记,0-h
posx=np.arange(0,h)
posy=np.arange(0,w)
#根据序列tx、ty对posx和posy排序
tx_posx=list(zip(tx,posx))
tx_posx.sort(key=lambda x:x[0])
ty_posy=list(zip(ty,posy))
ty_posy.sort(key=lambda x:x[0])
#得到排序后的标记列表
new_posx=list(list(zip(*tx_posx))[1])
new_posy=list(list(zip(*ty_posy))[1])
#行列置乱后的新的二维像素矩阵,这块注意如果不新定义一个变量,会造成覆盖
new_channel=np.array(channel)
for i in range(h):
for j in range(w):
new_channel[i][j]=channel[new_posx[i]][new_posy[j]]
return new_channel
'''
图像解密逆第一次二维置乱:逆行列置乱
'''
def channel_reverse_permutation(tx,ty,channel):
h,w=channel.shape
#标记,0-h
posx=np.arange(0,h)
posy=np.arange(0,w)
#根据序列tx、ty对posx和posy排序
tx_posx=list(zip(tx,posx))
tx_posx.sort(key=lambda x:x[0])
ty_posy=list(zip(ty,posy))
ty_posy.sort(key=lambda x:x[0])
#得到排序后的标记列表
new_posx=list(list(zip(*tx_posx))[1])
new_posy=list(list(zip(*ty_posy))[1])
#行列置乱后的新的二维像素矩阵
new_channel=np.array(channel)
for i in range(h):
for j in range(w):
new_channel[new_posx[i]][new_posy[j]]=channel[i][j]
return new_channel
'''
生成新的混沌系统初始值,作为密钥
'''
def Generate_Key(img,key):
#计算图像各通道间的汉明距离
HRG,HRB,HGB=Hamming(img)
#根据初始密钥生成密钥
#复数实部和虚部分别运算
#z1初值
real=HRG%key[0].real
imag=HRG%key[0].imag
key[0]=complex(real,imag)
#z2初值
real=HRB%key[1].real
imag=HRB%key[1].imag
key[1]=complex(real,imag)
#z3初值
key[2]=HGB%key[2]
#w1初值
real=HRG%key[3].real
imag=HRG%key[3].imag
key[3]=complex(real,imag)
#w2初值
real=HRB%key[4].real
imag=HRB%key[4].imag
key[4]=complex(real,imag)
#w3初值
key[5]=HGB%key[5]
#得到新的混沌系统初值key
return key
'''
加密图像,
params:
img-图像path
key-初始密钥,大小为6
'''
def encrypt(img,key):
#Complex_Chen控制参数
a=35
b=3
c=28
#给定复杂Lorenz控制参数
p=10
q=28
r=8/3
im=cv2.imread(img)
h,w,dim=im.shape
B,G,R=cv2.split(im)
#迭代次数,去掉前1000次迭代,消除瞬态效应
T=1000+w*h
z1=key[0]
z2=key[1]
z3=key[2]
w1=key[3]
w2=key[4]
w3=key[5]
chen_seqs=Complex_Chen(z1,z2,z3,a,b,c,T)
Lorenz_seqs=Complex_Lorenz(w1,w2,w3,p,q,r,T)
seq_t=[]
for i in range(5):
seq_t.append(chen_seqs[i][1000:])
for i in range(5):
seq_t.append(Lorenz_seqs[i][1000:])
#seq_t是一个二维列表10 * (w*h),共包含了10个混沌序列
#为了便于运算,将混沌序列浮点类型数据转成0-255的整数
for i in range(len(seq_t)):
for j in range(len(seq_t[0])):
seq_t[i][j]=int(seq_t[i][j]*(10**12)%256)
#像素置乱
#RGB三通道各自行列置乱,采用的混沌序列都来自一个
#R通道,使用大小为h的tx混沌序列进行行置乱,大小为w的ty混沌序列进行列置乱,混沌序列来自z1_r
tx=seq_t[0][:h]
ty=seq_t[0][h:h+w]
# print(R[0][:10])
R=channel_permutation(tx,ty,R)
#扁平化为一维进行排列,row-major方式
Rn=R.flatten(order='C')
#根据序列tz排序R通道一维像素,tz来自z1_i
tz=seq_t[1]
tz_Rn=list(zip(tz,Rn))
tz_Rn.sort(key=lambda x:x[0])
new_Rn=np.array(list(zip(*tz_Rn))[1])
#同样方式排序G通道
tx=seq_t[0][h+w:2*h+w]
ty=seq_t[0][2*h+w:2*h+2*w]
G=channel_permutation(tx,ty,G)
Gn=G.flatten(order='C')
#序列tz来自z2_r
tz=seq_t[2]
#根据序列tz排序G通道一维像素
tz_Gn=list(zip(tz,Gn))
tz_Gn.sort(key=lambda x:x[0])
new_Gn=np.array(list(zip(*tz_Gn))[1])
#同样方式排序B通道
tx=seq_t[0][2*h+2*w:3*h+2*w]
ty=seq_t[0][3*h+2*w:3*h+3*w]
B=channel_permutation(tx,ty,B)
Bn=B.flatten(order='C')
#序列tz来自z2_i
tz=seq_t[3]
#根据序列tz排序B通道一维像素
tz_Bn=list(zip(tz,Bn))
tz_Bn.sort(key=lambda x:x[0])
new_Bn=np.array(list(zip(*tz_Bn))[1])
#RGB三通道异或操作进行置乱
tR=seq_t[4]
tG=seq_t[5]
tB=seq_t[6]
Rn_xor=new_Rn^tR
Gn_xor=new_Gn^tG
Bn_xor=new_Bn^tB
Rn_xor=Rn_xor.astype(np.uint8)
Gn_xor=Gn_xor.astype(np.uint8)
Bn_xor=Bn_xor.astype(np.uint8)
#混乱编马尾
#创建随机元素长度序列
#最大步长限制
zoom=30
mix=np.array(seq_t[7])%zoom
mix_sum=0
#混乱编码次数
time=0
while mix_sum<w*h:
#第一步,交换通道R-G
#下面一行是错误地赋值,这个bug调了好久,tmp相当于只是一个指针,Rn_xor发生变化,tmp还是会跟着变化
# tmp=Rn_xor[mix_sum:mix[time]]
end=min(mix_sum+mix[time],w*h)
#tmp一定要下面这种定义
tmp=np.array(Rn_xor[mix_sum:end])
Rn_xor[mix_sum:end]=Gn_xor[mix_sum:end]
Gn_xor[mix_sum:end]=tmp
mix_sum+=mix[time]
if mix_sum>=w*h:
break
time+=1
#第二步,交换通道R-B
end=min(mix_sum+mix[time],w*h)
tmp=np.array(Rn_xor[mix_sum:end])
Rn_xor[mix_sum:end]=Bn_xor[mix_sum:end]
Bn_xor[mix_sum:end]=tmp
mix_sum+=mix[time]
if mix_sum>=w*h:
break
time+=1
#第三步,交换通道G-B
tmp=np.array(Gn_xor[mix_sum:end])
Gn_xor[mix_sum:end]=Bn_xor[mix_sum:end]
Bn_xor[mix_sum:end]=tmp
mix_sum+=mix[time]
time+=1
#转成三维RGB图像,多种方式,这里逆上面flatten
#逆flatten将三通道分别重新转成二维
R=Rn_xor.reshape((h,w),order='C')
G=Gn_xor.reshape((h,w),order='C')
B=Bn_xor.reshape((h,w),order='C')
#逆split,转成三通道彩色加密图像
img_encrypt=cv2.merge([R,G,B])
#返回加密后的图像,返回的是RGB通道顺序
return img_encrypt
'''
加密图像解密,解密是加密的逆过程
params:
img-加密图像path
key-密钥,大小为6
'''
def decrypt(img,key):
#Complex_Chen控制参数
a=35
b=3
c=28
#给定复杂Lorenz控制参数
p=10
q=28
r=8/3
#得到混沌系统初始值
z1=key[0]
z2=key[1]
z3=key[2]
w1=key[3]
w2=key[4]
w3=key[5]
im=cv2.imread(img)
# print('加密后的图像:',im[:20,:,(2,1,0)])
h,w,dim=im.shape
B,G,R=cv2.split(im)
#迭代次数,去掉前1000次迭代,消除瞬态效应
T=1000+w*h
chen_seqs=Complex_Chen(z1,z2,z3,a,b,c,T)
Lorenz_seqs=Complex_Lorenz(w1,w2,w3,p,q,r,T)
seq_t=[]
for i in range(5):
seq_t.append(chen_seqs[i][1000:])
for i in range(5):
seq_t.append(Lorenz_seqs[i][1000:])
#seq_t是一个二维列表10 * (w*h),共包含了10个混沌序列
#为了便于运算,将混沌序列浮点类型数据转成0-255的整数
# print(type(seq_t),type(seq_t[0]))
for i in range(len(seq_t)):
for j in range(len(seq_t[0])):
seq_t[i][j]=int(seq_t[i][j]*(10**12)%256)
#逆混乱马尾操作,再执行一次编马尾操作即可
Rn_xor=R.flatten(order='C')
Gn_xor=G.flatten(order='C')
Bn_xor=B.flatten(order='C')
#创建随机元素长度序列
#最大步长限制
zoom=30
mix=np.array(seq_t[7])%zoom
mix_sum=0
#混乱编码次数
time=0
while mix_sum<w*h:
#第一步,交换通道R-G
end=min(mix_sum+mix[time],w*h)
tmp=np.array(Rn_xor[mix_sum:end])
Rn_xor[mix_sum:end]=Gn_xor[mix_sum:end]
Gn_xor[mix_sum:end]=tmp
mix_sum+=mix[time]
if mix_sum>=w*h:
break
time+=1
#第二步,交换通道R-B
end=min(mix_sum+mix[time],w*h)
tmp=np.array(Rn_xor[mix_sum:end])
Rn_xor[mix_sum:end]=Bn_xor[mix_sum:end]
Bn_xor[mix_sum:end]=tmp
mix_sum+=mix[time]
if mix_sum>=w*h:
break
time+=1
#第三步,交换通道G-B
end=min(mix_sum+mix[time],w*h)
tmp=np.array(Gn_xor[mix_sum:end])
Gn_xor[mix_sum:end]=Bn_xor[mix_sum:end]
Bn_xor[mix_sum:end]=tmp
mix_sum+=mix[time]
time+=1
#逆操作异或运算,再和混沌序列异或一次即可
tR=seq_t[4]
tG=seq_t[5]
tB=seq_t[6]
new_Rn=Rn_xor^tR
new_Gn=Gn_xor^tG
new_Bn=Bn_xor^tB
#把int32类型转成uint8类型(0-255)
new_Rn=new_Rn.astype(np.uint8)
new_Gn=new_Gn.astype(np.uint8)
new_Bn=new_Bn.astype(np.uint8)
#逆像素置乱
#通道R
#逆第二次一维置乱
tz=seq_t[1]
seq=np.arange(w*h)
tz_seq=list(zip(tz,seq))
#根据序列tz得到R通道真实的索引序列
tz_seq.sort(key=lambda x:x[0])
tz=list(list(zip(*tz_seq))[1])
#根据新的索引序列tz对通道R进行排序
tz_Rn=list(zip(tz,new_Rn))
tz_Rn.sort(key=lambda x:x[0])
Rn=np.array(list(zip(*tz_Rn))[1])
#转成二维
R=Rn.reshape((h,w),order='C')
#逆第一次二维置乱即行列置乱,采用与加密时同样的混沌序列
tx=seq_t[0][:h]
ty=seq_t[0][h:h+w]
R=channel_reverse_permutation(tx,ty,R)
#通道G
tz=seq_t[2]
seq=np.arange(w*h)
tz_seq=list(zip(tz,seq))
#根据序列tz得到G通道真实的索引序列
tz_seq.sort(key=lambda x:x[0])
tz=list(list(zip(*tz_seq))[1])
#根据新的索引序列tz对通道G进行排序
tz_Gn=list(zip(tz,new_Gn))
tz_Gn.sort(key=lambda x:x[0])
Gn=np.array(list(zip(*tz_Gn))[1])
#转成二维
G=Gn.reshape((h,w),order='C')
#逆第一次二维置乱即行列置乱,采用与加密时同样的混沌序列
tx=seq_t[0][h+w:2*h+w]
ty=seq_t[0][2*h+w:2*h+2*w]
G=channel_reverse_permutation(tx,ty,G)
#通道B
#逆行列置乱
tz=seq_t[3]
seq=np.arange(w*h)
tz_seq=list(zip(tz,seq))
#根据序列tz得到R通道真是的索引序列
tz_seq.sort(key=lambda x:x[0])
tz=list(list(zip(*tz_seq))[1])
#根据新的索引序列tz对通道B进行排序
tz_Bn=list(zip(tz,new_Bn))
tz_Bn.sort(key=lambda x:x[0])
Bn=np.array(list(zip(*tz_Bn))[1])
#转成二维
B=Bn.reshape((h,w),order='C')
#逆第一次二维置乱即行列置乱,采用与加密时同样的混沌序列
tx=seq_t[0][2*h+2*w:3*h+2*w]
ty=seq_t[0][3*h+2*w:3*h+3*w]
B=channel_reverse_permutation(tx,ty,B)
#三通道重新组成彩色RGB图像
img_decrypt=cv2.merge([R,G,B])
#返回解密图像,返回的是RGB通道顺序
return img_decrypt
def main():
img_path='./Lena.png'
#设定参数
a=35
b=3
c=28
#迭代次数
T=100000
#复杂Chen混沌系统初值
z1=3.7+3.8j
z2=10.2+6.9j
z3=9.1
#复杂Lorenz系统初值
w1=5.4+7.2j
w2=7.6+3.2j
w3=4.8
#初始密钥
key=[z1,z2,z3,w1,w2,w3]
#生成密钥
new_key=Generate_Key(img_path,key)
#原始图像
img=cv2.imread(img_path)[:,:,(2,1,0)]
#加密图像
img_encrypt=encrypt(img_path,new_key)
cv2.imwrite('./Lena_encrypt.png',img_encrypt[:,:,(2,1,0)])
encrypt_path='./Lena_encrypt.png'
#正确密钥解密图像
img_decrypt=decrypt(encrypt_path,new_key)
decrypt_path='./Lena_decrypt.png'
cv2.imwrite(decrypt_path,img_decrypt[:,:,(2,1,0)])
#错误密钥解密图像
wrong_key=list(new_key)
wrong_key[2]+=pow(10,-10)
wrong_decrypt=decrypt(encrypt_path,wrong_key)
cv2.imwrite('./wrong_decrypt.png',wrong_decrypt[:,:,(2,1,0)])
#分别计算原始图像与解密图像的汉明距离,保证解密后信息的完整性
HRG1,HRB1,HGB1=Hamming(img_path)
HRG2,HRB2,HGB2=Hamming(decrypt_path)
print('原始图像各通道的汉明距离为:',HRG1,HRB1,HGB1)
print('解密图像各通道的汉明距离为:',HRG2,HRB2,HGB2)
#结果展示
plt.rcParams['font.sans-serif'] = ['SimHei'] # 中文乱码
#子图1,原始图像
plt.subplot(221)
#imshow()对图像进行处理,画出图像,show()进行图像显示
plt.imshow(img)
plt.title('原始图像')
#不显示坐标轴
plt.axis('off')
#子图2,加密后图像
plt.subplot(222)
plt.imshow(img_encrypt)
plt.title('加密图像\nz3={}'.format(new_key[2]))
plt.axis('off')
#子图3,错误密钥解密结果
plt.subplot(223)
plt.imshow(wrong_decrypt)
plt.title('解密图像\nz3={}'.format(wrong_key[2]))
plt.axis('off')
#子图4,正确密钥解密结果
plt.subplot(224)
plt.imshow(img_decrypt)
plt.title('解密图像\nz3={}'.format(new_key[2]))
plt.axis('off')
# #设置子图默认的间距
plt.tight_layout()
#显示图像
plt.show()
if __name__=='__main__':
main()
性能评估
注:代码参见【图像加密常见性能评估指标】
密钥空间和敏感度分析
本文提出的利用两个复杂混沌系统的加密算法可以提高算法的复杂度,并使密钥变大。在两个复杂的混沌系统中,有10个参数,它们的值可以任意设置。假设取值范围为 1 0 − 4 ∼ 1 0 4 10^{-4} \thicksim 10^4 10−4∼104,精度为 1 0 15 10^{15} 1015,最终的密钥空间是 ( 2 ∗ 1 0 4 ∗ 1 0 15 ) 10 ≈ 1 0 194 (2*10^4*10^{15})^{10}\thickapprox10^{194} (2∗104∗1015)10≈10194。因此,我们的加密算法的密钥空间足够大,可以抵御暴力攻击。
为了分析灵敏度,对Lena图像用两个很相近只相差 1 0 10 10^{10} 1010的初始值进行加密,采用像素改变率 NPCR 和像素平均改变强度 UACI 量化两张密文图像的差别。NPCR 和 UACI 越接近理想值,加密算法对安全密钥 的敏感度越强,加密算法越安全。
NPCR | UACI | |
---|---|---|
R | 99.6281% | 33.5412% |
G | 99.6059% | 33.5768% |
B | 99.5892% | 33.5300% |
直方图分析
原始图像直方图如下:
加密图像直方图如下
相关性分析
原始图像的相关系数
通道 | Horizontal | Vertical | Diagonal |
---|---|---|---|
R | 0.981086 | 0.988981 | 0.970668 |
G | 0.966661 | 0.981110 | 0.950107 |
B | 0.933897 | 0.958900 | 0.918832 |
加密图像的相关系数
通道 | Horizontal | Vertical | Diagonal |
---|---|---|---|
R | 0.025596 | 0.027092 | -0.030060 |
G | -0.002710 | -0.024414 | 0.015201 |
B | -0.011373 | 0.009783 | -0.001298 |
原始图像相关性图
加密图像相关性图
运行时间分析
为了评估运行速度效率,测试在Python3.8.3和Windows 10 Professional操作系统中实现,其硬件是Intel® Core™ i7-2600 CPU @ 3.40GHz 3.40 GHz, 8G RAM和1TB硬盘。
采用大小为512*512的lena.tiff、baboon.tiff、couple.tiff、vegatables.tiff四张图像各自加密解密5次,平均运行时间如下表。
图像 | 加密时间(s) | 解密时间(s) |
---|---|---|
lena | 5.899555 | 7.489705 |
baboon | 5.856375 | 7.25655 |
couple | 1.156215 | 1.453077 |
vegatables | 5.833449 | 7.55911 |