DES加密与解密C实现+实验报告

更新时间:2024-01-24 08:58:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

工程实践报告

DES加密与解密算法

课 程 名 称: 工程实践 学 生 姓 名: xxxx 学 生 学 号: xxxx 专 业 班 级: xxxx 任 课 教 师: xxxx 论文提交日期: xxxx

1 / 31

DES加密与解密算法

摘 要

本世纪五十年代以来,密码学研究领域出现了最具代表性的两大 成就。其中之一就是1971年美国学者塔奇曼(Tuchman)和麦耶(Meyer)根据信息论创始人香农(Shannon)提出的“多重加密有效性理论”创立的,后于1977年由美国国家标准局颁布的数据加密标准。

DES密码实际上是Lucifer密码的进一步发展。它是一种采用传统加密方法的区组密码。它的算法是对称的,既可用于加密又可用于解密。

1977年1月,美国政府颁布:采纳IBM公司设计的方案作为非机密数据的正式数据加密标准(DES枣Data Encryption Standard)。

目前在这里,随着三金工程尤其是金卡工程的启动,DES算法在POS、ATM、磁卡及智能卡(IC卡)、加油站、高速公路收费站等领域被广泛应用,以此来实现关键数据的保密,如信用卡持卡人的PIN的加密传输,IC卡与POS间的双向认证、金融交易数据包的MAC校验等,均用到DES算法。

关键词:DES算法,加密,解密

2 / 31

Abstract

This century since fifty time, cryptography research field is the most representative of the two Achievement. One was the 1971 USA scholar Tuchman (Tuchman) and Meyer (Meyer) based on information theory founder Shannon (Shannon) proposed \theory\promulgated by the America data encryption standard.The DES password is actually a further development of the Lucifer password. It is a traditional encryption method of block cipher. The algorithm is

symmetric, which can be used for encryption and decryption can be used.

In 1977 January, the government promulgated American: adopted IBM design as a non official data confidential data encryption standard (DES - Data Encryption Standard).

At present here, along with three gold project especially golden card project startup, DES algorithm in POS, ATM, magnetic card and intelligent card (IC card), gas station, highway toll station and other fields are widely used, so as to realize the security of key data encryption transmission, such as credit card holders PIN, IC card and POS mutual authentication, financial transaction data package of MAC check and so on, are used in DES algorithm.

Keywords: DES algorithm, encryption, decryption

3 / 31

目录

1

需求分析 ................................................................................................................................... 5 1.1背景分析............................................................................................................................. 5 1.2需求分析............................................................................................................................. 5 2 相关技术介绍 ........................................................................................................................... 6

1.2 DES简介 ............................................................................................................................. 6 2.2 DES算法详述 ..................................................................................................................... 7 2.3 C语言简介及特点 .............................................................................................................. 9 3 总体设计流程图:如图a ...................................................................................................... 10

3.1 DES加密算法流程图:如图b......................................................................................... 11 3.2 DES算法的子密钥的生成过程:如图c ............................................................................ 12 4 详细设计:................................................................................................................................. 13

4.1菜单选择: ....................................................................................................................... 13 4.2DES加密算法: ................................................................................................................ 14 4.3DES解密算法: ................................................................................................................ 20 5过程中遇到的问题及心得体会: .............................................................................................. 21 参考文献......................................................................................................................................... 21

4 / 31

1 需求分析

1.1背景分析

DES密码实际上是Lucifer密码的进一步发展。它是一种采用传统加密方法的区组密码。它的算法是对称的,既可用于加密又可用于解密。 美国国家标准局1973年开始研究除国防部外的其它部门的计算机系统的数据加密标准,于1973年5月15日和1974年8月27日先后两次向公众发出了征求加密算法的公告。加密算法要达到的目的通常称为DES密码算法要求主要为以下四点:提供高质量的数据保护,防止数据未经授权的泄露和未被察觉的修改;具有相当高的复杂性,使得破译的开销超过可能获得的利益,同时又要便于理解和掌握DES密码体制的安全性应该不依赖于算法的保密,其安全性仅以加密密钥的保密为基础实现经济,运行有效,并且适用于多种完全不同的应用。

1.2需求分析

项目开发要求:

随着三金工程尤其是金卡工程的启动,DES算法在POS、ATM、磁卡及智

能卡(IC卡)、加油站、高速公路收费站等领域被广泛应用,以此来实现关键数

据的保密,如信用卡持卡人的PIN的加密传输,IC卡与POS间的双向认证、金

融交易数据包的MAC校验等,均用到DES算法。

在通信网络的两端,双方约定一致的Key,在通信的源点用Key对核心数

据进行DES加密,然后以密码形式在公共通信网(如电话网)中传输到通信网

络的终点,数据到达目的地后,用同样的Key对密码数据进行解密,便再现了

5 / 31

明码形式的核心数据。这样,便保证了核心数据(如PIN、MAC等)在公共通

信网中传输的安全性和可靠性。

通过定期在通信网络的源端和目的端同时改用新的Key,便能更进一步提高数据

的保密性,这正是现在金融交易网络的流行做法。

2 相关技术介绍

1.2 DES简介

本世纪五十年代以来,密码学研究领域出现了最具代表性的两大成就。其中之一就是1971年美国学者塔奇曼(Tuchman)和麦耶(Meyer)根据信息论创始人香农(Shannon)提出的“多重加密有效性理论”创立的,后于1977年由美国国家标准局颁布的数据加密标准。 DES密码实际上是Lucifer密码的进一步发展。它是一种采用传统加密方法的区组密码。它的算法是对称的,既可用于加密又可用于解密。 美国国家标准局1973年开始研究除国防部外的其它部门的计算机系统的数据加密标准,于1973年5月15日和1974年8月27日先后两次向公众发出了征求加密算法的公告。加密算法要达到的目的通常称为DES密码算法要求主要为以下四点: 提供高质量的数据保护,防止数据未经授权的泄露和未被察觉的修改;具有相当高的复杂性,使得破译的开销超过可能获得的利益,同时又要便于理解和掌握DES密码体制的安全性应该不依赖于算法的保密,其安全性仅以加密密钥的保密为基础实现经济,运行有效,并且适用于多种完全不同的应用。

6 / 31

2.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

7 / 31

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, 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, 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, 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, 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, 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, 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, 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,

子密钥Ki(48bit)的生成算法

初始Key值为64位,但DES算法规定,其中第8、16、......64位是奇偶校

8 / 31

验位,不参与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,算法本身并没有任何变化。

2.3 C语言简介及特点

C语言是一种计算机程序设计语言。它既有高级语言的特点,又具有汇编语言的特点。它可以作为系统设计语言, 编写工作系统应用程序,也可以作为应用程序设计语言,编写不依赖计算机硬件的应用程序。因此,它的应用范围广泛。

主要有以下特点:

C语言在很多方面都可以用,不仅仅是在软件开发上,各类科研都是需要用到C语言的。具体应用比如我是学硬件的,单片机以及嵌入式系统都可以用C来开发。C 语言发展如此迅速, 而且成为最受欢迎的语言之一,主要因为它具有强大的功能。许多著名的系统软件, 如DBASE Ⅲ PLUS、DBASE Ⅳ 都是由C 语言编写的。用C语言加上一些汇编语言子程序, 就更能显示C 语言的优势了, 像PC- DOS 、WORDSTAR等就是用这种方法编写的。

C是中级语言它把高级语言的基本结构和语句与低级语言的实用性结合起来。C语言可以象汇编语言一样对位、字节和地址进行操作, 而这三者是计算机最基本的工作单元。

C是结构式语言结构式语言的显著特点是代码及数据的分隔化,即程序的各个部分除了必要的信息交流外彼此独立。这种结构化方式 可使程序层次清晰,

9 / 31

便于使用、维护以及调试。C 语言是以函数形式提供给用户的,这些函数可方便的调用, 并具有多种循环、条件语 句控制程序流向, 从而使程序完全结构化。 C语言功能齐全C 语言具有各种各样的数据类型, 并引入了指针概念,可使程序效率更高。另外C 语言也具有强大的图形功能, 支持 多种显示器和驱动器。而且计算功能、逻辑判断功能也比较强大,可以实现决策目的编游戏,编3D游戏,做数据库,做联众世界,做 聊天室,做 PHOTOSHOP做FLASH,做3DMAX。 C语言适用范围大C 语言还有一个突出的优点就是适合于多种操作系统, 如DOS、UNIX,也适用于多种机型。

3 总体设计流程图:如图1

图 1(总体设计流程图)

10 / 31

3.1 DES加密算法流程图:如图2

明文(m1m2 ...m64)64比特 密钥K0(k1k2 ...k64)64比特初始置换IP32比特32比特选择置换1(PC-1)56比特28比特28比特子密钥计算第1轮L0(左半部)R0(右半部)C0左移位D0左移位D1+32比特L1=R0F48比特32比特R1=L0⊕F(R0,K1)K1(子密钥)48比特选择置换2(PC-2)C156比特左移位左移位第2轮+32比特L2=R1F48比特32比特R2=L1⊕F(R1,K2)K2(子密钥)48比特选择置换2(PC-2)C256比特D2第3轮|第15轮左移位左移位+32比特L15=R14F48比特32比特R15=L14⊕F(R14,K15)48比特48比特K15(子密钥)选择置换2(PC-2)C1556比特D15左移位48比特左移位D16K16(子密钥)第16轮+32比特L16=L15⊕F(R15,K16)F32比特R16=R15选择置换2(PC-2)C1656比特64比特逆初始置换IP-164比特密文(c1c2 ...c64)图 2(DES加密算法流程图)

11 / 31

3.2 DES算法的子密钥的生成过程:如图3

密钥K0(k1k2 ...k64)选择置换1(PC-1)56比特28比特28比特子密钥计算C0左移位48比特D0左移位D1K1(子密钥)选择置换2(PC-2)C156比特左移位左移位K2(子密钥)48比特选择置换2(PC-2)C256比特D2左移位左移位48比特K15(子密钥)选择置换2(PC-2)C1556比特D15左移位48比特左移位D16K16(子密钥)选择置换2(PC-2)

C1656比特 12 / 31

图 3(DES算法的子密钥的生成过程:)

4 详细设计:

4.1菜单选择:

用户首先进入菜单选择页面, 根据自己需求选择对应的加密或者解密选项 如图4-1:

图 4-1(菜单选择)

13 / 31

4.2DES加密算法:

用户先输入想要加密的明文和秘钥,然后输出二进制明文和秘钥,以及第一轮经过E盒S 盒P盒的扩展输出,和第二轮经过E盒S 盒P盒的扩展输出。如图4-2:

图 4-2(加密明文)

功能函数:(1)字符数组转换二进制数组

static void Chartobit(const char input[],int output[],int bits) { int i,j; for(j=0;j<8;j++) {

for(i=0;i<8;i++)

14 / 31

{

output[7*(j+1)-i+j]=(input[j]>>i)&1; } }

} 函数功能:完成字符到二进制转换

函数参数说明:const char input[ ]:需要转换的字符数组 int output[ ]:转换之后存放二进制的数组 int bits:需要转换的二进制位数

(2)二进制数组转换为字符数组

static void BitToChar(const int intput[],char output[],int bits) {

int i,j; for(j=0;j<8;j++) {

for(i=0;i<8;i++)

{output[j]=output[j]*2+intput[i+8*j];} }} 函数功能:完成二进制到字符数组转换 函数参数说明:

const int intput[ ] :需要转换二进制数组 char output[ ]:转换之后存放字符

15 / 31

int bits:需要转换二进制位数 (3)Xor异或操作

static void Xor(int *INA,int *INB,int len)//异或操作 {

int i;

for(i=0;i

*(INA+i)=*(INA+i)^*(INB+i); }

} 函数功能:完成异或运算,结果存放在异或操作InA中 函数参数说明:

int * InA:异或操作数1 int * inB:异或操作数 2 int len:需要异或的位数长度 (4)IP初始置换

static void IP(const int input[64],int output[64],int table[64]);

函数功能:IP初始置换 函数参数说明:

int input[]:IP置换输入的64比特数据 int output[]:IP置换输出64比特数据 int table[]:IP置换表

16 / 31

(5)E盒扩展

static void E(const int input[32],int output[48],int table[48]);

函数功能:E盒扩展 函数参数说明:

int input[]:E置换输入的32比特数据 int output[]:E置换输出48比特数据 int table[]:E盒扩展表 (6)P盒替代

static void P(const int input[32],int output[32],int table[32]);

函数功能:P盒替代 函数参数说明:

int input[]:P盒输入的32比特数据 int output[]:P盒输出32比特数据 int table[]:P盒替代表 (7)IP逆置换

static void IP_In(const int input[64],int output[64],int table[64]);

函数功能:IP逆置换 函数参数说明:

int input[]:IP逆置输入64比特

17 / 31

int output[]:IP逆置换输出64比特 int table[]:IP逆置换表 (8)PC-1置换选择

static void PC_1(const int input[64],int output[56],int table[56]);

函数功能:密钥扩展中PC_1置换选择 函数参数说明:

int input[]:PC-1置换选择输入64比特 int output[]:PC-1置换选择输出56比特 int table[]:PC-1置换选择表 (9)PC-2置换选择

static void PC_2(const int input[56],int output[48],int table[48]);

函数功能:密钥扩展中PC_2置换选择 函数参数说明:

int input[]:PC-2置换选择输入56比特 int output[]:PC-2置换选择输出48比特 int table[]:PC-2置换选择表 (10)S盒压缩

static void PC_2(const int input[48],int output[32],int table[8][4][16]);

函数功能:密钥扩展中PC_2置换选择

18 / 31

函数参数说明:

int input[]:S盒压缩的输入48比特 int output[]:S盒压缩输出32比特

int table[8][4][16]:8个S盒,每个S盒4行16列 (11)F轮函数

static void F_func(const int input[32],int output[32],const int subkey[48]);

函数功能:完成DES算法轮变换(调用之前E盒扩展,S盒压缩,P置换,Xor异或函数) 函数参数说明:

const int input[32]:F轮函数的输入32比特 int output[32]:F轮变换输出32比特 const int subkey[48]:F轮变换需要的子密钥 (12)生成子密钥中循环左移函数

static void RotateL(const int input[28],int output[28], int loop);

函数功能:完成子密钥扩展的循环左移功能 const int input[28]:循环左移输入28比特 int output[28]:循环左移输出28比特 int loop:每轮子密钥需要循环左移的位数 (13) 子密钥生成

static void subKey_fun(const int input[64],int

19 / 31

Subkey[16][48]);

函数功能:完成16轮子密钥生成 函数参数说明:

const int input[64]:输入的64比特密钥

然后输出二进制密文:如图4-3

图 4-3(输出密文)

4.3DES解密算法:

用户输入想要解密的二进制密文和秘钥,然后输出明文:如图4-4

图 4-4(DES解密)

20 / 31

5过程中遇到的问题及心得体会:

在刚开始做工程的时候无从下手,不知道代码该从哪里写起,其中二进制转换和那几个明文秘钥扩展都是一些难点。在经过老师的讲解后解决了一些问题,但是在代码的细节方面只有靠自己不断修改,不断查询资料,借鉴前辈的经验,最终得以完善,写出了这个程序!

在经过自己努力完成代码之后,我对密码学算法有了更加深刻的理解,自己也在实践过程中学到了很多知识!

参考文献

[1] 谭浩强 《C程序设计(第二版)》 清华大学出版社 1999 [2] 张仕斌 《应用密码学》 2009

源代码:

#include #include #include

int IP_Table[64] = { //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 };

int E_Table[48] = { //扩展矩阵 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 };

int P_Table[32] = { // 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};

int IPR_Table[64] = { //逆IP置换矩阵 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,

21 / 31

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 };

int PC1_Table[56] = { //密钥第一次置换矩阵 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 };

int PC2_Table[48] = { // 密钥第二次置换矩阵 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 }; int S_Box[8][4][16] = { //8个S盒 三维数组 // 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, // 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, // 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, // 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, // 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, // 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, // S7

22 / 31

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, // 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

}; const static int LOOP_Table[16] = { 1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1}; static void Chartobit(const char input[],int output[],int bits)//把CHAR转换为INT { int i,j;

for(j=0;j<8;j++) {

for(i=0;i<8;i++) {

output[7*(j+1)-i+j]=(input[j]>>i)&1; } } }

static void BitToChar(const int intput[],char output[],int bits)//把INT转换为CHAR {

int i,j;

for(j=0;j<8;j++) {

for(i=0;i<8;i++) {

output[j]=output[j]*2+intput[i+8*j]; } } }

static void Xor(int *INA,int *INB,int len)//异或操作 {

int i;

for(i=0;i

*(INA+i)=*(INA+i)^*(INB+i); } }

static void IP(const int input[64],int output[64],int table[64])//初始IP置换 {

23 / 31

int i;

for(i=0;i<64;i++) {

output[i]=input[table[i]-1];//减1操作不可少!! } }

static void E(const int input[32],int output[48],int table[48])//E扩展 {

int i;

for(i=0;i<48;i++) {

output[i]=input[table[i]-1]; } }

static void P(const int input[32],int output[32],int table[32])//P置换 {

int i;

for(i=0;i<32;i++) {

output[i]=input[table[i]-1]; } }

static void IP_In(const int input[64],int output[64],int table[64])//逆IP {

int i;

for(i=0;i<64;i++) {

output[i]=input[table[i]-1]; } }

static void PC_1(const int input[64],int output[56],int table[56])//PC_1 {

int i;

for(i=0;i<56;i++) {

output[i]=input[table[i]-1]; } }

static void PC_2(const int input[56],int output[48],int table[48])//PC_2 {

int i;

for(i=0;i<48;i++) {

output[i]=input[table[i]-1];

24 / 31

} }

static void S(const int input[48],int output[32],int table[8][4][16])//S盒压缩 {

int i=0; int j=0; int INT[8]; for(;i<48;i=i+6) {

INT[j]=table[j][(input[i]*2)+(input[i+5])][(input[i+1]*8)+(input[i+2]*4)+(input[i+3]*2)+(input[i+4])]; j++; }

for(j=0;j<8;j++) {

for(i=0;i<4;i++) {

output[3*(j+1)+j-i]=(INT[j]>>i)&1; } } }

static void F_func(int input[32],int output[32], int subkey[48]) { int len=48; int temp1[48]={0};int temp2[48]={0}; E(input,temp1,E_Table); Xor(temp1,subkey,len); S(temp1,temp2,S_Box); P(temp2,output,P_Table); }

static void F_func1(int input[32],int output[32], int subkey[48]) { int i; int len=48; int temp1[48]={0};int temp2[32]={0}; E(input,temp1,E_Table); printf(\经过e盒扩展后的输出:\\n\ for(i=0;i<48;i++) { printf(\

25 / 31

}

if(i%6==5) printf(\ \}

Xor(temp1,subkey,len);

printf(\经过s盒压缩后的输出:\\n\S(temp1,temp2,S_Box); for(i=0;i<32;i++) { printf(\ if(i%4==3) printf(\ \}

P(temp2,output,P_Table);

printf(\经过p盒置换后的输出:\\n\for(i=0;i<32;i++) { printf(\ if(i%4==3) printf(\ \}

printf(\

static void RotateL(const int input[28],int output[28], int loop)//秘钥循环左移 {

int i;

int len = 28 ; for(i=0;i

output[i]=input[(i+loop)%len]; } }

static void subKey_fun(const int input[64],int Subkey[16][48])//子密钥生成 { int loop=0; int i,j; int c[28],d[28]; int pc_1[56]={0},pc_2[16][56]={0}; int r_c[16][28]={0},r_d[16][28]={0}; PC_1(input,pc_1,PC1_Table); for(i=0;i<28;i++) {

c[i]=pc_1[i];

26 / 31

d[i]=pc_1[i+28]; } for(i=1;i<17;i++) { if(i==1||i==2||i==9||i==16) { loop=loop+1; RotateL(c,r_c[i-1],loop); RotateL(d,r_d[i-1],loop); } else { loop=loop+2; RotateL(c,r_c[i-1],loop); RotateL(d,r_d[i-1],loop); } } for(i=0;i<16;i++) {

for(j=0;j<28;j++) {

pc_2[i][j]=r_c[i][j];

pc_2[i][j+28]=r_d[i][j]; } PC_2(pc_2[i],Subkey[i],PC2_Table); } }

static void DES_Efun(char input[8],char key_in[8],int output[64]) {

int Ip[64]={0};//存储初始置换后的矩阵 int output_1[64]={0}; int subkeys[16][48]; int chartobit[64]={0}; int key[64];

int l[17][32],r[17][32];

Chartobit(input,chartobit,8);//正确,转换为64个二进制数的操作正确! IP(chartobit,Ip,IP_Table);//正确,IP初始置换! Chartobit(key_in,key,8);//正确!

27 / 31

subKey_fun(key,subkeys);//正确! for(int i=0;i<32;i++) {

l[0][i]=Ip[i]; r[0][i]=Ip[32+i]; }

for(int j=1;j<16;j++)//前15轮的操作 {

for(int k=0;k<32;k++) {

l[j][k]=r[j-1][k]; } if(j==1||j==2) { printf(\第%d轮\ fflush(stdin); F_func1(r[j-1],r[j],subkeys[j-1]); } else F_func(r[j-1],r[j],subkeys[j-1]); Xor(r[j],l[j-1],32); }

int t=0;

for(t=0;t<32;t++)//最后一轮的操作 {

r[16][t]=r[15][t]; }

F_func(r[15],l[16],subkeys[15]); Xor(l[16],l[15],32); for(t=0;t<32;t++) {

output_1[t]=l[16][t]; output_1[32+t]=r[16][t]; }

IP_In(output_1,output,IPR_Table); }

static void DES_Dfun(int input[64],char key_in[8],char output[8]) {

int Ip[64]={0};//存储初始置换后的矩阵 int output_1[64]={0}; int output_2[64]={0}; int subkeys[16][48]; int chartobit[64]={0};

28 / 31

int key[64];

int l[17][32],r[17][32];

IP(input,Ip,IP_Table);//正确,IP初始置换! Chartobit(key_in,key,8);//正确! subKey_fun(key,subkeys);//正确! for(int i=0;i<32;i++) {

l[0][i]=Ip[i]; r[0][i]=Ip[32+i]; }

for(int j=1;j<16;j++)//前15轮的操作 {

for(int k=0;k<32;k++) {

l[j][k]=r[j-1][k]; }

F_func(r[j-1],r[j],subkeys[16-j]); Xor(r[j],l[j-1],32); }

int t=0;

for(t=0;t<32;t++)//最后一轮的操作 {

r[16][t]=r[15][t]; }

F_func(r[15],l[16],subkeys[0]); Xor(l[16],l[15],32); for(t=0;t<32;t++) {

output_1[t]=l[16][t]; output_1[32+t]=r[16][t]; }

IP_In(output_1,output_2,IPR_Table); BitToChar(output_2,output,8); }

int main() {

int a; int i; int output[64]={0}; int MIW2[64]={0}; char MIN[9]={0}; char MI[9]={0}; do

29 / 31

{

printf(\ E S 算 法****************\\n\ printf(\加 密 明 文****************\\n\ printf(\解 密 密 文****************\\n\ printf(\退 出****************\\n\ printf(\请选择:______\ scanf(\ system(\ switch(a) { case 1: { fflush(stdin); printf(\请输入明文\\n\ gets(MIN); printf(\请输入秘钥\\n\ gets(MI); printf(\明文转化为二进制为:\\n\

Chartobit(MIN,output,8); for(i=0;i<64;i++) { printf(\ if(i%8==7) printf(\ \

}

printf(\秘文转化为二进制为:\\n\ Chartobit(MI,output,8); for(i=0;i<64;i++) { printf(\ if(i%8==7) printf(\ \ } DES_Efun(MIN,MI,output);

printf(\密文如下:\\n\ for(int i=0;i<64;i++) { printf(\ if(i%8==7) printf(\ }

30 / 31

break; } system(\ case 2: { fflush(stdin);

printf(\请输入密文:\\n\ for(i=0;i<64;i++) { scanf(\ }

printf(\请输入秘钥\\n\ fflush(stdin); gets(MI); DES_Dfun(MIW2,MI,MIN); printf(\明文如下:\\n\ for(i=0;i<8;i++) {

printf(\和%s的区别 } printf(\ break; } system(\ default: break; } }

while(a!=3); return 0; }

31 / 31

break; } system(\ case 2: { fflush(stdin);

printf(\请输入密文:\\n\ for(i=0;i<64;i++) { scanf(\ }

printf(\请输入秘钥\\n\ fflush(stdin); gets(MI); DES_Dfun(MIW2,MI,MIN); printf(\明文如下:\\n\ for(i=0;i<8;i++) {

printf(\和%s的区别 } printf(\ break; } system(\ default: break; } }

while(a!=3); return 0; }

31 / 31

本文来源:https://www.bwwdw.com/article/94uo.html

Top