天天看點

常見圖像加密性能評價名額(詳解加python實作)參考

前言

本文目的

介紹一些常見的用于圖像加密的評價名額并予以代碼實作,友善以後做實驗時參考查閱。

圖像加密領域所有常見的安全分析技術彙總如下圖。

常見圖像加密性能評價名額(詳解加python實作)參考

實驗示例圖檔下載下傳

Lena.png,Lena_encrypt1.png,Lena_encrypt2.png

常見圖像加密性能評價名額(詳解加python實作)參考

注:Lena.png為原圖像,Lena_encrypt1.png、Lena_encrypt2.png為使用不同密鑰加密的圖像。

加密過程參見【使用基于混沌理論和SHA-2的異或與DNA互補規則的彩色圖像加密技術】

靈敏度分析

密鑰空間分析

密鑰空間指能夠用于生成密鑰的所有可能密鑰的集合,密鑰空間的大小取決于安全密鑰的長度,它是決定密碼系統強度的最重要特性之一。對于長度為 L 的二進制安全密鑰,其密鑰空間大小為2 𝐿,即攻擊者想要通過暴力攻擊的手 段攻擊加密系統,理論上需要計算2𝐿次才能保證一定能攻擊成功。以現階段計 算機的計算能力來看,當安全密鑰長度 L = 128, 即密鑰空間大小為 2 128 2^{128} 2128時,使用現代高性能計算機檢查所有可能的密鑰需要大約 1021 年,是以,加密算法能抵禦任何形式的暴力攻擊。

密鑰敏感性分析

概念

理想的多媒體加密應該對密鑰敏感,即密鑰中一個比特的變化應該産生一個完全不同的加密結果,稱為密鑰敏感性。一般來說,混沌密碼的密鑰靈敏度是指混沌映射的初始狀态的靈敏度和控制參數的靈敏度。靈敏度的評估使用兩個參數:像素數變化率(NPCR)和統一平均變化強度(UACI)。NPCR和UACI分别表示兩張加密圖像之間的變化像素數和兩張加密圖像之間的平均變化強度數。它們相應的理想值分别為 NPCR=99.6094%,UACI=33.4635%,計算公式如下:

N P C R = Σ i , j D ( i , j ) M ∗ N ∗ 100 % NPCR=\frac{\Sigma_{i,j}D(i,j)}{M*N}*100\% NPCR=M∗NΣi,j​D(i,j)​∗100%

式中,M和N分别為兩幅随機圖像的寬度和高度,定義D (i, j)如下:

D ( i , j ) = f ( x ) = { 1 ,   C 1 ( i , j ) ≠ C 2 ( i , j ) 0 ,   o t h e r w i s e \begin{array}{lr} D(i,j)=f(x)=\left\{ \begin{array}{lr} 1,\ C_1(i,j)\neq C_2(i,j) \\ 0,\ otherwise \\ \end{array} \right . \end{array} D(i,j)=f(x)={1, C1​(i,j)​=C2​(i,j)0, otherwise​​

相應地,UACI可以用來測量顔色分量對比度強度的平均值,計算公式如下:

U A C I = 1 M ∗ N Σ ( C 1 ( i , j ) − C 2 ( i , j ) ) 255 ∗ 100 % UACI=\frac{1}{M*N}\frac{\Sigma(C_1(i,j)-C_2(i,j))}{255}*100\% UACI=M∗N1​255Σ(C1​(i,j)−C2​(i,j))​∗100%

密鑰敏感度測試可以通過修改密鑰 K 中的某一位得到 K’,利用 K 和 K’ 加密同一張圖像得到 C 1 C_1 C1​和 C 2 C_2 C2​,采用像素改變率 NPCR 和像素平均改變強度 UACI 量化兩張密文圖像的差别。NPCR 和 UACI 越接近理想值,加密算法對安全密鑰 的敏感度越強,加密算法越安全。

實驗結果

PSNR UACI
R 99.5686% 33.4380%
G 99.6098% 33.4592%
B 99.6178% 33.4337%

實驗代碼

import cv2
import numpy as np
import matplotlib.pyplot as plt


'''
計算像素數變化率
'''
def NPCR(img1,img2):
  #opencv顔色通道順序為BGR
  img1=cv2.imread(img1)
  img2=cv2.imread(img2)
  w,h,_=img1.shape

  #圖像通道拆分
  B1,G1,R1=cv2.split(img1)
  B2,G2,R2=cv2.split(img2)
  #傳回數組的排序後的唯一進制素和每個元素重複的次數
  ar,num=np.unique((R1!=R2),return_counts=True)
  R_npcr=(num[0] if ar[0]==True else num[1])/(w*h)
  ar,num=np.unique((G1!=G2),return_counts=True)
  G_npcr=(num[0] if ar[0]==True else num[1])/(w*h)
  ar,num=np.unique((B1!=B2),return_counts=True)
  B_npcr=(num[0] if ar[0]==True else num[1])/(w*h)

  return R_npcr,G_npcr,B_npcr

'''
兩張圖像之間的平均變化強度
'''

def UACI(img1,img2):
  img1=cv2.imread(img1)
  img2=cv2.imread(img2)
  w,h,_=img1.shape
  #圖像通道拆分
  B1,G1,R1=cv2.split(img1)
  B2,G2,R2=cv2.split(img2)
  #元素為uint8類型取值範圍:0到255
  # print(R1.dtype)

  #強制轉換元素類型,為了運算
  R1=R1.astype(np.int16)
  R2=R2.astype(np.int16)
  G1=G1.astype(np.int16)
  G2=G2.astype(np.int16)
  B1=B1.astype(np.int16)
  B2=B2.astype(np.int16)

  sumR=np.sum(abs(R1-R2))
  sumG=np.sum(abs(G1-G2))
  sumB=np.sum(abs(B1-B2))
  R_uaci=sumR/255/(w*h)
  G_uaci=sumG/255/(w*h)
  B_uaci=sumB/255/(w*h)

  return R_uaci,G_uaci,B_uaci


def main():
  #img='./lena.png'
  img1='./lena_encrypt1.png'
  img2='./lena_encrypt2.png'

  R_npcr,G_npcr,B_npcr=NPCR(img1,img2)
  print('*********PSNR*********')
  #百分數表示,保留小數點後4位
  print('Red  :{:.4%}'.format(R_npcr))
  print('Green:{:.4%}'.format(G_npcr))
  print('Blue :{:.4%}'.format(B_npcr))


  R_uaci,G_uaci,B_uaci=UACI(img1,img2)
  print('*********UACI*********')
  #百分數表示,保留小數點後4位
  print('Red  :{:.4%}'.format(R_uaci))
  print('Green:{:.4%}'.format(G_uaci))
  print('Blue :{:.4%}'.format(B_uaci))


if __name__== '__main__':
  main()
           

差分攻擊

破解密文圖像的一種方法是差分攻擊:它指的是攻擊者對原始明文數字圖像資料進行細微的改變,利用提出的加密算法對改變後的數字圖像和原始明文數字圖像分别進行加密,并通過比較兩幅加密後的密文圖像,找出原始明文數字圖像資料與加密後密文數字圖像資料之間的關系,利用這種關系和規律來進行對密文圖像進行破解。通俗點說,它是指攻擊者對大小為M × N的圖像P做少量改動得到 P’,分别利用相同的安全密鑰加密P和P’得到 C1 和C2 ,比較 C1和 C2的差別以找到攻擊圖像加密方案的線索。當 C1和 C2表現出較大差異時,攻擊者就難以實施差分攻擊。差分攻擊是一種選擇明文攻擊,抗差分攻擊性能依賴于對明文的敏感性,在圖像加密領域,衡量兩張圖像的差異有兩個非常重要的變量:像素改變率 (NPCR)和統一平均變化強度(UACI)。像素改變率NPCR反映了兩張圖像相同位置不相等的像素的個數占圖像所有像素個數的比例;UACI 是整體平均變化密度,表示平面圖像的平均變化的強度,主要展現普通明文數字圖像資料和加密後的密文數字圖像資料之間的差異的平均變化的強弱程度。為了抵抗差分攻擊,在明文圖像發生一個像素變化時,要使密文圖像有大幅度的變化,則抵抗差分攻擊的能力越強。 NPCR和UACI的理想值分别為99.6094%和33.4635%,當某算法的NPCR和UACI計算結果越接近于理想值時,則說明該算法抵抗差分攻擊的能力越強。

統計分析

直方圖分析

概念

直方圖顯示圖像的統計資訊,直覺地反映了圖像中各個灰階值的分布情況。明文圖像的直方圖表現出明顯的統計規律,針對統計規律的攻擊方案被稱為統計分析攻擊。統計分析攻擊是指攻擊者通過分析密文和明文的統計規律來破譯密碼。攻擊者對截獲 的密文圖像進行統計分析,總結出其間的統計規律,并與明文的統計規律進行 比較,從中提取明文圖像和密文圖像之間的變換關系, 以達到攻擊加密方案的目的。為了抵抗統計攻擊,加密圖像的直方圖必須是均勻的,并且完全不同于明文圖像的直方圖。直方圖的方差能有效量化加密算法抵禦統計分析攻擊能力。方差越小,說明像素 分布越均勻,圖像顯示的統計資訊就越少,圖像加密方案就越安全。

實驗結果

原圖像Lena.png的灰階直方圖如下:

常見圖像加密性能評價名額(詳解加python實作)參考

加密圖像Lena_encrypt1.png的灰階直方圖如下:

常見圖像加密性能評價名額(詳解加python實作)參考

實驗代碼

import cv2
import numpy as np
import matplotlib.pyplot as plt

'''
繪制灰階直方圖
'''
def hist(img):
  img=cv2.imread(img)
  B,G,R=cv2.split(img)
  #轉成一維
  R=R.flatten(order='C')
  G=G.flatten(order='C')
  B=B.flatten(order='C')


  #結果展示
  plt.rcParams['font.sans-serif'] = ['SimHei']  # 中文亂碼
  plt.subplot(232)
  # plt.imshow(img[:,:,(2,1,0)])
  plt.hist(img.flatten(order='C'),bins=range(256),color='gray')
  plt.title('原圖像')
  #子圖2,通道R
  plt.subplot(234)
  #imshow()對圖像進行處理,畫出圖像,show()進行圖像顯示
  plt.hist(R,bins=range(256),color='red')
  plt.title('通道R')
  # plt.show()
  #不顯示坐标軸
  # plt.axis('off')

  #子圖3,通道G
  plt.subplot(235)
  plt.hist(G,bins=range(256),color='green')
  plt.title('通道G')
  # plt.show()
  # plt.axis('off')

  #子圖4,通道B
  plt.subplot(236)
  plt.hist(B,bins=range(256),color='blue')
  plt.title('通道B')
  # plt.axis('off')
  # #設定子圖預設的間距
  plt.tight_layout()
  plt.show()


def main():
  img='./lena.png'
  #圖像lean的灰階直方圖
  hist(img)

if __name__== '__main__':
  main()
           

相鄰像素相關性分析

概念

相關性分析是指對兩個或多個具備相關性的變量元素進行分析,進而衡量變量之間的相關密切程度。由于圖像相鄰像素之間存在着很高的相關性,一個像素往往會洩露其周邊像素的資訊,攻擊者往往可以利用該特性推理預測出下一個像素的灰階值,,進而實作對整個明文圖像的恢複。數字圖像中的相鄰像素具有相似的強度;是以具有很強的相關性,這些強相關性必須被打破,以避免統計攻擊。相關系數在水準、垂直和對角線方向的計算公式如下:

R x y = c o v ( x , y ) D ( x ) D ( y ) R_{xy}=\frac{cov(x,y)}{\sqrt{D(x)}\sqrt{D(y)}} Rxy​=D(x)

​D(y)

​cov(x,y)​

E ( x ) = 1 N ∑ i = 1 N x i E(x)=\frac{1}{N}\sum_{i=1}^{N}{x_i} E(x)=N1​i=1∑N​xi​

D ( x ) = 1 N ∑ i = 1 N ( x i − E ( x ) ) 2 D(x)=\frac{1}{N}\sum_{i=1}^{N}{(x_i-E(x))^2} D(x)=N1​i=1∑N​(xi​−E(x))2

c o v ( x , y ) = 1 N ∑ i = 1 N ( x i − E ( x ) ) ( y i − E ( y ) ) cov(x,y)=\frac{1}{N}\sum_{i=1}^{N}{(x_i-E(x))(y_i-E(y))} cov(x,y)=N1​i=1∑N​(xi​−E(x))(yi​−E(y))

上述式子中,y為x的相鄰像素,N為M × N幅圖像中像素的總數, R x y R_{xy} Rxy​即為兩相鄰像素的相關性,cov(x, y)是x和y兩個像素點處的協方差, D ( x ) \sqrt{D(x)} D(x)

​是标準差,D(x)是方差,E(x)是均值。通常,明文圖像相鄰像素的相關性接近 1,而密文圖像相鄰像素的相關性應該接近于 0。

實驗結果

通過分别随機選取3000對相鄰像素,根據相關系數的上述定義在水準、垂直和對角方向分别計算原圖像和加密圖像内的相關系數,實驗結果如下:

原Lena圖像的相關系數

通道 Horizontal Vertical Diagonal
R 0.9782 0.9893 0.9664
G 0.9699 0.9805 0.9548
B 0.9359 0.9572 0.9239

加密圖像1的相關系數

通道 Horizontal Vertical Diagonal
R -0.0110 -0.0091 0.0223
G -0.0260 -0.0175 -0.0228
B -0.0147 -0.0078 -0.0114

原始圖像像素相關性圖

常見圖像加密性能評價名額(詳解加python實作)參考

加密圖像1像素相關性圖

常見圖像加密性能評價名額(詳解加python實作)參考

實驗代碼

import cv2
import numpy as np
import matplotlib.pyplot as plt


'''
分别計算圖像通道相鄰像素的水準、垂直和對角線的相關系數并傳回
'''
def RGB_correlation(channel,N):
  #計算channel通道
  h,w=channel.shape
  #随機産生pixels個[0,w-1)範圍内的整數序列
  row=np.random.randint(0,h-1,N)
  col=np.random.randint(0,w-1,N)
  #繪制相鄰像素相關性圖,統計x,y坐标
  x=[]
  h_y=[]
  v_y=[]
  d_y=[]
  for i in range(N):
    #選擇目前一個像素
    x.append(channel[row[i]][col[i]])
    #水準相鄰像素是它的右側也就是同行下一列的像素
    h_y.append(channel[row[i]][col[i]+1])
    #垂直相鄰像素是它的下方也就是同列下一行的像素
    v_y.append(channel[row[i]+1][col[i]])
    #對角線相鄰像素是它的右下即下一行下一列的那個像素
    d_y.append(channel[row[i]+1][col[i]+1])
  #三個方向的合到一起
  x=x*3
  y=h_y+v_y+d_y

  #結果展示
  # plt.rcParams['font.sans-serif'] = ['SimHei']  # 中文亂碼
  # plt.scatter(x,y)
  # plt.show()

  #計算E(x),計算三個方向相關性時,x沒有重新選擇也可以更改
  ex=0
  for i in range(N):
    ex+=channel[row[i]][col[i]]
  ex=ex/N
  #計算D(x)
  dx=0
  for i in range(N):
    dx+=(channel[row[i]][col[i]]-ex)**2
  dx/=N

  #水準相鄰像素h_y
  #計算E(y)
  h_ey=0
  for i in range(N):
    h_ey+=channel[row[i]][col[i]+1]
  h_ey/=N
  #計算D(y)
  h_dy=0
  for i in range(N):
    h_dy+=(channel[row[i]][col[i]+1]-h_ey)**2
  h_dy/=N
  #計算協方差
  h_cov=0
  for i in range(N):
    h_cov+=(channel[row[i]][col[i]]-ex)*(channel[row[i]][col[i]+1]-h_ey)
  h_cov/=N
  h_Rxy=h_cov/(np.sqrt(dx)*np.sqrt(h_dy))

  #垂直相鄰像素v_y
  #計算E(y)
  v_ey=0
  for i in range(N):
    v_ey+=channel[row[i]+1][col[i]]
  v_ey/=N
  #計算D(y)
  v_dy=0
  for i in range(N):
    v_dy+=(channel[row[i]+1][col[i]]-v_ey)**2
  v_dy/=N
  #計算協方差
  v_cov=0
  for i in range(N):
    v_cov+=(channel[row[i]][col[i]]-ex)*(channel[row[i]+1][col[i]]-v_ey)
  v_cov/=N
  v_Rxy=v_cov/(np.sqrt(dx)*np.sqrt(v_dy))

  #對角線相鄰像素d_y
  #計算E(y)
  d_ey=0
  for i in range(N):
    d_ey+=channel[row[i]+1][col[i]+1]
  d_ey/=N
  #計算D(y)
  d_dy=0
  for i in range(N):
    d_dy+=(channel[row[i]+1][col[i]+1]-d_ey)**2
  d_dy/=N
  #計算協方差
  d_cov=0
  for i in range(N):
    d_cov+=(channel[row[i]][col[i]]-ex)*(channel[row[i]+1][col[i]+1]-d_ey)
  d_cov/=N
  d_Rxy=d_cov/(np.sqrt(dx)*np.sqrt(d_dy))

  return h_Rxy,v_Rxy,d_Rxy,x,y

'''
分别計算圖像img的各通道相鄰像素的相關系數,預設随機選取3000對相鄰像素
'''
def correlation(img,N=3000):
  img=cv2.imread(img)
  h,w,_=img.shape
  B,G,R=cv2.split(img)
  R_Rxy=RGB_correlation(R,N)
  G_Rxy=RGB_correlation(G,N)
  B_Rxy=RGB_correlation(B,N)

  #結果展示
  plt.rcParams['font.sans-serif'] = ['SimHei']  # 中文亂碼
  plt.subplot(221)
  plt.imshow(img[:,:,(2,1,0)])
  plt.title('原圖像')
  #子圖2
  plt.subplot(222)
  plt.scatter(R_Rxy[3],R_Rxy[4],s=1,c='red')
  plt.title('通道R')

  #子圖3
  plt.subplot(223)
  plt.scatter(G_Rxy[3],G_Rxy[4],s=1,c='green')
  plt.title('通道G')
  #子圖4
  plt.subplot(224)
  plt.scatter(B_Rxy[3],B_Rxy[4],s=1,c='blue')
  plt.title('通道B')
  plt.show()

  return R_Rxy[0:3],G_Rxy[0:3],B_Rxy[0:3]


def main():
  img='./lena.png'
  img1='./lena_encrypt1.png'
  img2='./lena_encrypt2.png'
  R_Rxy,G_Rxy,B_Rxy=correlation(img)
  #輸出結果保留四位有效數字
  print("******該圖像的各通道各方向的相關系數為*****")
  print('通道\tHorizontal\tVertical\tDiagonal')
  print(' R    \t{:.4f}    {:.4f}    {:.4f}'.format(R_Rxy[0],R_Rxy[1],R_Rxy[2]))
  print(' G    \t{:.4f}    {:.4f}    {:.4f}'.format(G_Rxy[0],G_Rxy[1],G_Rxy[2]))
  print(' B    \t{:.4f}    {:.4f}    {:.4f}'.format(B_Rxy[0],B_Rxy[1],B_Rxy[2]))

if __name__== '__main__':
  main()

           

資訊熵分析

概念

熵常用來描述事物的複雜性,信源的資訊熵是度量資訊随機性的一個重要 參考名額。資訊論之父克勞德·香農給出的資訊熵的三個性質:單調性,發生 機率越高的事件其攜帶的資訊量越低;非負性,資訊熵作為一種廣度量,非負 性是一種合理的必然;累加性,多随機事件同時發生存在的總不确定性的量度是可以表示為各事件不确定性的量度之和。

資訊熵是對信号源随機程度的一種定量度量。也就是說,資訊熵可以用來衡量圖像的随機性,它計算每個顔色通道的每個灰階級的像素的擴散。如果均勻分布更好,那麼它對統計攻擊的抵抗就會更強。對于彩色圖像強度在0-255之間的R、G、B通道,加密消息的理想熵值為8,值越高,分布越均勻。

資訊熵計算公式如下:

H ( x ) = − ∑ i = 1 L P ( x i ) log ⁡ 2 P ( x i ) H(x)=-\sum_{i=1}^{L}{P(x_i)\log_{2}{P(x_i)}} H(x)=−i=1∑L​P(xi​)log2​P(xi​)

其中, x i x_i xi​是灰階值, P ( x i ) P(x_i) P(xi​)是灰階級 x i x_i xi​的機率。

實驗結果

資訊熵計算 原Lena圖像 加密圖像1 加密圖像2
R 6.879 7.999 7.999
G 6.926 7.999 7.999
B 6.968 7.999 7.999

實驗代碼

import cv2
import math
import numpy as np
import matplotlib.pyplot as plt


'''
計算圖像的資訊熵
'''
def entropy(img):
  img=cv2.imread(img)
  w,h,_=img.shape
  B,G,R=cv2.split(img)
  gray,num1=np.unique(R,return_counts=True)
  gray,num2=np.unique(G,return_counts=True)
  gray,num3=np.unique(B,return_counts=True)
  R_entropy=0
  G_entropy=0
  B_entropy=0

  for i in range(len(gray)):
    p1=num1[i]/(w*h)
    p2=num2[i]/(w*h)
    p3=num3[i]/(w*h)
    R_entropy-=p1*(math.log(p1,2))
    G_entropy-=p2*(math.log(p2,2))
    B_entropy-=p3*(math.log(p3,2))
  return R_entropy,G_entropy,B_entropy

def main():
  img='./lena.png'
  img1='./lena_encrypt1.png'
  img2='./lena_encrypt2.png'
  #圖像lena的熵
  R_entropy,G_entropy,B_entropy=entropy(img)
  print('***********資訊熵*********')
  print('通道R:{:.4}'.format(R_entropy))
  print('通道G:{:.4}'.format(G_entropy))
  print('通道B:{:.4}'.format(B_entropy))

if __name__== '__main__':
  main()
           

随機性測試

GVD

概念

灰階差度是比較原始圖像和加密圖像的随機性的另一種統計度量,可由下式定義:

KaTeX parse error: No such environment: equation at position 8: \begin{̲e̲q̲u̲a̲t̲i̲o̲n̲}̲ GN(x,y)=\frac…

其中G(x, y)表示位置(x, y)處的灰階值。整幅圖像的平均鄰域灰階差可以用下式子計算:

G V D = A N ′ [ G N ( x , y ) ] − A N [ G N ( x , y ) ] A N ′ [ G N ( x , y ) ] + A N [ G N ( x , y ) ] GVD=\frac{AN'[GN(x,y)]-AN[GN(x,y)]}{AN'[GN(x,y)]+AN[GN(x,y)]} GVD=AN′[GN(x,y)]+AN[GN(x,y)]AN′[GN(x,y)]−AN[GN(x,y)]​

A N [ G N ( x , y ) ] = ∑ x = 2 M − 1 ∑ y = 2 N − 1 G N ( x , y ) ( M − 2 ) ( N − 2 ) AN[GN(x,y)]=\frac{\sum_{x=2}^{M-1}{\sum_{y=2}^{N-1}{GN(x,y)}}}{(M-2)(N-2)} AN[GN(x,y)]=(M−2)(N−2)∑x=2M−1​∑y=2N−1​GN(x,y)​

在上兩個式子中,AN和AN’代表平均鄰域灰階值,但前者表示加密前,後者表示加密後。上述方程的最終結果稱為GVD評分,如果兩幅圖像完全相同,則為0,否則為1。

實驗結果

GVD 原圖-加密圖像1 原圖-加密圖像2
R 0.9864 0.9864
G 0.9753 0.9754
B 0.9768 0.9768

實驗代碼

import cv2
import math
import numpy as np
import matplotlib.pyplot as plt

#計算圖像分量的GVD,參數為加密前後的2個分量二維矩陣
def GVD_components(channel0,channel1):
  AN0=0
  AN1=0
  w,h=channel0.shape
  for i in range(1,w-1):
    for j in range(1,h-1):
      #加密前
      GN0=0
      GN0+=(channel0[i][j]-channel0[i-1][j])**2
      GN0+=(channel0[i][j]-channel0[i+1][j])**2
      GN0+=(channel0[i][j]-channel0[i][j-1])**2
      GN0+=(channel0[i][j]-channel0[i][j+1])**2
      GN0/=4
      #加密後
      GN1=0
      GN1+=(channel1[i][j]-channel1[i-1][j])**2
      GN1+=(channel1[i][j]-channel1[i+1][j])**2
      GN1+=(channel1[i][j]-channel1[i][j-1])**2
      GN1+=(channel1[i][j]-channel1[i][j+1])**2
      GN1/=4
      AN0+=GN0
      AN1+=GN1
  AN0/=((w-2)*(h-2))
  AN1/=((w-2)*(h-2))
  gvd=(AN1-AN0)/(AN1+AN0)
  return gvd

def GVD(img1,img2):
  img1=cv2.imread(img1)
  img2=cv2.imread(img2)
  w,h,_=img1.shape
  B1,G1,R1=cv2.split(img1)
  B2,G2,R2=cv2.split(img2)
  R1=R1.astype(np.int16)
  R2=R2.astype(np.int16)
  G1=G1.astype(np.int16)
  G2=G2.astype(np.int16)
  B1=B1.astype(np.int16)
  B2=B2.astype(np.int16)
  R_gvd=GVD_components(R1,R2)
  G_gvd=GVD_components(G1,G2)
  B_gvd=GVD_components(B1,B2)
  return R_gvd,G_gvd,B_gvd

def main():
  img='./lena.png'
  img1='./lena_encrypt1.png'
  img2='./lena_encrypt2.png'
  #計算GVD
  R_gvd,G_gvd,B_gvd=GVD(img,img1)
  print('***********GVD*********')
  #print(R_gvd,G_gvd,B_gvd)
  print('通道R:{:.4}'.format(R_gvd))
  print('通道G:{:.4}'.format(G_gvd))
  print('通道B:{:.4}'.format(B_gvd))

if __name__== '__main__':
  main()
           

加密品質

概念

圖像加密的品質可由下式決定:

E Q = ∑ L = 0 255 ( H L ( E ) − H L ( I ) ) 2 / 256 EQ=\sum_{L=0}^{255}{(H_L(E)-H_L(I))^2/256} EQ=L=0∑255​(HL​(E)−HL​(I))2/256

其中 E ( i , j ) E(i,j) E(i,j)和 I ( i , j ) I(i,j) I(i,j)分别是M*N像素L灰階級的密文和明文圖像在(i,j)處的像素灰階值。很顯然, I ( i , j ) 、 E ( i , j ) ∈ { 0 , 1 , . . , L − 1 } I(i,j)、E(i,j)\in \{0,1,..,L-1\} I(i,j)、E(i,j)∈{0,1,..,L−1}。将 H L ( I ) H_L(I) HL​(I) 和 H L ( E ) H_L(E) HL​(E)定義為每個灰階級L各自在明文圖像和密碼圖像中的出現次數,EQ表示每個灰階級l的平均變化次數,EQ值越大,加密安全性越好。

實驗結果

注:512*512圖像,EQ值最大應該是1024???待考慮??

EQ 原圖-加密圖像1 原圖-加密圖像2
R 807 804
G 589 590
B 1027 1027

實驗代碼

import cv2
import math
import numpy as np
import matplotlib.pyplot as plt

'''
計算加密品質,img1是原圖,img2是加密圖像
'''
def EQ(img1,img2):
  img1=cv2.imread(img1)
  img2=cv2.imread(img2)
  w,h,_=img1.shape
  B1,G1,R1=cv2.split(img1)
  B2,G2,R2=cv2.split(img2)
  R1_H={}
  R2_H={}
  G1_H={}
  G2_H={}
  B1_H={}
  B2_H={}
  R_EQ=0
  G_EQ=0
  B_EQ=0
  for i in range(256):
    R1_H[i]=0
    R2_H[i]=0
    G1_H[i]=0
    G2_H[i]=0
    B1_H[i]=0
    B2_H[i]=0

  for i in range(w):
    for j in range(h):
      R1_H[R1[i][j]]+=1;
      R2_H[R2[i][j]]+=1;
      G1_H[G1[i][j]]+=1;
      G2_H[G2[i][j]]+=1;
      B1_H[B1[i][j]]+=1;
      B2_H[B2[i][j]]+=1;

  for i in range(256):
    #公式裡是平方,待考慮
    R_EQ+=abs(R1_H[i]-R2_H[i])
    G_EQ+=abs(G1_H[i]-G2_H[i])
    B_EQ+=abs(B1_H[i]-B2_H[i])
  # print(R_EQ)
  R_EQ/=256
  G_EQ/=256
  B_EQ/=256
  return R_EQ,G_EQ,B_EQ


def main():
  img='./lena.png'
  img1='./lena_encrypt1.png'
  img2='./lena_encrypt2.png'
  #計算加密品質
  R_EQ,G_EQ,B_EQ=EQ(img,img1)
  print('***********EQ*********')
  print(R_EQ,G_EQ,B_EQ)
  print('通道R:{:.0f}'.format(R_EQ))
  print('通道G:{:.0f}'.format(G_EQ))
  print('通道B:{:.0f}'.format(B_EQ))

if __name__== '__main__':
  main()
           

魯棒性分析

噪聲攻擊(Noise addition)

概念

在現實世界中,圖像在網際網路上的傳輸不可避免地會受到各種因素的影響,比如噪聲,通信噪聲造成的失真、退化和污染是很常見的,這些因素都會對終端圖像的解密産生一定的影響,從有噪聲的密文 中恢複圖像是比較困難的。是以,圖像加密算法必須具有足夠的魯棒性,以抵抗實際場景中的噪聲攻擊。在仿真實驗中,大多數的研究人員常會對密文圖像添加不同程度的高斯噪聲或椒鹽噪聲進行實驗,再對有噪聲的加密圖像進行解密并對解密結果進行比較。抗噪聲能力是測試加密方案性能的一個重要名額。

實驗結果

對加密圖像1分别添加均值為零,方差為0.0005的高斯噪聲和5%的校驗噪聲,然後進行解密,結果如下

常見圖像加密性能評價名額(詳解加python實作)參考

實驗代碼

import cv2
import math
import random
import numpy as np
import matplotlib.pyplot as plt

def gauss_noise(image, mean=0, var=0.001):
    '''
        添加高斯噪聲
        mean : 均值
        var : 方差
    '''
    image = np.array(image/255, dtype=float)
    noise = np.random.normal(mean, var ** 0.5, image.shape)
    out = image + noise
    if out.min() < 0:
        low_clip = -1.
    else:
        low_clip = 0.
    out = np.clip(out, low_clip, 1.0)
    out = np.uint8(out*255)
    return out

#預設10%的椒鹽噪聲
def salt_and_pepper_noise(noise_img, proportion=0.1):
    height, width, _ = noise_img.shape
    num = int(height * width * proportion)  # 多少個像素點添加椒鹽噪聲
    for i in range(num):
        w = random.randint(0, width - 1)
        h = random.randint(0, height - 1)
        if random.randint(0, 1) == 0:
            noise_img[h, w] = 0
        else:
            noise_img[h, w] = 255
    return noise_img

def main():
  img='./lena.png'
  img1='./lena_encrypt1.png'
  img2='./lena_encrypt2.png'
  im=cv2.imread(img1)
  gauss_img=gauss_noise(im,mean=0,var=0.0005)
  salt_img=salt_and_pepper_noise(im,proportion=0.05)
  cv2.imwrite('./gauss_img.png',gauss_img)
  cv2.imwrite('./salt_img.png',salt_img)


if __name__== '__main__':
  main()

           

阻塞攻擊

概念

在網際網路上的通信過程中,圖像的一部分可能丢失,提出的算法必須能夠以适當的方式處理有損圖像的解碼。為了顯示所提出的密碼在這種情況下的強度,分别從一個圖形中去掉紅色通道的一塊像素、綠色通道的一塊像素以及所有通道的一塊像素,然後對它們進行解密;如果解密後原始資訊被保留,并且原始圖像的内容可以可視化,所提出的密碼将能夠處理有損圖像的解密。

實驗結果

從加密圖像1中移除(換成0)一塊80×80像素的紅色通道,一塊50×80像素的綠色通道和一塊60×50像素的全通道,然後進行解密,結果如圖。

常見圖像加密性能評價名額(詳解加python實作)參考

實驗代碼

import cv2
import math
import numpy as np
import matplotlib.pyplot as plt

'''
對加密圖像進行處理,傳回處理後的結果
'''
def occlusion(img):
  img=cv2.imread(img)
  h,w,_=img.shape
  B,G,R=cv2.split(img)
  #随機移除R通道80*80大小的像素
  #産生随機整數,裁剪大小為80
  pos_w=np.random.randint(0,w-80)
  pos_h=np.random.randint(0,h-80)
  for i in range(80):
    for j in range(80):
      R[pos_h+i][pos_w+j]=0
  #随機移除G通道50*80的像素
  pos_w=np.random.randint(0,w-50)
  pos_h=np.random.randint(0,h-80)
  for i in range(80):
    for j in range(50):
      G[pos_h+i][pos_w+j]=0
  #三通道合并
  im=cv2.merge([R,G,B])
  #随機移除All通道60*50的像素
  pos_w=np.random.randint(0,w-60)
  pos_h=np.random.randint(0,h-50)
  for i in range(50):
    for j in range(60):
      im[pos_h+i][pos_w+j]=np.array([0,0,0])

  return im


def main():
  img='./lena.png'
  img1='./lena_encrypt1.png'
  img2='./lena_encrypt2.png'
  lossy_encrypt=occlusion(img1)
  # plt.imshow(lossy_encrypt)
  # plt.show()
  #儲存處理後的有損加密圖像,opencv的顔色通道順序為[B,G,R]
  cv2.imwrite('./Lossy_Lena_encrypt1.png',lossy_encrypt[:,:,(2,1,0)])
 
if __name__== '__main__':
  main()
           

裁剪攻擊

當在網際網路上通信時,圖像的一部分可能會被裁剪甚至丢失,是以提出的密碼必須能夠以适當的方式處理有損圖像的加密。在仿真實驗中,将密文圖像的一部分區域(例如,該區域占總區域的1%、5%和10%)像素設定為0,然後用正确的密鑰對其解密。在圖像進行中,可以通過分析密文圖像和明文圖像之間的峰值信噪比(PSNR)來判斷重構圖像的品質,裁剪處理參見上面阻塞攻擊,PSNR計算參見下面。

峰值信噪比(PSNR)

概念

峰值信噪比主要考察對應像素點之間的誤差。給定大小為M*N的加密圖像X和原圖像Y,均方誤差(MSE)定義為:

M S E = 1 M ∗ N ∑ i = 1 M ∑ j = 1 N ( X ( i , j ) − Y ( i , j ) ) 2 MSE=\frac{1}{M*N}\sum_{i=1}^{M}\sum_{j=1}^{N}{(X(i,j)-Y(i,j))^2} MSE=M∗N1​i=1∑M​j=1∑N​(X(i,j)−Y(i,j))2

PSNR計算公式如下:

P S N R = 10 log ⁡ 10 ( 2 n − 1 ) 2 M S E PSNR=10\log_{10}{\frac{(2^n-1)^2}{MSE}} PSNR=10log10​MSE(2n−1)2​

其中,M、N分别表示圖像的寬高,n為像素位數;PSNR值越大,表示失真越小,兩張圖檔差距越小,加密效果越差。

實驗結果

PSNR 原圖-加密圖像1 原圖-加密圖像2
R 7.895 7.890
G 8.562 8.548
B 9.603 9.612

實驗代碼

import cv2
import math
import numpy as np
import matplotlib.pyplot as plt

def PSNR(img1,img2):
  img1=cv2.imread(img1)
  img2=cv2.imread(img2)
  w,h,_=img1.shape
  B1,G1,R1=cv2.split(img1)
  B2,G2,R2=cv2.split(img2)

  #強制轉換元素類型,為了運算
  R1=R1.astype(np.int32)
  R2=R2.astype(np.int32)
  G1=G1.astype(np.int32)
  G2=G2.astype(np.int32)
  B1=B1.astype(np.int32)
  B2=B2.astype(np.int32)

  #計算均方誤差,初始化64位無符号整型,防止累加中溢出
  R_mse=np.uint64(0)
  G_mse=np.uint64(0)
  B_mse=np.uint64(0)
  for i in range(w):
    for j in range(h):
      R_mse+=(R1[i][j]-R2[i][j])**2
      G_mse+=(G1[i][j]-G2[i][j])**2
      B_mse+=(B1[i][j]-B2[i][j])**2
  R_mse/=(w*h)
  G_mse/=(w*h)
  B_mse/=(w*h)
  R_psnr=10*math.log((255**2)/R_mse,10)
  G_psnr=10*math.log((255**2)/G_mse,10)
  B_psnr=10*math.log((255**2)/B_mse,10)

  return R_psnr,G_psnr,B_psnr


def main():
  img='./lena.png'
  img1='./lena_encrypt1.png'
  img2='./lena_encrypt2.png'
  #計算PSNR
  R_psnr,G_psnr,B_psnr=PSNR(img,img1)
  print('***********峰值信噪比*********')
  print(R_psnr,G_psnr,B_psnr)
  print('通道R:{:.4}'.format(R_psnr))
  print('通道G:{:.4}'.format(G_psnr))
  print('通道B:{:.4}'.format(B_psnr))


if __name__== '__main__':
  main()

           

對比度調節

一幅圖像中必須存在合适的亮度和對比度,這樣才能讓人看得舒服,前者代表整個圖像的明度或暗度,後者定義亮度的差異,以确定不同區域的清晰分離。是以,對比度調整是一種圖像處理機制,其中的輸入強度映射到所需的水準,以增強感興趣的區域或區域。

時間和空間開銷分析

加密算法的時間和空間開銷是衡量加密算法性能的重要名額之一。時間開銷分析通常包括加/解密算法的時間複雜度分析和模拟平台測試的真實的加/解密運作速度,通過對算法的時間複雜度的分析從理論上證明圖像加密算法在效率上的可行性。空間開銷分析是指分析圖像加密算法在加/解密過程中占用的最大記憶體單元,給出模拟平台下需要的最大記憶體資源。一個好的加密算法應該盡可能地花費較少的時間成本,并占用較少的空間資源。

潛在攻擊

純密文攻擊

概念

在隻有密文本身可用的情況下解密密文的一種攻擊,攻擊者試圖恢複相應的明文或加密密鑰。

已知明文攻擊

概念

攻擊者試圖在擁有密文和相關的純文字片段的情況下恢複密鑰。

選擇明文攻擊

概念

一種具有優異擴散特性的圖像加密算法,能夠抵抗選擇明文攻擊。然而,當幾種現有的圖像加密算法使用相同的安全密鑰加密原始圖像時,它們的加密圖像是重複的。攻擊者利用這個安全弱點,使用標明的純文字攻擊來破壞加密算法

未完待續。。。。

參考

【An overview of encryption algorithms in color images】

【A color image encryption technique using exclusive-OR with DNA complementary rules based on chaos theory and SHA-2】