logo资料库

DES_加密解密算法的C++实现--实验报告.doc

第1页 / 共11页
第2页 / 共11页
第3页 / 共11页
第4页 / 共11页
第5页 / 共11页
第6页 / 共11页
第7页 / 共11页
第8页 / 共11页
资料共11页,剩余部分请下载后查看
网络与信息安全 Introduction to Network and Security ——DES 加密解密算法的 C++实现 姓 名: 学 号: 学 院: 2010 年 10 月
一、 DES 算法的实现 1.DES 简介 本世纪五十年代以来,密码学研究领域出现了最具代表性的两大成就。其中之一就是 1971 年美国学者塔奇曼(Tuchman)和麦耶(Meyer)根据信息论创始人香农(Shannon) 提出的“多重加密有效性理论”创立的,后于 1977 年由美国国家标准局颁布的数据加密标 准。 DES 密码实际上是 Lucifer 密码的进一步发展。它是一种采用传统加密方法的区组密码。 它的算法是对称的,既可用于加密又可用于解密。 美国国家标准局 1973 年开始研究除国防部外的其它部门的计算机系统的数据加密标 准,于 1973 年 5 月 15 日和 1974 年 8 月 27 日先后两次向公众发出了征求加密算法的公告。 加密算法要达到的目的通常称为 DES 密码算法要求主要为以下四点: 提供高质量的数据保护,防止数据未经授权的泄露和未被察觉的修改;具有相当高的复 杂性,使得破译的开销超过可能获得的利益,同时又要便于理解和掌握 DES 密码体制的安 全性应该不依赖于算法的保密,其安全性仅以加密密钥的保密为基础实现经济,运行有效, 并且适用于多种完全不同的应用。 1977 年 1 月,美国政府颁布:采纳 IBM 公司设计的方案作为非机密数据的正式数据加 密标准(DES 枣 Data Encryption Standard)。 目前在这里,随着三金工程尤其是金卡工程的启动,DES 算法在 POS、ATM、磁卡及 智能卡(IC 卡)、加油站、高速公路收费站等领域被广泛应用,以此来实现关键数据的保密, 如信用卡持卡人的 PIN 的加密传输,IC 卡与 POS 间的双向认证、金融交易数据包的 MAC 校验等,均用到 DES 算法。 DES 算法的入口参数有三个:Key、Data、Mode。其中 Key 为 8 个字节共 64 位,是 DES 算法的工作密钥;Data 也为 8 个字节 64 位,是要被加密或被解密的数据;Mode 为 DES 的工作方式,有两种:加密或解密。 DES 算法是这样工作的:如 Mode 为加密,则用 Key 去把数据 Data 进行加密, 生成 Data 的密码形式(64 位)作为 DES 的输出结果;如 Mode 为解密,则用 Key 去把密码形式 的数据 Data 解密,还原为 Data 的明码形式(64 位)作为 DES 的输出结果。在通信网络的 两端,双方约定一致的 Key,在通信的源点用 Key 对核心数据进行 DES 加密,然后以密码 形式在公共通信网(如电话网)中传输到通信网络的终点,数据到达目的地后,用同样的 Key 对密码数据进行解密,便再现了明码形式的核心数据。这样,便保证了核心数据(如 PIN、MAC 等)在公共通信网中传输的安全性和可靠性。 通过定期在通信网络的源端和目的端同时改用新的 Key,便能更进一步提高数据的保密 性,这正是现在金融交易网络的流行做法。 2.DES 算法详述 DES 算法把 64 位的明文输入块变为 64 位的密文输出块,它所使用的密钥也是 64 位, 其功能是把输入的 64 位数据块按位重新组合,并把输出分为 L0 、R0 两部分,每部分各长 32 位,其置换规则见下表:
58,50,12,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, 即将输入的第 58 位换到第一位,第 50 位换到第 2 位,……,依此类推,最后一位是原 来的第 7 位。 L0、R0 则是换位输出后的两部分,L0 是输出的左 32 位,R0 是右 32 位, 例:设置换前的输入值为 D1D2D3……D64,则经过初始置换后的结果为:L0=D550……D8; R0=D57D49...D7。 经过 26 次迭代运算后,得到 L16、R16,将此作为输入,进行逆置换,即得到密文输出。 逆置换正好是初始置的逆运算,例如,第 1 位经过初始置换后,处于第 40 位,而通过逆置 换,又将第 40 位换回到第 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, 放大换位表 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, 单纯换位表 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, 在 f(Ri,Ki)算法描述图中,S1,S2...S8 为选择函数,其功能是把 6bit 数据变为 4bit 数据。 下面给出选择函数 Si(i=1,2......8)的功能表: 选择函数 Si 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, 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, 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, 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, S2: S3: S4:
S5: S6: S7: S8: 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, 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, 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, 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, 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, 3.子密钥 Ki(48bit)的生成算法 初始 Key 值为 64 位,但 DES 算法规定,其中第 8、16、......64 位是奇偶校验位,不参 与 DES 运算。故 Key 实际可用位数便只有 56 位。即:经过缩小选择换位表 1 的变换后, Key 的位数由 64 位变成了 56 位,此 56 位分为 C0、D0 两部分,各 28 位,然后分别进行 第 1 次循环左移,得到 C1、D1,将 C1(28 位)、D1(28 位)合并得到 56 位,再经过缩小 选择换位 2,从而便得到了密钥 K0(48 位)。依此类推,便可得到 K1、K2、......、K15,不 过需要注意的是,16 次循环左移对应的左移位数要依据下述规则进行: 循环左移位数 1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1 以上介绍了 DES 算法的加密过程。 DES 算法的解密过程是一样的,区别仅仅在于第一 次迭代时用子密钥 K15,第二次 K14、……,最后一次用 K0,算法本身并没有任何变化。 二、 加/解密执行过程及结果 1.运行程序
2.加密过程(同时生成密文文档) 3.解密过程(同时生成明文外部文档) 三、 源代码 #include "stdafx.h" #include "DESTest.h" #include "DESTestDlg.h" #include "Encrypt.h" void CDES::deskey(unsigned char key[8], Mode md) { register int ii, j, l, m, n; unsigned char pc1m[56], pcr[56]; unsigned long kn[32];
for (j = 0; j < 56; j++) { l = pc1[j]; m = l & 07; pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1:0; } for (ii = 0; ii < 16; ii++) { if (md == DECRYPT) m = (15 - ii) << 1; else m = ii << 1; n = m + 1; kn[m] = kn[n] = 0L; for (j = 0; j < 28; j++) { l = j + totrot[ii]; if (l < 28) pcr[j] = pc1m[l]; else pcr[j] = pc1m[l - 28]; } for (j = 28; j < 56; j++) { l = j + totrot[ii]; if (l < 56) pcr[j] = pc1m[l]; else pcr[j] = pc1m[l - 28]; } for (j = 0; j < 24; j++) { if (pcr[ pc2[j] ]) kn[m] |= bigbyte[j]; if (pcr[ pc2[j+24] ])
kn[n] |= bigbyte[j]; } } cookey(kn); return; } void CDES::cookey(register unsigned long *raw1) { register unsigned long *cook, *raw0; unsigned long dough[32]; register int i; cook = dough; for (i = 0; i < 16; i++, raw1++) { raw0 = raw1++; *cook = (*raw0 & 0x00fc0000L) << 6; *cook |= (*raw0 & 0x00000fc0L) << 10; *cook |= (*raw1 & 0x00fc0000L) >> 10; *cook++ |= (*raw1 & 0x00000fc0L) >> 6; *cook = (*raw0 & 0x0003f000L) << 12; *cook |= (*raw0 & 0x0000003fL) << 16; *cook |= (*raw1 & 0x0003f000L) >> 4; *cook++ |= (*raw1 & 0x0000003fL); } usekey(dough); return; } void CDES::usekey(register unsigned long *from) { register unsigned long *to, *endp; to = KnL, endp = &KnL[32]; while (to < endp) { *to++ = *from++;
} return; } void CDES::scrunch(register unsigned char *outof, register unsigned long *into ) { *into = (*outof++ & 0xffL) << 24; *into |= (*outof++ & 0xffL) << 16; *into |= (*outof++ & 0xffL) << 8; *into++ |= (*outof++ & 0xffL); *into = (*outof++ & 0xffL) << 24; *into |= (*outof++ & 0xffL) << 16; *into |= (*outof++ & 0xffL) << 8; *into |= (*outof & 0xffL); return; } void CDES::unscrun(register unsigned long *outof, register unsigned char *into) { *into++ = (*outof >> 24) & 0xffL; *into++ = (*outof >> 16) & 0xffL; *into++ = (*outof >> 8) & 0xffL; *into++ = *outof++ & 0xffL; *into++ = (*outof >> 24) & 0xffL; *into++ = (*outof >> 16) & 0xffL; *into++ = (*outof >> 8) & 0xffL; *into = *outof & 0xffL; return; } void CDES::desfunc(register unsigned long *block, register unsigned long *keys) { register unsigned long fval, work, right, leftt; register int round; leftt = block[0]; right = block[1]; work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL; right ^= work; leftt ^= (work << 4); work = ((leftt >> 16) ^ right) & 0x0000ffffL; right ^= work;
分享到:
收藏