1、 1 洗手 洗手 洗手 洗手 洗手 洗手 洗手 密码学与网络安全课程实验 洗手 利用 Matlab 语言实现 DES 加密算法 洗手 洗手 洗手 洗手 洗手 洗手 洗手 洗手 洗手 洗手 洗手 洗手 洗手 姓名 :b eef ZA 学号 :b eef XXXXX 洗手 2 洗手 实验目的 洗手 牢固掌握 DES 密码算法 洗手 通过编程实现 DES 算法 , 吃饭深入掌握现代密码算法实现的基本方法 洗手 验证 DES 算法中各个模块在实现混淆和弥散中的作用 洗手 实验 内容 要求 洗手 DES 算法实现 : bef利用 Matlab 语言实现 DES 密码算法 , 吃饭 输入 64 比特明文和
2、56 比特密钥 , 吃饭加密得到 64 比特的密文 ; bef洗手 DES 弱密钥验证 : bef观察弱密钥两次加密的结果 , 吃饭 与非弱密钥两次加密的结果进行比较 ; b eef洗手 DES 算法初步应用 : beef尝试加密一个字符串 , 吃饭 字符串的长度大于 8 个字节 ; bef洗手 DES 弥散特性分析 : bef试输出每一轮加密得到的比特序列 , 吃饭 并比较当初始明文 1 个比特发生变化时 , 吃饭每一轮加密输出的哪些比特发生变化 。 洗手 洗手 实验方案 与步骤 洗手 DES 算法实现 洗手 算法实现方案 洗手 Matlab(矩阵实验室)是一款工程计算用的软件 , 吃饭 功
3、能十分强大 。 洗手 Matlab的计算基于矩阵 , 吃饭 而 DES 算法用矩阵描述是十分简洁方便的 。 洗手 因此 , 吃饭 选用Matlab 作为算法实现语言 , 吃饭 基于一系列的矩阵变换 、 bef运算来实现 DES 算法的加密 。 洗手 洗手 主要功能实现流程及代码解析 洗手 3 加密程序 洗手 图 1 DES 基本结构 洗手 DES 算法的结构非常简单 , 吃饭 是一个 16 次的迭代 。 洗手 核心是 f 函数中一系列变换 。 洗手 洗手 根据算法框图 , 吃饭程序步骤主要分为三大部分 : bef洗手 输入明文和密钥 进行字符转换 洗手 产生 16 轮 密钥 矩阵 洗手 16
4、轮迭代 洗手 %demo5.m洗手 clc, clear all;b eef洗手 %洗手 %-第一步 输入明文和密钥-%洗手 M=0123456789ABCDEF;bef% 洗手 K=0123456789ABCDEF;bef%洗手 MB=;bef 洗手 for i=1:16洗手 Mi=M(i);b eef洗手 MBi=0000,dec2bin(hex2dec(Mi);b eef洗手 MBi=MBi(end-3:end);b eef洗手 MBi=str2num(MBi(1),str2num(MBi(2),str2num(MBi(3),str2num(MBi(4);b eef洗手 MB=MB,MB
5、i;b eef洗手 end洗手 M=MB;bef% 转化为 64位二进制明文 洗手 KB=;bef洗手 for i=1:16洗手 Ki=K(i);b eef洗手 KBi=0000,dec2bin(hex2dec(Ki);b eef洗手 KBi=KBi(end-3:end);b eef洗手 KBi=str2num(KBi(1),str2num(KBi(2),str2num(KBi(3),str2num(KBi(4);b eef洗手 KB=KB,KBi;b eef洗手 end洗手 K=KB;bef% 转化为 64位二进制密钥 洗手 洗手 %洗手%-第三步 产生密钥 -%洗手PC_1=57,49,4
6、1,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;b eef洗手 %PC_1置换矩阵 56位 洗手 KEY0=K(PC_1);bef% 初始矩+ F第 1 轮L1R1+ F第 i轮LiRi+ F第 n 轮LnRnK1KiKn明文 ( 2 W 比特 )W 比特 W 比特L0R0密文 ( 2 W 比特 )选择扩展运算E+选择压缩运算S置换运算P+
7、LiRiRi - 1Li - 1Ki483248 324832324 阵变换 64 to 56洗手 %循环移位 洗手shift_array=-1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1;b eef 洗手C(1,:)=KEY0(1:28);b eef%C0洗手 D(1,:)=KEY0(29:56);bef%D0洗手 for i=2:17洗手C(i,:)=circshift(C(i-1,:),shift_array(i-1);b eef %前 28位 循环移位 %circshift是右移 移动负数位表示左移 洗手D(i,:)=circshift(D(i-1,:),shift_a
8、rray(i-1);b eef %后 28位循环移位 洗手 end洗手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;b eef洗手 Ki=zeros(16,48);bef洗手 %循环移位 洗手 KEY_MAT=C,D;bef%17*56洗手KEY_MAT=KEY_MAT(2:17,:);b eef%16*56洗手PC_2=14,17,11,24,1,5,3,28,
9、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;b eef 洗手 for i=1:16洗手 Ki(i,:)=KEY_MAT(i,PC_2);bef洗手 end洗手 KEY=Ki;bef洗手 %洗手%-第四步 Feistel结构 -%洗手 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
10、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;b eef洗手 %IP初始置换矩阵 洗手 M=M(IP);b eef%初始置换 洗手 m0_L=M(1:32);b eef %输入的左半部分明文 洗手 m0_R=M(33:64);b eef% 输入的右半部分明文 洗手L,R=fchange(m0_L,m0_R,1,KEY);b eef洗手 mi=L,R;b eef洗手 mi2_hex(1,:)=mi洗手 %进入 16轮迭代 洗手 for i=2:16洗手
11、 L,R=fchange(L,R,i,KEY);b eef洗手 mi=L,R;b eef洗手 mi2_hex(i,:)=mi洗手 end洗手 洗手 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;b eef洗手 %IP_1初始逆置换矩阵 洗手 m16=R,L;bef% 最
12、后一步进行交换 洗手 C=m16(IP_1);bef %IP逆置换 洗手m_hex=m_2_hex(C)% 转化为 16进制 输出密文 % %fchange.m洗手 function Li,Ri = fchange(Li_1,Ri_1,m,KEY)洗手 %第 i轮 f函数的实现 输入 Ri-1 表示第 i-1轮的右半部分密文 输出第 i轮的密文 Ri_1_ex=trm32_to_48(Ri_1);b eef% 第一步 右半明文进行 32to48扩展 OK Ri_1_ex2=reshape(Ri_1_ex,1,48);b eef %将扩展的 48位变为向量 OK f=bitxor(KEY(m,:
13、),Ri_1_ex2);b eef %与第 i轮密钥按位异或 洗手 f1=reshape(f,6,8);beef %变为矩阵 8个 6位二进制数 8*6洗手 %经过 S1盒 洗手 s=S_box(1);b eef洗手 x=2*f1(1,1)+f1(1,6);b eef %S盒纵坐标 y=8*f1(1,2)+4*f1(1,3)+2*f1(1,4)+f1(1,5);b eef洗手 %S盒横坐标 洗手 f2=s(x+1,y+1);b eef %取 S盒中某一数 洗手 f2_bin=0000,dec2bin(f2);b eef% % 字符串处理 洗手 f2_bin=f2_bin(end-3:end);
14、b eef洗手 f2_1=str2num(f2_bin(1),str2num(f2_bin(2),str2num(f2_bin(3),str2num(f2_bin(4);b eef洗手 %省略 s2s8盒 洗手 Ri_1_P=P_exchange(f2S);b eef %转化为向量并置换运算 P洗手 Ri=bitxor(Li_1,Ri_1_P);b eef %Li_1与 f函数后的 Ri_1进行按位异或 洗手 Li=Ri_1;b eef %交换位置 洗手 end 程序见 demo5.m。 洗手 洗手 洗手 解密程序 洗手 DES 算法设计 巧妙 也体现在 其 解密过程非常简单 , 吃饭 结构和
15、加密算法完全一样 , 吃饭 只需要将 165 轮 加密所用的密钥完全倒 过来 。 洗手 洗手 对密钥矩阵16X64 的行倒序排列 , 吃饭得到倒过来后的密钥矩阵 。 洗手 其余部分与解密程序 洗手 保持一致即可 。 洗手解密时 , 吃饭 输入密文和密钥 , 吃饭 得到明文 。 洗手 洗手 程序见 demo5_inv.m。 洗手 洗手 加密 64 比特明文 , 吃饭对密文进行解密得到明文 , 吃饭 观察是否与初始明文一致 洗手 加密 。 洗手这里用 Matlab 中的 GUI 界面编写了加解密的交互程序 。 洗手交互程序见 desecb.m。 洗手 洗手 在程序 demo5.m中输入 64 比特
16、明文及 64 比特 密钥 :洗手 M=0123456789ABCDEF;beef洗手 K=0123456789ABCDEF;beef洗手 运行 :洗手 m_hex = 56CC09E7CFDC4CEF 洗手 图 2 DES_demo GUI 界面 洗手 洗手 解密 : b eef洗手 在程序 demo5_inv.m中输入 64 比特 密文 及 64 比特 密钥 :洗手 M=56CC09E7CFDC4CEF;beef洗手 K=0123456789ABCDEF;beef洗手 运行 : 洗手 m_hex =0123456789ABCDEF 洗手 洗手 将密文解密后与初始明文一致 。 洗手 洗手 为了
17、证明程序对 DES 算法的正确实现 , 吃饭用密码学习软件 Cryptool 进行了验证 。 洗手 洗手 加密结果与本程序一致 。 洗手 洗手 图 3 CrypTool 加密结果 洗手 洗手 DES 弱密钥验证 洗手 用选定的弱密钥进行两次加密 , 吃饭观察得到的结果 洗手 用已知四个弱密钥中的一个 FFFFFFFFFFFFFFFF, 吃饭对 0123456789ABCDEF进行加 洗手 6 密 : b eef洗手 M=0123456789ABCDEF;beef洗手 K=FFFFFFFFFFFFFFFF;beef洗手 m_hex =6DCE0DC9006556A3 洗手 再次加密 : b ee
18、f洗手 M=6DCE0DC9006556A3;beef洗手 K=FFFFFFFFFFFFFFFF;beef洗手 m_hex = 0123456789ABCDEF 洗手 可以看出 , 吃饭两次加密后密文和第一次的初始明文一样 , 吃饭 相当于是加密后再解密 。 洗手 洗手 验证了弱密钥 。 洗手 洗手 用选定的非弱密钥进行两次加密 , 吃饭观察得到的结果 洗手 用已知四个半弱密钥中的一个 01FE01FE01FE01FE 和对 0123456789ABCDEF进行加密 : b e e f洗手 M=0123456789ABCDEF;beef洗手 K=01FE01FE01FE01FE;beef洗手
19、m_hex =8A76C7A4F16D47ED 洗手 再用与 01FE01FE01FE01FE对应的 半弱密钥 FE01FE01FE01FE01FE01加密 : b e e f洗手 M=8A76C7A4F16D47ED;beef洗手 K=FE01FE01FE01FE01;beef洗手 m_hex =0123456789ABCDEF 洗手 可以看出 , 吃饭一对半弱密钥能够互相加解密 。 洗手 洗手 DES 算法初步应用 洗手 任意选定一个长度大于 8 个字符的字符串 , 吃饭设计一种方法对这个字符串进行加密 洗手 用电码本模式 ECB 直接对明文分成以 64 位一组的块 , 吃饭 这里用密文分
20、组链接模 洗手 式 CBC 来实现 。 洗手 洗手 算法步骤 : b eef洗手 对任意长( m bit)明文 分成 N组 , 吃饭 每组 64bit 洗手 初始向量 IV与第一组明文异或 洗手 第 i-1 组密文与第 i 组明文异或作为 DES 的输入明文 洗手 迭代 N-1 次 洗手 得到 N*64bit 密文 , 吃饭截取 为 m bit 洗手 7 算法 框图为 : b eef洗手 图 4 DES_CBC模式基本结构 洗手 洗手 程序编写主要实现对任意长明文分组 , 吃饭以及对 DES 外围结构的改变 。 洗手 主要代码如下 : bef洗手 M=0123456789ABCDEF01234
21、56789ABCD0123456789ABCDEF0123456789ABCD;b eef洗手 % 任意长明文 洗手 K=0123456789ABCDEF;bef%密钥 洗手 IV=11223344AABBCCDD;bef %初始向量 洗手%*明文分组 洗手 a=ceil(length(M)/16);bef %向上取整 洗手 MB=M;beef洗手 for i=1:16*a-length(M)洗手 MB=MB 0;b eef洗手 end洗手 Mi=;bef洗手 for j=1:a 洗手 Mi(j,:)=MB(16*j-15):16*j);b eef 洗手 end 洗手 M=bitxor(M,I
22、V);bef %算法核心是先按位异或再输入 DES 程序 见 mydes.m, 吃饭 demo5_CBC.m。 洗手 洗手 洗手 运行 , 吃饭得密文 : bef洗手 C_CBC =洗手 21BC605D513B38E8D8EF6671D93179070D7E6266C1FA5A5210099C143D26洗手 与明文等长 (60*4bit)。 洗手 洗手 洗手 分析你所设计的这种方法有什么优点和 /或缺点 洗手 CBC算法的优点很明显能有效地避免 ECB对明文统计特征的泄漏 , 吃饭 因为同一明文块输入 DES中的实际明文是不一样的 。 洗手 洗手 CBC算法的缺点也是很明显的 , 吃饭 由
23、于其算法结构的限制 , 吃饭 CBC不能实现并行运算 , 吃饭且误差传递效应比 ECB差 , 吃饭 一个密文块损坏 , 吃饭 会引起两个明文块损坏 。 洗手 洗手 洗手 DES弥散特性分析 洗手 选择任意 64比特明文 m, 吃饭选择 任意 56比特密钥 k进行加密 , 吃饭 并输出每一轮加密的 64比特序列 洗手 选定明文和密钥 , 吃饭依次输出每一轮加密输出的密文 : bef洗手 明文 : b eefM=0123456789ABCDEF;beef洗手 密钥 : b eefK=0123456789ABCDEF;beef洗手 每一轮的加密结果如下表所示 : b eef洗手 8 轮数 密文 轮数
24、 密文 1 F0AAF0AA5E1CEC63 2 5E1CEC6382E13C49 3 82E13C49499542F9 4 499542F90DD64AFB 5 0DD64AFB7036043B 6 7036043BF1470BC2 7 F1470BC2394C8F45 8 394C8F45348DC746 9 348DC746F37100C6 10 F37100C63C22A9CB 11 3C22A9CB0A37C369 12 0A37C3695C725FFB 13 5C725FFBF4748AD6 14 F4748AD6CC6C340E 15 CC6C340EBA88F699 16 BA
25、88F699FB21FB9C 表 1 16轮加密结果 洗手 随机改变 m中的一个比特 , 吃饭用上述密钥 k进行加密 , 吃饭 并输出每一轮加密的 64比特序列 , 吃饭 与上一步的结果进行比较 , 吃饭你发现了什么 ? bef洗手 洗手 将 明文 : b eefM=0123456789ABCDEF中第四位二进制改为 1, 吃饭 则明文变为 : b eef洗手 M=1123456789ABCDEF, 吃饭 用相同的密钥加密 , 吃饭用红字标注出 前 6轮 密 文中与之前对应相等的位数 , 吃饭结果为 : bef洗手 轮数 密文 轮数 密文 1 F0AAF0AA5E1DEC63 2 5E1DEC
26、63A3E52C89 3 A3E52C89ECE9D0E2 4 ECE9D0E269DD75C5 5 69DD75C5ABC7850D 6 ABC7850D0DC7CB61 7 0DC7CB61A75AF648 8 A75AF64855F4CFF9 9 55F4CFF92689AB42 10 2689AB4249F54614 11 49F546142DFDC287 12 2DFDC287A9245140 13 A924514098AB62F9 14 98AB62F9D4C4149D 15 D4C4149DC833086F 16 C833086FAAE41685 表 3 明文改变 1bit 后的
27、 16 轮加密结果 洗手 洗手 首先定性的 可以明显 看出 : 第一轮密文有 1bit 不相等 :洗手 16 16( C) ( D) 即 221100 1101( ) ( )洗手 第二轮密文有 7bit 不相等 :洗手 16 16( C) ( D) 即 221100 1101( ) ( )洗手 16 168 ( ) ( A) 即 1000 1010( ) ( )洗手 16 1623( ) ( ) 即 220010 0011( ) ( )洗手 16 1615( ) ( ) 即 0001 0101( ) ( )洗手 16 1632( ) ( ) 即 220011 0010( ) ( )洗手 9 1
28、6 1648( ) ( ) 即 220100 1000( ) ( )洗手 为了说明弥散特性 , 吃饭对改变后的 16轮密文与之前产生密文进行 定量 分析 ( 相 洗手 等位数检查 程序见 bitcheck.m) :洗手 轮数 相等位数 轮数 相等位数 1 63 2 57 3 42 4 31 5 30 6 34 7 35 8 32 9 31 10 22 11 24 12 30 13 25 14 34 15 31 16 25 表 4 明文改变 1bit前后的 16轮加密结果中相等比特位数 洗手 洗手 由上表 可以 看出 , 吃饭随着轮数增加 , 吃饭 初始明文 1bit的改变对于密文的弥散效应越
29、洗手 好 。 洗手理论上 , 吃饭 任意两个 64位二进制序列相等时在相等位数为 32时概率最大( 每一位取 0, 吃饭 1是等概率的 ) , 吃饭 因此在第四轮之后可认为弥散效应已经使得两组 64位二进制序列不具有相关性 。 洗手 这些结论充分说明 , 吃饭 1bit明文的改变对于密文的改变影响是很大的 。 洗手 洗手 洗手 对明文 m, 吃饭随机改变 k的一个比特 , 吃饭 并以此进行加密 , 吃饭 同样输出每一轮的 64比特序列 , 吃饭与第一步中的结果进行比较 , 吃饭 你发现了什么 ? bef洗手 洗手 将密钥 : b eefk=0123456789ABCDEF中第四位二进制 数 改
30、为 1, 吃饭 则密钥为 : b eef洗手 k=1123456789ABCDEF, 吃饭 输入 相同的 明文 , 吃饭用红字标注出前 2轮密文中与之前对应相等的位数 , 吃饭结果为 : bef洗手 轮数 密文 轮数 密文 1 F0AAF0AA5F18EC63 2 5F18EC6382A82D5D 3 82E13C49499542F9 4 499542F90DD64AFB 3 82A82D5D49A47B98 4 49A47B98B918F4AD 5 B918F4ADBEB55997 6 BEB5599751D27C9E 7 51D27C9E0D1B52DF 8 0D1B52DF1F1F546
31、0 9 1F1F54603AA16D15 10 3AA16D15DBC7BB1E 11 DBC7BB1ED19C8AD1 12 D19C8AD1CF57EA82 13 CF57EA82F6DA759D 14 F6DA759D30E6B261 15 30E6B26198CA7A01 16 98CA7A0149C4EF99 表 5 密钥改变 1bit 后的 16 轮加密结果 洗手 洗手 10 同样进行 弥散 特性的定量分析 : b eef洗手 轮数 相等位数 轮数 相等位数 1 62 2 55 3 47 4 35 5 28 6 31 7 30 8 32 9 33 10 29 11 28 12 29 13 29 14 28 15 36 16 41 表 6 密钥改变 1bit 前后的 16 轮加密结果中相等比特位数 洗手 洗手 与 a)和 b)中结果比较 , 吃饭 1bit 密钥的改变对于密文的改变影响同样是很大的 。 洗手 洗手 洗手 洗手 洗手