0%

A novel hybrid color image encryption algorithm using two complex chaotic systems

论文地址

一种基于两个复杂混沌系统的混合彩色图像加密算法
摘要

本文在复杂Chen和复杂Lorenz系统的基础上,提出了一种新的彩色图像加密算法。与真实混沌系统相比,复杂混沌系统具有更大的混沌范围和更复杂的行为,可以进一步提高彩色图像加密的安全性,扩大密钥空间。加密算法由三个步骤组成。在置乱过程中,对明文图像的像素分别进行二维和一维的RGB通道排列。在扩散过程中,采用异或(XOR)操作来隐藏像素信息。最后,利用混合RGB信道实现多级加密。

引言

在计算机和网络技术飞速发展的今天,数据传输和存储的安全性越来越受到人们的关注。混沌系统的一些基本性质,如对初始条件的敏感性和伪随机性质,满足了一个好的密码系统的要求。从这个意义上说,图像混沌加密作为图像加密的一个新领域得到了迅速的发展,自1989年Matthews提出第一个混沌密码学以来,许多研究者都提出了基于混沌的密码学方案,基于混沌的加密在其他领域也有良好的性能,如视频加密。

但目前研究的密钥空间还有待完善。在大多数理论中,使用一维混沌映射生成伪随机数,而伪随机数的密钥空间小,可能会削弱对潜在攻击的抵抗能力。此外,由于在混沌系统的迭代上花费过多的时间,可能会降低加密速度。

面对这些问题,一些研究者在过去几年里做出了一些贡献,可以概括为四个方向。引入多维或复杂的混沌映射;结合多个混沌映射;设计更复杂的排列-扩散算法;或者增加一些传统的加密方法。

本文提出的基于复杂Chen系统和复杂Lorenz系统的方案可以扩大密钥空间,以应对潜在的攻击。另外,我们对像素混淆部分进行了二维处理,最后增加了一步处理,其主要思想是利用复杂混沌系统产生的伪随机数序列混合RGB通道。该算法的突出特点是具有多级扩散和更大的密钥空间,这些组合过程可以从各个方面保证系统的安全性,抵御攻击,避免上述问题的存在。

伪随机序列生成

伪随机性是混沌系统的基本性质,适用于对信息进行加密覆盖。一维混沌系统(如logistic map)因其简单、高效而被广泛应用于伪随机数序列的生成。然而,他们的缺点,如小的密钥空间,是如此明显以致于许多提出的混沌密码系统已被一些密码分析方法破解。复杂混沌系统中复变量的实部和虚部使实变量的数量增加了一倍,增加了复杂性和随机性。因此,本文采用了复杂的Chen系统和复杂的Lorenz系统来克服系统的不足,提高系统的安全性。

复杂Chen系统

复杂Chen系统公式定义如下:

其中,$a_1,b_1$和 $c_1$是系统的控制参数,都是正实数。$z_1=z_1^r+jz_1^i$和 $z_2=z_2^r+jz_2^i$是复变量,$z_3$是实变量。根据论文所说,当 $a_1=27,b_1=4.5$且 $c_1=23$时,复杂Chen系统有更复杂和更混沌的表现,但是混沌系统对初始值不敏感,且吸引子图像与论文所述也不一样,反而当 $a_1=35,b_1=3$且 $c_1=28$时(正是Chen混沌控制参数),吸引子图像与论文相符,且对初值敏感,所以此处存疑???此时吸引子图像如下:

complex_chen

复杂Lorenz系统

复杂Lorenz系统公式定义如下:

其中, $a_2,b_2$和 $c_3$是正实数, $w_1=w_1^r+jw_1^i$和 $w_2=w_2^r+jw_2^i$是复数变量,$w_3$是实数。同样,论文中描述当 $a_2=14,b_2=3.7$且 $c_2=35$时,复杂Lorenz系统有很好的的混沌表现,但是实验时发现这样的控制参数没有形成混沌,反而当 $a_2=10,b_2=28$且 $c_2=8/3$时(正是Lorenz混沌控制参数),吸引子图像与论文相符,所以此处也是没想明白???此时吸引子图像如下:

complex_Lorenz

密钥生成

汉明距离是一种表示两个等长序列对应位置的不同元素个数的方法,序列 $\alpha=(\alpha_1,\alpha-2,…,\alpha_n)$和 $\beta=(\beta_1,\beta_2,…,\beta_n)$的汉明距离 $H(\alpha,\beta)$定义如下:

基于上式,可以得到R、G、B三个通道的汉明距离 $H_{RG},H_{RB},H_{GB}$,因此生成密钥如下:

其中,$Key_{Chen}$和$Key_{Lorenz}$是两个大小为6的序列,并且6个元素是由消息发送者选择的。 Key2是两个复杂混沌系统的初始值。

在生成密钥时,对于不同的明文图像,在每个加密过程中汉明距离的值是不同的,消息接收方可以重新计算汉明距离,以保证解密后信息的完整性。因此,以上这些都达到了更高的安全级别。

伪随机序列

采用上文提及的复杂混沌系统生成的混沌序列是浮点数值,不适合直接应用于图像加密方案。有必要将一个通道中的像素值修改为从0到255的整数,整数伪随机数序列转换公式如下:

其中,$s_i$是 来自两个混沌系统的混沌序列;mod返回除法之后的余数(即取模运算)。

加密方案

明文图像加密的主要思想是对像素的位置进行排列,并通过不同的方法对像素值进行隐藏。本文的算法如下:

  • 首先,利用两个复杂的混沌系统生成随机序列对明文图像进行加密,改善了密钥空间,提高了对潜在攻击的安全性。
  • 其次,与传统的加密方案相比,我们的加密方案采用了图像的二维特征。
  • 第三,我们增加了一步混合RGB通道和混沌序列的过程,在前面的步骤的基础上实现了全方位多级加密。

本文采用512*512的“Lena”图像进行试验,加密步骤如图:

img

像素置乱

在我们的加密算法中,这部分的目的是混淆像素在每个通道中的位置。为了描述简单,以R通道为例来说明加密过程,其他两个通道类似,只是使用了两个复杂混沌系统中不同的伪随机数序列。

假设明文图像为$P_{MN}$,其R通道的数据是一个M\N的二维数组,两个伪随机序列是 $t_x$和 $t_y$,大小分别为M和N。$pos_x$和 $pos_y$两个序列用来标定 $t_x,t_y$ 和 $P_{MN}$中元素的位置;然后我们根据元素大小分别对 $t_x$和 $t_y$进行排序,得到新序列 $pos_x$,$pos_y$。最后,$P_{MN}$根据新的 $t_x、t_y$重新排列。

排序过程图如下:

img

然后,$P_{M*N}$扁平化为一维数组 $P_n$,对于一个伪随机序列 $t_z$,它的大小为n的元素位置标定

序列为 $pos_z$,使用相同的方法来排列 $P_n$。

异或操作

异或操作是加密和解密信息的一种简单而有用的方法。在此步骤过程中,通过对像素值与伪随机数序列进行异或运算来隐藏像素信息。

用三个整数伪随机序列 $t_R,t_G,t_B$在每个通道上执行异或操作。

混沌马尾??

最后的加密步骤是用混沌序列混合RGB通道,这个加密步骤过程被生动地称为“混乱马尾”,因为它的过程就像马尾一样。RGB通道之间的界限可以用这种方法打破。因此,从一个通道到另一个通道解密图像是完全不可能的。该部分的加密步骤过程如下所示:

  • 为了实现马尾在每一部分的长度是变化的,设计了一个函数用于创建随机元素长度的序列,$M_{mix}$:

​ $u_i$是复杂混沌系统生成的一个序列,这里i设置为5。zoom是最大步长限制。

  • 编马尾的步骤如下:

    步骤1:用Mmix中第一个元素的长度交换R和G通道中的数据

    步骤2:用Mmix中下一个元素的长度交换R和B通道中的数据;

    步骤3:用Mmix中下一个元素的长度交换G和B通道中的数据;

    步骤4:重复步骤从1到3,直到所有的像素被交换。

”混沌马尾辫“的基本加密原理和处理步骤如图所示

img

实验结果

Complex_chaos

实验代码
加解密python代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
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个参数,它们的值可以任意设置。假设取值范围为$10^{-4} \thicksim 10^4$,精度为$10^{15}$,最终的密钥空间是 $(210^410^{15})^{10}\thickapprox10^{194}$。因此,我们的加密算法的密钥空间足够大,可以抵御暴力攻击。

为了分析灵敏度,对Lena图像用两个很相近只相差$10^{10}$的初始值进行加密,采用像素改变率 NPCR 和像素平均改变强度 UACI 量化两张密文图像的差别。NPCR 和 UACI 越接近理想值,加密算法对安全密钥 的敏感度越强,加密算法越安全。

NPCR UACI
R 99.6281% 33.5412%
G 99.6059% 33.5768%
B 99.5892% 33.5300%
直方图分析

原始图像直方图如下:

hist_lena

加密图像直方图如下

hist_encryption

相关性分析

原始图像的相关系数

通道 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

原始图像相关性图

correlation_lena

加密图像相关性图

correlation_encryption

运行时间分析

为了评估运行速度效率,测试在Python3.8.3和Windows 10 Professional操作系统中实现,其硬件是Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz 3.40 GHz, 8G RAM和1TB硬盘。

采用大小为512*512的lena.tiffbaboon.tiffcouple.tiffvegatables.tiff四张图像各自加密解密5次,平均运行时间如下表。

图像 加密时间(s) 解密时间(s)
lena 5.899555 7.489705
baboon 5.856375 7.25655
couple 1.156215 1.453077
vegatables 5.833449 7.55911
问题
复杂混沌系统???

复杂混沌系统不够明确,还没读太懂。。。

混沌系统可以产生10个混沌序列,在使用时可以多种选择。。。

密钥生成???

密钥生成那部分语句读着感觉有歧义???密钥到底有几个值啊?混沌系统初值复数整个算一个密钥,还是实部和虚部各算一个啊?

密钥是由复杂混沌系统的6个初值组成的,其中4个是复数。。。

混沌序列选择???

混沌序列到底产生了几个啊?两个复杂混沌系统应该都是五维的?应该有10个混沌序列?怎么选择混沌序列使用的并没有详细介绍?

多种选择方式。。。

解密时G、B通道像素错误??

没错啊???

参考

【图像加密常见性能评估指标】

------------- THE END! THANKS! -------------