MATLAB 实现Hill密码加解密

程序下载链接:https://download.csdn.net/download/m0_56241309/87456830

一、实验目的

实验环境: Windows 11操作系统;Matlab2019b

实现目标:实现Hill密码加解密;矩阵规模可随意设置;

实现加密解密交互界面;实现加密解密关键步骤信息输出。

二、方案设计

1. 加密过程

首先获取明文字符串,并对明文字符串做预处理,将字符串中的所有空格删除,并将所有字母大写

此外,由于Hill密码要求每次计算时,明文字符的个数需要与密钥矩阵的行数相同,因此需要确保明文字符串的长度是行数的整数倍。所以,长度不足时,使用明文字符串的最后一个字符进行尾部填充

预处理结束后,获取密钥矩阵规模(必须是方阵)以及密钥矩阵元素

在获取到密钥矩阵元素后,需要对文本框内的元素进行矩阵化处理(注意Matlab文本框中需要按列输入矩阵元素),以空格为分隔符将每个元素从文本款中提取出来,并存储到密钥矩阵中,直至最后一个字符

密钥矩阵初始化结束后,可以开始加密。假设密钥矩阵规模为n*n,那么每次加密时,使用n个明文字符与密钥矩阵相乘,得到每次加密后的n个密文字符。以此类推,直至最后一组明文字符也运算完毕。最后将所有组别的密文字符拼接在一起,便得到最终加密后的密文字符串。

2. 解密过程

首先获取密文字符串,由于密文字符串中已无空格以及小写字符的存在,因此无需进行预处理

随后获取密钥矩阵规模(必须是方阵)以及密钥矩阵元素

在获取到密钥矩阵元素后,需要对文本框内的元素进行矩阵化处理(注意Matlab文本框中需要按列输入矩阵元素),以空格为分隔符将每个元素从文本款中提取出来,并存储到密钥矩阵中,直至最后一个字符

接下来需要对密钥矩阵的逆矩阵进行计算。首先计算密钥矩阵的行列式N,随后计算N关于26的逆元I。紧接着,需要确定密钥矩阵的伴随矩阵,计算方式为A=mod(inv(matrix)*det(matrix),26)。最后通过计算逆矩阵,计算方式为De_matrix=mod(NI*Accompanny,26)

计算得到密钥矩阵的逆矩阵后,可以开始解密。假设密钥矩阵的规模依旧为n*n,那么每次解密时,使用n个密文字符与逆矩阵相乘,得到每次解密后的n个明文字符。以此类推,直至最后一组密文字符也运算完毕。最后将所有组别的明文字符拼接在一起,便得到最终解密后的明文字符串。

3. 信息输出

设置两个信息输出函数,分别实现加密界面和解密界面的信息输出

4. 交互界面

基于Matlab2019b中的mlapp编程实现

三、方案实现

1. 加密过程

介绍:加密按钮EnButtom回调函数

function EnButtonPushed(app, event)
            ifstrcmp(app.Plaintext_En.Value,'')
                logRefresh_func_En(app,'请输入明文');
                return
            end
            if(app.ROW_En.Value==0||app.COLUM_En.Value==0)
                logRefresh_func_En(app,'请输入正确的矩阵规模');
                return
            end
            ifstrcmp(app.NUM_En.Value,'')
                logRefresh_func_En(app,'请输入完整矩阵信息');
                return
            end
            logRefresh_func_En(app,'字符串预处理中');
            fbar=waitbar(0,'字符串预处理中');
            plaintext_en=upper(app.Plaintext_En.Value);
            %删除明文中的空格
            Bridge='';
            for i=1:length(plaintext_en)
                ifplaintext_en(i)==' '
                    continue
                else
                    Bridge=strcat(Bridge,plaintext_en(i));
                end
            end
            plaintext_en=Bridge;
%           获取矩阵的行数,相乘时需要确保字符数与行数相等,因此不足时需要对字符串尾部进行填充无关字符
            row=app.ROW_En.Value;
            colum=app.COLUM_En.Value;
            
            times=row-mod(length(plaintext_en),row);
            iftimes~=0&&times~=row
                tail=plaintext_en(length(plaintext_en));
                for i=1:times
                    plaintext_en=strcat(plaintext_en,tail);
                end
            end
            logRefresh_func_En(app,'字符串处理完毕');
            waitbar(1,fbar,'字符串处理完毕')
            pause(0.3)
            %将获取到的数值转换为矩阵
            matrix=reshape(str2double(regexp(app.NUM_En.Value,' ','split')),[row,colum]);
            logRefresh_func_En(app,'开始加密');
            waitbar(0,fbar,'开始加密')
            pause(0.3)
            %开始加密,每colum个字符进行一次加密
            ciphertext='';
            plain_mat=abs(plaintext_en)-65;
            for i=1:length(plain_mat)
                waitbar(i/length(plain_mat),fbar,'加密中');
                pause(0.01)
                if mod(i,row)==0
                    results=mod(plain_mat(i-row+1:i)*matrix,26);    
                    for j=1:length(results)
                        ifresults(j)==0
                            ciphertext=strcat(ciphertext,'A');
                        else
                            ciphertext=strcat(ciphertext,app.alphabet(results(j)+1));
                        end
                    end
                end
            end
            logRefresh_func_En(app,'加密完成');
            waitbar(1,fbar,'加密完成')
            pause(0.3)
            close(fbar)
            app.Crypt_En.Value=ciphertext;
            app.Crypt_De.Value=ciphertext;
end
 
2.       解密过程
介绍:解密按钮DeButtom回调函数
function DeButtonPushed(app, event)
            ifstrcmp(app.Crypt_De.Value,'')
                logRefresh_func_De(app,'请输入密文');
                return
            end
            if(app.ROW_De.Value==0||app.COLUM_De.Value==0)
                logRefresh_func_De(app,'请输入正确的矩阵规模');
                return
            end
            ifstrcmp(app.NUM_De.Value,'')
                logRefresh_func_De(app,'请输入完整矩阵信息');
                return
            end
            
            row=app.ROW_De.Value;
            colum=app.COLUM_De.Value;
            matrix=reshape(str2double(regexp(app.NUM_De.Value,' ','split')),[row,colum]);
            ciphertext=app.Crypt_De.Value;
 
            logRefresh_func_De(app,'获取逆矩阵中,请稍后');
            fbar=waitbar(0,'获取逆矩阵中,请稍后');
            %确定解密密钥矩阵
                %首先求解矩阵的行列式
            for i=1:10000000000000
                if(mod(det(matrix)*i,26)-1.0000<2.7978e-12)
                    NI=i;
                    waitbar(1,fbar,'逆矩阵获取成功')
                    pause(0.3);
                    logRefresh_func_De(app,'逆矩阵获取成功');
                    break;
                end
            end
                %确定原矩阵的伴随矩阵
            Accompanny=mod(inv(matrix)*det(matrix),26);
                %确定解密矩阵
            De_matrix=mod(NI*Accompanny,26);
            logRefresh_func_De(app,'开始解密');
            waitbar(0,fbar,'开始解密')
            pause(0.3)
            %获取密文,开始解密
            plaintext='';
            cipher_mat=abs(ciphertext)-65;
            for i=1:length(cipher_mat)
                waitbar(i/length(cipher_mat),fbar,'解密中,请稍后')
                pause(0.01)
                if mod(i,row)==0
                    results=mod(cipher_mat(i-row+1:i)*De_matrix,26);    
                    for j=1:length(results)
                        ifresults(j)==0
                            plaintext=strcat(plaintext,'A');
                        else
                            plaintext=strcat(plaintext,app.alphabet(results(j)+1));
                        end
                    end
                end
            end
            waitbar(1,fbar,'解密成功')
            pause(0.3)
            close(fbar);
            logRefresh_func_De(app,'解密成功');
            app.Plaintext_De.Value=plaintext;
end

3. 信息输出

介绍:加密界面信息输出函数logRefresh_func_En

function logRefresh_func_En(app,StrArrayNew)
            app.Ptime=datestr(now);
            app.LOG=strcat('[',app.Ptime(end-7:end),']');
            StrArrayNew=strcat(app.LOG,StrArrayNew);
            app.StrArray_En=[app.StrArray_En,StrArrayNew,newline];
            app.Process_En.Value=app.StrArray_En;
end

介绍:解密界面信息输出函数logRefresh_func_De

function logRefresh_func_De(app,StrArrayNew)
            app.Ptime=datestr(now);
            app.LOG=strcat('[',app.Ptime(end-7:end),']');
            StrArrayNew=strcat(app.LOG,StrArrayNew);
            app.StrArray_De=[app.StrArray_De,StrArrayNew,newline];
            app.Process_De.Value=app.StrArray_De;
end

4. 交互界面

Matlab2019b的mlapp开发环境

四、数据测试与分析

1. 数据测试

明文:love

密钥矩阵:

密文:ZQFS

加密过程

解密过程

加解密演示

2. 分析

Hill密码是一种典型的分组加密方法。加密方与解密方约定一个共同的密钥矩阵,用于解密与解密。其中,需要确保明文字符的长度为密钥矩阵的行数的整数倍。加密方使用明文字符串与密钥矩阵相乘,得到一组密文字符。以此类推,直至计算至最后一组明文字符。最后将所有组别的密文字符拼接在一起,便得到最终的密文。解密方在获取密文字符串后,可以直接输入密钥矩阵的逆矩阵,也可以输入密钥矩阵后,计算得到密钥矩阵的逆矩阵。实验中,采用了第二种方式。在输入密钥矩阵后,需要依次计算密钥矩阵的行列式、行列式的逆元、密钥矩阵的伴随矩阵,最终计算得到密钥矩阵的逆矩阵。得到逆矩阵后,可以开始解密。解密方使用密文字符串与逆矩阵相乘,得到一组明文字符。以此类推,直至计算至最后一组密文字符。最后将所有组别的明文字符拼接在一起,便得到最终的明文文本。

五、总结

Hill密码是一种典型的分组密码

Hill密码对于唯密文攻击方式具有很高的放攻击能力

Hill密码对于已知明文攻击方式来时抵抗能力很弱

Hill密码本身基于矩阵乘法体系

分组密码中,即使密钥由多个值组成,但是每一组明文都使用同样的密钥进行加密,因此依然是单密钥

在Hill密码中,加解密双方使用同一个密钥矩阵。但是加密方使用的是原矩阵进行加密,解密方使用密钥矩阵的逆矩阵进行解密

在实现Hill密码时,需要处理大量的字符串。其中,在对密钥矩阵进行处理时需要注意,Matlab在获取密钥矩阵的元素时,需要按列进行输入。输入后,需要以空格为分隔符,将每个元素提取出来,并存储到密钥矩阵中

此外,在处理明文文本时,除了需要处理空格以及小写字符外,还需要确保明文字符有足够的元素参与运算,即需要确保明文字符的长度为密钥矩阵行数的整数倍

还需要注意的是,Hill密码的密钥矩阵规模必须是方阵,但并不是所有的方阵都存在逆矩阵

实验中,没有对密钥矩阵的规模加以限定,可以使用随意规模的方阵进行加解密。明文文本的预处理也可以保证有足够长的明文字符串参与加密,鲁棒性更强

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BumbleStone

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值