MATLAB 实现DES加解密

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

实验题目:DES加解密

一、实验目的

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

实现目标:实现DES加解密;

实现加密解密交互界面;

为方便输入,采用16进制,加解密时转换为64bit的2进制;

实现加密解密关键步骤信息输出。

二、方案设计

1. 加密过程

DES加密过程总体上可拆分为3大块,即明文加密过程、F轮函数、密钥生成过程

明文加密过程:

输入64bit的明文进行IP置换,分成左右两个分支各为32bit, 左边:32bitL0,右边:32bitR0

右分支:L1 = R0 左分支:引入48bit 的密钥,R1=L0 异或 f(R0,K1)

相同的操作进行16次的运算循环,算出相应的,R1~R16,L0~L16

最后进行IP的逆序置换,将左右两个分支再次合并为64bit密文

轮函数:

首先进行IP置换

置换结束后进行E扩展,将32bit的R0 扩展为48bit的R0

异或:将48bit的R0于48bit的K1进行异或

S盒压缩处理:大盒子里有8块6bit的小盒子,盒子的特点是6进4出,出了盒子就变成了32bit

IP逆序置换

密钥生成过程

密钥原本为64bit ,去掉8位校验位,剩余56位参与运算

按照交换规则,生成16个48bit的轮密钥

2. 解密过程

DES解密与DES加密过程对称,在16轮循环中子密钥相加时有所不同(16轮迭代中,调转左右子秘钥的位置),核心代码为:

3. 信息输出

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

4. 交互界面

基于Matlab2019b中的mlapp编程实现

三、方案实现

1. DES加解密函数

介绍:DES加解密函数
%DES
function C=DES(~,D,K,M)
            %   输入16进制数表示的字符串格式明文D和密钥K,M=1表示加密
            fbar = waitbar(0,'16进制转2进制中');
            %%    ----------------------------------数据初始化-----------------------------------
            %将以字符串形式输入的明文和密钥转换成01数字串
            DB=[];
            for i=1:16
                waitbar(i/16,fbar,'字符处理中');
                pause(0.01);
                Di=D(i);
                DBi=['0000',dec2bin(hex2dec(Di))];
                DBi=DBi(end-3:end);
                DBi=[str2num(DBi(1)),str2num(DBi(2)),str2num(DBi(3)),str2num(DBi(4))];
                DB=[DB,DBi];
            end
            waitbar(1,fbar,'字符处理完毕');
            pause(0.3);
            D=DB;
            KB=[];
            for i=1:16
                waitbar(i/16,fbar,'密钥处理中');
                pause(0.01);
                Ki=K(i);
                KBi=['0000',dec2bin(hex2dec(Ki))];
                KBi=KBi(end-3:end);
                KBi=[str2num(KBi(1)),str2num(KBi(2)),str2num(KBi(3)),str2num(KBi(4))];
                KB=[KB,KBi];
            end
            K=KB;
            waitbar(1,fbar,'密钥处理完毕');
            pause(0.3);
            %64位数据IP置换表
            waitbar(0,fbar,'初始化IP置换表');
            pause(0.3);
            IP=[58 50 42 34 26 18 10 2;
                60 52 44 36 28 20 12 4;
                62 54 46 38 30 22 14 6;
                64 56 48 40 32 24 16 8;
                57 49 41 33 25 17 9 1;
                59 51 43 35 27 19 11 3;
                61 53 45 37 29 21 13 5;
                63 55 47 39 31 23 15 7];
            IP0=reshape(IP',1,64);
            waitbar(1,fbar,'IP置换表初始化完毕');
            pause(0.3);
            %转换成行向量
            D_IP=D(IP0);%对D初始置换
            %E盒为数据扩展
            waitbar(0,fbar,'初始化密钥E盒');
            pause(0.3);
            E=[32, 1,    2, 3, 4, 5;
                4, 5,    6, 7, 8, 9;
                8, 9,10,11,12,13;
                12,13,14,15,16,17;
                16,17,18,19,20,21;
                20,21,22,23,24,25;
                24,25,26,27,28,29;
                28,29,30,31,32,1];
            waitbar(1,fbar,'E盒处理完毕');
            pause(0.3);
            waitbar(0,fbar,'初始化S盒中');
            pause(0.3);
            S1=[14, 4,    13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7;
                0, 15, 7,    4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8;
                4, 1,    14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0;
                15, 12, 8,    2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13];
            waitbar(1/8,fbar,'初始化S盒中');
            pause(0.1);
            S2=[15, 1,    8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10;
                3, 13, 4,    7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5;
                0, 14, 7,    11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15;
                13, 8,    10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9];
            waitbar(2/8,fbar,'初始化S盒中');
            pause(0.1);
            S3=[10, 0,    9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8;
                13, 7,    0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1;
                13, 6,    4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7;
                1, 10, 13, 0,    6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12];
            waitbar(3/8,fbar,'初始化S盒中');
            pause(0.1);
            S4=[7, 13, 14, 3,    0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15;
                13, 8,    11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9;
                10, 6,    9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4;
                3, 15, 0,    6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14];
            waitbar(4/8,fbar,'初始化S盒中');
            pause(0.1);
            S5=[2, 12, 4,    1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9;
                14, 11, 2,    12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6;
                4, 2,    1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14;
                11, 8,    12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3];
            waitbar(5/8,fbar,'初始化S盒中');
            pause(0.1);
            S6=[12, 1,    10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11;
                10, 15, 4,    2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8;
                9, 14, 15, 5,    2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6;
                4, 3,    2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13];
            waitbar(6/8,fbar,'初始化S盒中');
            pause(0.1);
            S7=[4, 11, 2,    14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1;
                13, 0,    11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6;
                1, 4,    11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2;
                6, 11, 13, 8,    1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12];
            waitbar(7/8,fbar,'初始化S盒中');
            pause(0.1);
            S8=[13, 2,    8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7;
                1, 15, 13, 8,    10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2;
                7, 11, 4,    1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8;
                2, 1,    14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11];
            waitbar(8/8,fbar,'S盒初始化完毕');
            pause(0.3);
            %P盒置换
            waitbar(0,fbar,'P盒初始化中');
            pause(0.3);
            P=[16,7,20,21,29,12,28,17,1,15,23,26,5,18,31,10,2,8,24,14,32,27,3,9,19,13,30,6,22,11,4,25];
            PC1=[57,49,41,33,25,17,9,1,58,50,42,34,26,18,10,2,59,51,43,35,27,19,11,3,60,52,44,36,63,55,47,39,31,23,15,7,62,54,46,38,30,22,14,6,61,53,45,37,29,21,13,5,28,20,12,4];
            PC2=[14,17,11,24,1,5,3,28,15,6,21,10,23,19,12,4,26,8,16,7,27,20,13,2,41,52,31,37,47,55,30,40,51,45,33,48,44,49,39,56,34,53,46,42,50,36,29,32];
            waitbar(1,fbar,'P盒初始化完毕');
            pause(0.3);
            %%    ------------------------------产生子密钥---------------------------------
            Ki=zeros(16,48);
            K_PC1=K(PC1);
            %经过密钥初始置换
            C0=K_PC1(1:28);%分为两部分
            D0=K_PC1(29:56);
            for i=1:16
                waitbar(i/16,fbar,'子密钥生成中');
                pause(0.01);
                if i==1||i==2||i==9||i==16%第1、2、9、16轮循环左移1位
                    C0=[C0(2:end),C0(1)];
                    D0=[D0(2:end),D0(1)];
                else%其它轮循环左移2位
                    C0=[C0(3:end),C0(1:2)];
                    D0=[D0(3:end),D0(1:2)];
                end
                K_LS=[C0,D0];
                Ki(i,:)=K_LS(PC2);
            end
            waitbar(1,fbar,'子密钥生成完毕');
            pause(0.3);
            %%    ---------------------------16轮循环加密---------------------------------
            L=D_IP(1:32);%输入的左半部分明文
            R=D_IP(33:64);%输入的右半部分明文
            for i=1:16
                waitbar(i/16,fbar,'循环加密中');
                pause(0.01);
                E0=reshape(E',1,48);%把E盒转换成行向量
                R_E=R(E0);       %E盒扩展
                %与子密钥相加
                if M==1       %选择加密与解密,M=1表示加密
                    R_Ki=mod(R_E+Ki(i,:),2);
                else
                    R_Ki=mod(R_E+Ki(17-i,:),2);
                end
                %经S1盒
                B=R_Ki(1:6);
                x=B(1)*2+B(6)+1;
                y=B(2)*8+B(3)*4+B(4)*2+B(5)+1;
                C=['0000',dec2bin(S1(x,y))];
                C=C(end-3:end);
                C1=[str2num(C(1)),str2num(C(2)),str2num(C(3)),str2num(C(4))];
                %经S2盒
                B=R_Ki(7:12);
                x=B(1)*2+B(6)+1;
                y=B(2)*8+B(3)*4+B(4)*2+B(5)+1;
                C=['0000',dec2bin(S2(x,y))];
                C=C(end-3:end);
                C2=[str2num(C(1)),str2num(C(2)),str2num(C(3)),str2num(C(4))];
                %经S3盒
                B=R_Ki(13:18);
                x=B(1)*2+B(6)+1;
                y=B(2)*8+B(3)*4+B(4)*2+B(5)+1;
                C=['0000',dec2bin(S3(x,y))];
                C=C(end-3:end);
                C3=[str2num(C(1)),str2num(C(2)),str2num(C(3)),str2num(C(4))];
                %经S4盒
                B=R_Ki(19:24);
                x=B(1)*2+B(6)+1;
                y=B(2)*8+B(3)*4+B(4)*2+B(5)+1;
                C=['0000',dec2bin(S4(x,y))];
                C=C(end-3:end);
                C4=[str2num(C(1)),str2num(C(2)),str2num(C(3)),str2num(C(4))];
                %经S5盒
                B=R_Ki(25:30);
                x=B(1)*2+B(6)+1;
                y=B(2)*8+B(3)*4+B(4)*2+B(5)+1;
                C=['0000',dec2bin(S5(x,y))];
                C=C(end-3:end);
                C5=[str2num(C(1)),str2num(C(2)),str2num(C(3)),str2num(C(4))];
                %经S6盒
                B=R_Ki(31:36);
                x=B(1)*2+B(6)+1;
                y=B(2)*8+B(3)*4+B(4)*2+B(5)+1;
                C=['0000',dec2bin(S6(x,y))];
                C=C(end-3:end);
                C6=[str2num(C(1)),str2num(C(2)),str2num(C(3)),str2num(C(4))];
                %经S7盒
                B=R_Ki(37:42);
                x=B(1)*2+B(6)+1;
                y=B(2)*8+B(3)*4+B(4)*2+B(5)+1;
                C=['0000',dec2bin(S7(x,y))];
                C=C(end-3:end);
                C7=[str2num(C(1)),str2num(C(2)),str2num(C(3)),str2num(C(4))];
                %经S8盒
                B=R_Ki(43:48);
                x=B(1)*2+B(6)+1;
                y=B(2)*8+B(3)*4+B(4)*2+B(5)+1;
                C=['0000',dec2bin(S8(x,y))];
                C=C(end-3:end);
                C8=[str2num(C(1)),str2num(C(2)),str2num(C(3)),str2num(C(4))];
                   C=[C1,C2,C3,C4,C5,C6,C7,C8];%经过8个S盒的结果合并
                R_P=C(P);%P盒置换
                %交换左右两半部分
                TEMP=L;
                L=R;
                R=mod(TEMP+R_P,2);
            end
            waitbar(1,fbar,'循环加密结束');
            pause(0.3);
            %交换左右两半部分
            TEMP=L;
            L=R;
            R=TEMP;
            %输出密文
            C=[L,R];
            %%    -------------------------------逆初始置换------------------------------
            waitbar(0,fbar,'逆置换');
            pause(0.3);
            IP_1=[40 8 48 16 56 24 64 32;
                39 7 47 15 55 23 63 31;
                38 6 46 14 54 22 62 30;
                37 5 45 13 53 21 61 29;
                36 4 44 12 52 20 60 28;
                35 3 43 11 51 19 59 27;
                34 2 42 10 50 18 58 26;
                33 1 41 9 49 17 57 25];
            IP_10=reshape(IP_1',1,64);
            C=C(IP_10);
            CS=[];
            C=num2str(C);
            pos= C~=' ';
            %pos=find(C~='    ');
            C=C(pos);
            for i=1:4:61
                Ci=C(i:i+3);
                   CS=[CS,num2str(dec2hex(bin2dec(Ci)))];
            end
            waitbar(1,fbar,'加密结束');
            pause(0.3);
            close(fbar);
            C=CS;
end

2. 加密过程

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

function EnButtonPushed(app, event)
            ifstrcmp(app.Plaintext_En.Value,'')
                logRefresh_func_En(app,'请输入明文');
                return
            end
            ifstrcmp(app.KeyWord.Value,'')
                logRefresh_func_En(app,'请输入密钥');
                return
            end
            if length(app.Plaintext_En.Value)~=16
                logRefresh_func_En(app,'请输入16位明文字符(16进制)');
                return
            end
            if length(app.KeyWord.Value)~=16
                logRefresh_func_En(app,'请输入16位密钥字符(16进制)');
                return
            end
            
            plainText=app.Plaintext_En.Value;
            Key=app.KeyWord.Value;
            app.Ciphertext=app.DES(plainText,Key,1);
            app.logRefresh_func_En('加密结束');
            
            app.Crypt_En.Value=app.Ciphertext;
            app.Crypt_De.Value=app.Ciphertext;
end

3. 解密过程

介绍:解密按钮DeButtom回调函数

function DeButtonPushed(app, event)
            ifstrcmp(app.Crypt_De.Value,'')
                logRefresh_func_De(app,'请输入密文');
                return
            end
            ifstrcmp(app.KeyWord_De.Value,'')
                logRefresh_func_De(app,'请输入密钥');
                return
            end
            if length(app.Crypt_De.Value)~=16
                logRefresh_func_De(app,'请输入16位明文字符(16进制)');
                return
            end
            if length(app.KeyWord_De.Value)~=16
                logRefresh_func_De(app,'请输入16位密钥字符(16进制)');
                return
            end
            cipertext=app.Crypt_De.Value;
            Key=app.KeyWord_De.Value;
            app.Plaintext=app.DES(cipertext,Key,0);
            app.logRefresh_func_De('解密结束');
            app.Plaintext_De.Value=app.Plaintext;
end

4. 信息输出

介绍:加密界面信息输出函数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

5. 交互界面

Matlab2019b的mlapp开发环境

四、数据测试与分析

1. 数据测试

测试数据:明文2020310252210006 密钥7876564352839178

密文F23A2F37F5861AA0

加密过程

解密过程

加解密演示

2. 分析

DES加解密属于对称密码体系,加密方与解密方公用同一个密钥。DES加密的过程总体上可以分为3部分。首先是明文加密过程,在加密过程中,64bit的明文输入首先进行IP置换,分为左右两部分,各32bit。右半部分的L1=R0,左半部分引入48bit的密钥,R1=L0异或F(R0,K1)。随后进行相同的16次循环,算出相应的R1至R16与L1至L16。最后再进行IP逆置换,再将左右两部分合并,即可得到64bit的密文。

其中,轮函数为比较重要的部分,轮函数中首先进行IP置换。置换结束后进行E扩展,将32bit的R0扩展为48bit的R0,随后进行异或,即将48bit的R0与K1进行异或。结束后再进行S盒的压缩处理,6bit进4bit出,将48bit的输入转为32bit输出。S盒压缩处理结束后,再进行IP逆置换。

此外,密钥生成的过程也比较重要。密钥本身为64bit的输入,但是需要去除8bit的校验位,剩余的56bit参与运算。经过交换操作,生成16个48bit的轮密钥。

五、总结

DES加密属于对称密码体系中的分组加密算法

DES加解密针对64bit的明文以及密钥,在实验过程中,为了方便用户输入,使用16进制的输入。获取输入后,将其转换为2进制的明文以及密钥串

实验过程中,限制了用户的输入必须为16位16进制数字,位数不够时,会输出提示信息

DES加密过程复杂,且加密与解密过程高度对称,因此在实验过程中,将整个DES加解密函数编写在了同一个函数中,即DES()函数

在加密过程中,DES()函数的最后一个参数为1,表示加密。解密过程中,DES()函数的最后一个参数为0,表示解密

DES加密的主要过程为中间的16轮循环,该部分在处理时,为了加快速度,实验中将S盒以及P盒全部写进了DES()函数中,直接在加解密的过程中初始化并加以使用

DES加解密的过程中轮函数比较重要,首先进行IP置换。置换结束后进行E扩展,将32bit的R0扩展为48bit的R0,随后进行异或,即将48bit的R0与K1进行异或。结束后再进行S盒的压缩处理,6bit进4bit出,将48bit的输入转为32bit输出。此外,还需要进行IP逆置换

除了轮函数外,16轮的轮密钥生成也非常重要。密钥本身为64bit的输入,但是需要去除8bit的校验位,剩余的56bit参与运算。每轮中经过置换操作,生成48bit的轮密钥

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

BumbleStone

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

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

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

打赏作者

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

抵扣说明:

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

余额充值