Implementing a Digital Image Encryption and Decryption System with MATLAB


The project has been uploaded to GitHub: link address
My personal blog: Mouren·Blog
Wechat public account: Mouren's sack
CSDN: Cao Mouren



Summary & Mind Map

This project is a digital image encryption and decryption system based on MATLAB, and the encryption algorithm is independently designed by the author. This encryption system can restore the original image 100% losslessly, supports encryption and decryption of single-channel and three-channel digital images, and supports encryption and decryption of many mainstream image formats such as jpg, jpeg, png, tif, tiff, and bmp. In addition, users can choose the number of encryption times, the more encryption times, the more disordered the pixels, and the higher the safety factor. But for the recipient, it is convenient and fast to decrypt the image with one key without knowing the number of encryptions.
At the same time, the algorithm of this project is simple and easy to learn. It is a good digital image processing practice project.
The overall mind map of the algorithm is as follows:
mind Mapping

Image encryption algorithm (with source code)

The author believes that the so-called encryption is "regular destruction". That is to "destroy" as much as possible under the premise of ensuring recovery. The greater the degree of "destruction", the lower the correlation with the original information, the greater the difficulty of being broken, and the better the encryption effect.
Therefore, in order to "destroy" the original image as much as possible, in this encryption system, the encryption algorithm successively performs two parts: pixel value encryption and pixel distribution encryption, "destroying" the original image from two aspects successively, and the encryption effect is better.

Pixel value encryption

Pixel value encryption is divided into two steps.
In the first step, since the pixel value range of the RBG three-channel image and the single-channel grayscale image is [0,255], you can subtract each pixel value from 255 to perform the first pixel value transformation.
The test image looks like this:
test image

After the first step of transforming the pixel value, the result is as follows:
After the first step of pixel value encryption

The second step is to disrupt the order of the three channels of RGB and convert RGB to BRG. This step is only for RGB three-channel images. If the incoming image is a grayscale image, only the first step is completed.
In MATLAB, the storage format of the incoming three-channel color image is a three-dimensional matrix of unsigned integer 8 bits (uint8). The value of the R (Red) channel is stored in (*,*,1), the value of the G (Green) channel is stored in (*,*,2), and the value of the B (Blue) channel is stored in (*,*,3) . After transformation, the value of the R (Red) channel is stored in (*,*,2), the value of the G (Green) channel is stored in (*,*,3), and the value of the B (Blue) channel is stored in (*, *,1). The following figure is the image after the second step of transformation based on the output image of the first step, and it is also the result of the pixel value encryption of the test image:
Pixel value encryption completes the image

So far, pixel value encryption has been completed.
Pixel value transformation function source code:

function imSrc = Figure_Transform(imSrc,mode)
%该函数对传入图像进行像素值加密或解密
%imSrc:传入三通道或单通道图像
%mode:选择加密或解密。0:加密 1:解密


[~,~,channel]=size(imSrc);%获取传入图像的尺寸信息
%-----------------像素值加密/解密-----------------%
%---step 1:对最大像素值255取差(加密解密相同)---%
imSrc=abs(255-imSrc);

%下面的rgb通道顺序改变只针对3通道图像,单通道灰度图不能进行该操作
if channel==3   
    %---step 2:打乱/恢复 颜色通道顺序---%
    %彩色图像三通道分布顺序:
    %(:,:,1)--red (:,:,2)--green (:,:,3)--blue
    %加密:rgb->brg        解密:brg->rgb
    %---1:前两位交换(加密解密相同)---%
    temp=imSrc(:,:,2);
    imSrc(:,:,2)=imSrc(:,:,1);
    imSrc(:,:,1)=temp;
    %---2:加密:第一位g和第三位b交换得到brg---%
    %---2:解密:第二位b和第三位g交换得到rgb---%
    temp=imSrc(:,:,3);
    imSrc(:,:,3)=imSrc(:,:,1+mode);
    imSrc(:,:,1+mode)=temp;
end


end


Pixel distribution encryption

Judging from the output image after the pixel value encryption is completed, although the color has a large deviation from the original image, we can still clearly see the contour line information of the original image. So the next thing we have to do is to disrupt the order of the pixels and destroy the contour information.
In order to scramble the arrangement of pixels, similar to twisting the Rubik's cube, we can scramble the pixel distribution of each row and column successively. Then, what kind of shuffling rules should be followed to ensure the chaos and recoverability of the pixel distribution? Here I designed a key matrix: (The following key matrix is ​​the key matrix in the current system)
distriKey=

The first row of the matrix is ​​the index, the second row is the row offset key, and the third row is the column offset key key. The sign of the secret key determines the shift direction, the absolute value determines the degree of shift, and one line represents a translation period. The offset operation uses the MATLAB circular shift function circshift.
When performing row offset or column offset, since the sizes of the incoming images are different, in order to ensure a consistent shuffling effect, the absolute value of the key value cannot represent the number of bits offset. Instead, it should be converted into the ratio in the column or row, so the secret key matrix must be preprocessed first, that is, the absolute value of the secret key value in the second and third rows is converted into the ratio in the row, and then with On the original symbol, the code is as follows:

[~,distrikeyCol]=size(distriKey);%获取密钥矩阵尺寸
%下面循环是将密钥值换成比例
for a=1:distrikeyCol
    newRowKey=abs(  distriKey(2,a)  )/ sum( abs( distriKey(2,:) ) );
    newColKey=abs(  distriKey(3,a)  )/ sum( abs( distriKey(3,:) ) );
    %下面是将已经算得的比例值带上原先的正负号
    distriKey(2,a)=newRowKey*(distriKey(2,a)/abs(distriKey(2,a)));
    distriKey(3,a)=newColKey*(distriKey(3,a)/abs(distriKey(3,a)));
end

After preprocessing, the secret key matrix distriKey=
Preprocessed secret key matrix
How to obtain the secret key value corresponding to the current row or column according to the index of the first row?

  • The current row number or column number is modulo the length of the secret key matrix
  • Find the same value as the remainder result in the first row of the secret key matrix
  • After finding the corresponding index value, the second line of the column where the index is located is the row transformation key value, and the third line is the column transformation key value

In this way, after taking the value of the last column of the secret key matrix, it will return to the value of the first column next time. One row is one offset cycle.
Therefore, we can increase the degree of freedom of migration by increasing the length of the migration cycle, and improve the safety factor .
Next, the image after pixel value encryption will be subjected to a row transformation and a column transformation:
After the row transformation:
After row transformation

After row transformation + column transformation:
After row transformation + column transformation

So far, we have completed pixel value encryption and a pixel distribution encryption.
Of course, the encryption effect of this encrypted image reflects the key matrix just listed, not the optimal key.
We can change the key value and key matrix length to optimize the shuffling rules. For example:

  • The difference between the absolute values ​​of two adjacent secret key values ​​is larger
  • Adjacent intervals should avoid the same
  • The positive and negative signs of the secret key value should be set as irregularly as possible
  • Increase Length Increase Offset Period
  • ··· ···

Therefore, the secret key matrix brings a lot of freedom to the encryption algorithm and is not easy to be broken.

Source code:
row transformation function source code:

function imSrc = Row_Transform(imSrc,distriKey,mode)
%   对传入图像进行行变换(加密/解密)
%   imSrc:传入三通道或单通道图像
%   distriKey:传入秘钥矩阵
%   mode:选择加密或解密。 1:加密 -1:解密


[row,col,channel]=size(imSrc);%获取传入图像的尺寸信息
[~,distrikeyCol]=size(distriKey);%获取密钥数组尺寸
%下面循环是将密钥值换成比例
for a=1:distrikeyCol
    newRowKey=abs(  distriKey(2,a)  )/ sum( abs( distriKey(2,:) ) );
    newColKey=abs(  distriKey(3,a)  )/ sum( abs( distriKey(3,:) ) );
    
    distriKey(2,a)=newRowKey*(distriKey(2,a)/abs(distriKey(2,a)));
    distriKey(3,a)=newColKey*(distriKey(3,a)/abs(distriKey(3,a)));
end



%移动的位数和方向由像素分布密钥决定
tempRowMove=zeros(channel,col);
for j=1:row
    %下面循环是将当前行上所有像素值放到中间量tempRowMove中
    for i=1:col
        tempRowMove(:,i)=imSrc(j,i,:);
    end
    %下面选择结构用于判断当前行移动情况(方向和偏移量)
    %在密钥中找到相应秘钥值
    keyId=mod(j,distrikeyCol);
    for m=1:distrikeyCol
            if(distriKey(1,m)==keyId)
                keyId=m;%如果找到keyId位置将该位置的列数赋给keyId
                break;
            end
            continue;
    end
    %确定偏移的方向
    moveDirect=distriKey(2,keyId)/abs(distriKey(2,keyId));
    %偏移量和偏移方向
    rowMove=mode*moveDirect*ceil(row*abs(distriKey(2,keyId)));

    %下面的循环是对当前行上的像素进行移动
    for n=1:channel
        tempRowMove(n,:)=circshift(tempRowMove(n,:),rowMove);
    end
    %下面循环是将偏移后的像素重新赋值回去
    for t=1:col
        for s=1:channel
            imSrc(j,t,s)=tempRowMove(s,t);
        end
    end
end


end


Column transformation function source code:

function imSrc = Col_Transform(imSrc,distriKey,mode)
%   对传入图像进行列变换(加密/解密)
%   imSrc:传入三通道或单通道图像
%   distriKey:传入秘钥矩阵
%   mode:选择加密或解密。 1:加密 -1:解密

[row,col,channel]=size(imSrc);%获取传入图像的尺寸信息
[~,distrikeyCol]=size(distriKey);%获取密钥数组尺寸
%下面循环是将密钥值换成比例
for a=1:distrikeyCol
    newRowKey=abs(  distriKey(2,a)  )/ sum( abs( distriKey(2,:) ) );
    newColKey=abs(  distriKey(3,a)  )/ sum( abs( distriKey(3,:) ) );
    
    distriKey(2,a)=newRowKey*(distriKey(2,a)/abs(distriKey(2,a)));
    distriKey(3,a)=newColKey*(distriKey(3,a)/abs(distriKey(3,a)));
end

%移动的位数和方向由像素分布密钥决定
tempColMove=zeros(row,channel);
for j=1:col
    %下面循环是将当前列上所有像素值放到中间量tempColMove中
    for i=1:row
        tempColMove(i,:)=imSrc(i,j,:);
    end
    %下面选择结构用于判断当前列移动情况(方向和偏移量)
    %在密钥中找到相应偏移比例
    keyId=mod(j,distrikeyCol);
    for m=1:distrikeyCol
            if(distriKey(1,m)==keyId)
                keyId=m;%如果找到keyId位置将该位置的列数赋给keyId
                break;
            end
            continue;
    end
    %确定偏移的方向
    moveDirect=distriKey(3,keyId)/abs(distriKey(3,keyId));
    %偏移量和偏移方向
    colMove=mode*moveDirect*ceil(row*abs(distriKey(3,keyId)));
    %下面的循环是对当前列上的像素进行移动
    for n=1:channel
        tempColMove(:,n)=circshift(tempColMove(:,n),colMove);
    end
    %下面循环是将偏移后的像素重新赋值回去
    for t=1:row
        for s=1:channel
            imSrc(t,j,s)=tempColMove(t,s);
        end
    end
end


end


Pixel distribution encryption source code:
(call the above two row transformation functions and column transformation functions)

function imSrc = Distribution_Transform(imSrc,mode)
%  该函数对传入图像进行像素排列上加密或解密
%  imSrc:传入三通道或单通道图像
%  mode:选择加密或解密。1:加密  -1:解密


%像素分布密钥(第一行是密钥值的索引)
%秘钥的值的绝对值大小就是偏移的程度,正负号表示偏移的方向
%为了保证加密效果,行变换和列变换的秘钥不同
%第二行是行秘钥,第三行是列秘钥
distriKey=[
1,        2,        3,        4,        5,        6,        7,        8,        9,        10,        11,        12,        13,        14,        0;
8,       -1,      -16,      11,      7,        -4,      10,      -4,       12,	     2,	         1,         -20,       -7,         18,        1;
-1,     25,       7,	    -9,	     41,	  -10,	   16,	    -28,	  -2,	   11,	      -10,        6,         45,        -18,       9
];
if mode==1%加密
    imSrc=Row_Transform(imSrc,distriKey,mode);%打乱行
    imSrc=Col_Transform(imSrc,distriKey,mode);%打乱列
else %解密
    imSrc=Col_Transform(imSrc,distriKey,mode);%恢复列
    imSrc=Row_Transform(imSrc,distriKey,mode);%恢复行
end


end

pixel iterative encryption

Although we basically have no way of knowing what the original image looks like from the above image, we can still vaguely see that the colors of pixels in different areas are different. In order to ensure a higher safety factor, we can perform pixel iterative encryption without changing the secret key matrix .
Iterative encryption is to repeat the pixel distribution encryption many times. The reason why the pixel value encryption is not included is that if the pixel value encryption is iterated, the original pixel value will be restored, so the iteration is meaningless.

Image iteratively encrypted 2 times:
Iterate 2 times
Image iteratively encrypted 3 times:
Iterate 3 times
Image iteratively encrypted 5 times:
Iterate 5 times
From these results, we can basically meet our encryption needs.
However, in order to decrypt with one key, there is no need to enter the number of decryptions, and the image after iterative encryption must carry the information of the number of iterations.
In order to make the output image carry the information of the number of iterations, we can add a redundant column on the far left. The value of the redundant column is the same as that of the adjacent column, so that the redundant column can be well hidden in the encrypted image. Then store the encryption times in the first row, first column, first page, that is, (1,1,1) of the output image.
It can be seen at a glance from the following diagram:
Add redundant columns
After the iterative encryption is completed, the encryption of the image is completed.
Image encryption function source code:
(call the above pixel value encryption and pixel distribution encryption functions)

function imSrc = Digital_Image_Encryption(imSrc,count)
%该函数对传入图像进行加密
%imSrc:传入三通道或单通道图像
%count:像素排列加密次数


% %-----------------第一次加密:像素值加密-----------------%
imSrc=Figure_Transform(imSrc,0);%调用封装好的函数

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

%-----------------下面的操作是为了让输出图像携带有加密次数---------------%
[row,~,channel]=size(imSrc);
timesCol=zeros(row,1,channel);
%------为提升安全系数,多出的一列与邻近一列相同,只是第一个像素的像素值是加密次数%
for n=1:row
    timesCol(n,1,:)=imSrc(n,1,:);%将imSrc第一列所有像素复刻到新列中
end
timesCol(1,1,1)=count;%在第一行第一列第一页位置像素值就是加密次数
imOut=[timesCol,imSrc];%将加密次数列并到加密图像上
imSrc=imOut;%将最终图像输出

end

Image decryption algorithm (with source code)

Once encryption is complete, decryption is simple. Image decryption is the reverse process of image encryption. There are mainly the following steps:

  • The first step is to obtain the iteration number information at (1,1,1), and then delete the first column
  • Then decrypt the pixel value, as in the encryption, first subtract the pixel value from 255, if it is a three-channel image, then restore the RGB channel order, and convert BRG back to RGB
  • Finally, decrypt the pixel distribution. Multiply -1 on the offset direction to restore the same number of digits in the opposite direction to that of encryption. Set a for loop in the outer layer. The number of loops is the number of iterations that have been obtained, so it can be restored. original image

Decrypt the encrypted image iteratively for 5 times as follows:
decrypt
it can be restored without distortion.

Image decryption algorithm source code:
(call pixel value transformation function and pixel distribution transformation function)

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 interface design

The UI interface of this system is made with APP Designer of MATLAB. The specific operation will not be repeated here, the following image is the display of the UI interface:

Directory interface:
directory interface

Encryption system interface:
Encryption System Interface

Decryption system interface:
Decryption system interface

logo design

Software icon:
icon
original image:
original logo

Due to my limited level, there are still many flaws and irrationality in the algorithm and code, and I hope you can criticize and correct me a lot!

Guess you like

Origin blog.csdn.net/ZBC010/article/details/121446978