C语言DES加密算法.docx

上传人:b****3 文档编号:5355679 上传时间:2022-12-15 格式:DOCX 页数:16 大小:166.19KB
下载 相关 举报
C语言DES加密算法.docx_第1页
第1页 / 共16页
C语言DES加密算法.docx_第2页
第2页 / 共16页
C语言DES加密算法.docx_第3页
第3页 / 共16页
C语言DES加密算法.docx_第4页
第4页 / 共16页
C语言DES加密算法.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

C语言DES加密算法.docx

《C语言DES加密算法.docx》由会员分享,可在线阅读,更多相关《C语言DES加密算法.docx(16页珍藏版)》请在冰豆网上搜索。

C语言DES加密算法.docx

C语言DES加密算法

云南大学软件学院

SchoolofSoftware,YunnanUniversity

 

成绩

学期:

2011秋季学期

课程名称:

密码技术

任课教师:

学生姓名:

学号:

实验项目:

实验二DES加密算法

联系电话:

电子邮件:

完成提交时间:

年月日

密码技术实验报告

实验项目:

实验二,第2题实现DES对任意文件的加解密

实验要求

(内容)

实现DES对任意文件的加解密,利用控制台对所有文件(中英文文本、符号甚至任意的文件)的加解密。

加解密形式如下:

cipher-e/-dkeyinputfileoutputfile

说明:

对于加密来说,输入文件名就是明文文件,对于解密来说,输入文件名就是密文文件,注意文件读取方式和控制文件结束

控制台编程:

intmain(intargc,char*argv[])

实验环境

操作系统:

win7

编译环境:

MicrosoftVisualStudio2010

实现功能

本次实验达到了题目的要求:

实现了用DES实现控制台对任意文件的加解密,用键盘接收明文(密文)文件路径和密钥,然后再输入需要保存的密文(明文)文件路径,然后就可以把加解密后得到的密明文文件保存该路径下。

程序主要采取对数据的位操作的形式,把明密文文件中的内容以字节为单位读取,每次读取8个byte共65bits,然后使用标准DES的算法依次对读取的64bits明密文进出加解密处理。

主函数的操作也充分体现了程序的可操作性和健壮性,能够让用户自己选择相应的操作,比如加密、解密以及对程序的一些基本情况说明。

但是对文件的路径的输入有比较严格的格式约束。

如:

盘符名:

\\文件名.txt格式错误则会导致文件打开失败,不能进行加解密操作。

数据结构

本次实验的程序较为复杂,涉及对位的操作。

实验过程中用到的主要数据结构为数组和文件型指针,在实验中我定义了2个文件型指针FILE*fp1,*fp2,其中一个指向明文文件,一个指向密文文件。

另外还定义了多个字符数组,如charPlainfpath[260]声明字符数组存储明文文件的文件路径,charCipherfpath[260]声明字符数组存储密文文件的文件路径,charkey[100]声明字符数组存储密钥。

对于读取出来的数据均以unsignedchar的类型进行处理。

这个程序的实现比较复杂的是对位的操作,主要包括取位值、移位和异或等,在对位的操作还主要用到了memcpy函数对unsignedchar类型的字符串进行复制,除此之外没有采用更多的数据结构。

程序流程

程序模块结构图:

开始start

选择操作

 

解密函数

退出程序

加密函数

 

用户输入明密文文件路径和密钥

 

明(密)文文件是否能打开

 

退出程序

对打开的文件进行操作,每次取出长度为8个byte的明密文。

将8byte的明密文和密钥转换为64bits

明密文进行初始置换IP

密钥进行置换选择1

循环左移和置换选择2产生子密钥

分成左右两部分进入F函数

右半部分在F函数里依次进行扩展置换、与子密钥异或、S盒置换和P置换

经F函数处理的与左半部分异或后成右半部分,原先的右半部分作为左半部分

 

32bits对换,然后进行逆初始置换

 

将结果由64bits转换成8byte,然后写入文件保存

 

main()

函数的调用关系:

 

Encrypt()

Decrypt()

Explain()

Block_Decrypt()

Block_Encrypt()

 

L_Shift()

R_Shift()

BToC()

CToB()

F_function()

 

函数的接口:

voidEncrypt(char*Plainfpath,char*Cipherfpath,unsignedchar*Keys);//加密函数

voidDecrypt(char*Cipherfpath,char*Plainfpath,unsignedchar*Keys);//解密函数

voidBlock_Encrypt(unsignedchar*Plain,unsignedchar*Cipher,unsignedchar*Key);//分组加密函数

voidBlock_Decrypt(unsignedchar*Cipher,unsignedchar*Plain,unsignedchar*Key);//分组加密函数

voidCToB(unsignedchar*C_String,unsignedchar*B_String);//将字符类型转换成二进制类型的函数

voidBToC(unsignedchar*B_String,unsignedchar*C_String);//将二进制类型转换成字符类型的函数

voidL_Shift(unsignedchar*PC_Key,intcount);//加密中循环左移函数

voidR_Shift(unsignedchar*PC_Key,intcount);//解密中循环右移函数

voidF_function(unsignedchar*R_String,unsignedchar*S_Key);//F函数

voidExplain();//程序说明函数

代码与代码分析

主要函数的接口、调用与被调用函数、所实现的功能和实现的主要思路:

intmain(charch):

Function:

为用户提供基本操作,调用加密解密函数。

Calls:

Encrypt(),Decrypt()和Explain()。

CalledBy:

未被其它函数调用。

Input(type)字符型(char)。

Output(type):

无,只是输出“”中的字符串。

Return(type):

整型

Others:

Bug:

测试尚未发现

voidEncrypt(char*Plainfpath,char*Cipherfpath,unsignedchar*Keys)

Function:

实现的功能是:

接收明文文件路径和密钥,并打开文件,然后根据对文件的

操作依次从文件中以二进制方式读取字符,并使用DES算法加密,然后将处理过

的二进制字符写入到密文文件中。

实现的主要思路:

首先调用fopen()函数打开文件,对打开的文件进行操作,

调用fseek()函数定位读写指针函数fseek,将文件的读写指针移到文件结束位置,调

用ftell()函数返回fp1指向的文件中的读写指针当前位置,即文件的长度,再调用

rewind()函数将文件读写指针移到文件开始位置。

调用fgetc()从fp1所指向的明文

文件中依次以二进制的方式读取字符,然后调用Block_Encrypt进行加密,并

把结果写入密文文件保存。

此外对于不足8byte的分组将填充*并作标记以便

进行加密。

Calls:

Block_Encrypt()

CalledBy:

main()

Input(type)char类型的数组

Output(type):

char类型的数组

Return(type):

无返回值的类型。

Others:

Bug:

测试中尚未发现

voidDecrypt(char*Cipherfpath,char*Plainfpath,unsignedchar*Keys)

Function:

实现的功能是:

接收密文文件路径和密钥,并打开文件,然后根据对文件的

操作依次从文件中以二进制方式读取字符,并使用DES算法解密,然后将处理过

的二进制字符写入到明文文件中。

实现的主要思路:

首先调用fopen()函数打开文件,对打开的文件进行操作,

调用fseek()函数定位读写指针函数fseek,将文件的读写指针移到文件结束位置,调

用ftell()函数返回fp1指向的文件中的读写指针当前位置,即文件的长度,再调用

rewind()函数将文件读写指针移到文件开始位置。

调用fgetc()从fp1所指向的密文

文件中依次以二进制的方式读取字符,然后调用Block_Decrypt()进行解密,并

把结果写入明文文件保存。

此外对于之前有填充标记的分组在解密后应该删除

填充进去的*。

Calls:

Block_Decrypt()

CalledBy:

main()

Input(type)char类型的数组

Output(type):

char类型的数组

Return(type):

无返回值的类型。

Others:

Bug:

测试中尚未发现

voidBlock_Encrypt(unsignedchar*Plain,unsignedchar*Cipher,unsignedchar*Key)

Function:

实现的功能是:

接收8个byte的明文,并使用DES算法加密,得到8个byte

的密文。

实现的主要思路:

首先调用CToB()将二进制明文字符与密钥字符转换成

64bits,再依次对64bit的明文进行初始置换、16轮F_function()函数的处理、32bit

对换和逆初始置换得到64bit密文。

在F函数中使用的子密钥是将输入的密钥进

行置换选择1的处理然后在每轮加密中再对密钥进行循环左移和置换选择2的处

理后得到子密钥。

最后调用BToC()将64bit转换成8个byte的密文。

Calls:

CToB(),F_function(),L_Shift和BToC()。

CalledBy:

Encrypt()

Input(type)unsignedchar类型的数组

Output(type):

unsignedchar类型的数组

Return(type):

无返回值的类型。

Others:

Bug:

测试中尚未发现

voidBlock_Decrypt(unsignedchar*Cipher,unsignedchar*Plain,unsignedchar*Key);

Function:

实现的功能是:

接收8个byte的密文,并使用DES算法加密,得到8个byte

的明文。

实现的主要思路:

首先调用CToB()将二进制密文字符与密钥字符转换成

64bits,再依次对64bit的密文进行初始置换、16轮F_function()函数的处理、32bit

对换和逆初始置换得到64bit明文。

在F函数中使用的子密钥是将输入的密钥进

行置换选择1的处理然后在每轮解密中再对密钥进行循环右移和置换选择2的处

理后得到子密钥。

最后调用BToC()将64bit转换成8个byte的明文。

Calls:

CToB(),F_function(),R_Shift和BToC()。

CalledBy:

Decrypt()

Input(type)unsignedchar类型的数组

Output(type):

unsignedchar类型的数组

Return(type):

无返回值的类型。

Others:

Bug:

测试中尚未发现

voidCToB(unsignedchar*C_String,unsignedchar*B_String)

Function:

将字符(8byte)转换成二进制位值(64bit)

实现的主要思路:

利用表达式*(B_String+(8*i+7-j))=(C_String[i]>>j)&1

对C_String[i]中的字符进行移位操作取出每个位的值赋值给B_String。

Calls:

CalledBy:

Block_Encrypt和Block_Decrypt()

Input(type)unsignedchar类型的数组

Output(type):

unsignedchar类型的数组

Return(type):

Others:

Bug:

测试尚未发现

voidBToC(unsignedchar*B_String,unsignedchar*C_String)

Function:

将二进制位值(64bit)转换成字符(8byte)

实现的主要思路:

利用表达式*(C_String+i)=*(C_String+i)|(*(B_String+

(8*i+j))<<(7-j))将B_String中的每8个值进行移位的等操作构成C_String中的

一个值。

Calls:

CalledBy:

Block_Encrypt和Block_Decrypt()

Input(type)unsignedchar类型的数组

Output(type):

unsignedchar类型的数组

Return(type):

Others:

Bug:

测试尚未发现

voidL_Shift(unsignedchar*PC_Key,intcount)

Function:

将56bit的密钥分两部分左移count位

实现的主要思路:

利用memcpy()对密钥进行复制操作,具体步骤如下:

memcpy(temp,PC_Key,count);

memcpy(PC_Key,PC_Key+count,28-count);

memcpy(PC_Key+(28-count),temp,count);//前28位左移count位

memcpy(temp,PC_Key+28,count);

memcpy(PC_Key+28,PC_Key+(28+count),28-count);

memcpy(PC_Key+(56-count),temp,count);//后28位左移count位

Calls:

CalledBy:

Block_Encrypt和Block_Decrypt()

Input(type)unsignedchar类型的数组和int型的值

Output(type):

unsignedchar类型的数组

Return(type):

Others:

Bug:

测试尚未发现

voidR_Shift(unsignedchar*PC_Key,intcount)

Function:

将56bit的密钥分两部分右移count位

实现的主要思路:

利用memcpy()对密钥进行复制操作,具体步骤如下:

memcpy(temp,PC_Key+(28-count),count);

memcpy(PC_Key+count,PC_Key,28-count);

memcpy(PC_Key,temp,count);//前28位右移count位

memcpy(temp,PC_Key+(56-count),count);

memcpy(PC_Key+(28+count),PC_Key+28,28-count);

memcpy(PC_Key+28,temp,count);//后28位右移count位

Calls:

CalledBy:

Block_Encrypt和Block_Decrypt()

Input(type)unsignedchar类型的数组和int型的值

Output(type):

unsignedchar类型的数组

Return(type):

Others:

Bug:

测试尚未发现

voidF_function(unsignedchar*R_String,unsignedchar*S_Key)

Function:

对明密文的右半部分F函数进行处理,包括扩展置换、与子密钥异或、S

盒置换和P置换

实现的主要思路:

扩展置换利用E表将32位扩展到48位,然后与48位的子

密钥进行异或;S盒置换将48位的明密文分成8个6位块分别对应8个S盒替换

表,然后每个6位块中的第1和6位作为行号,其余的作为列号,在S盒替换表

中找到对应的值,这样将48位压缩到32位,然后再根据置换函数P进行置换操

作。

Calls:

CalledBy:

Block_Encrypt和Block_Decrypt()

Input(type)unsignedchar类型的数组

Output(type):

unsignedchar类型的数组

Return(type):

Others:

Bug:

测试尚未发现

实验输入(可加截图):

实验输入:

先选择加密,然后输入明文文件路径:

c:

\\123.jpg密钥:

yqg需要保存的密文文件路径:

c:

\\12301.jpg

先选择解密,然后输入密文文件路径:

c:

\\12301.jpg密钥:

yqg需要保存的明文文件路径:

c:

\\12302.jpg

结果输出(可加截图):

先选择加密,然后输入明文文件路径:

c:

\\123.jpg密钥:

yqg结果保存了密文文件,路径:

c:

\\12301.jpg但是加密后格式无法打开。

先选择解密,然后输入密文文件路径:

c:

\\12301.jpg密钥:

yqg需要保存的明文文件路径:

c:

\\12302.jpg

实验小结

这次的实验比上次的难度增加了许多,尤其是涉及到取位值以及对位的操作,这个实验花费了很长的时间才基本完成实验的要求,实现了使用DES对任意文件进行加密解密。

通过本次实验,我加深了对DES加密解密算法的的了解,另一方面,我进一步熟悉了C语言的语法知识,主要就是对二进制文件的一些打开关闭和读写操作,另外还有对位的操作等知识。

在这次的实验中对文件打开的方式依然以二进制方式打开,但是因为本次实验中是每次对8个byte的字符进行加密解密操作,因此在读文件的时候使用了fread()函数,每次从文件中读取8个byte的字符,然后用fwrite()函数将8个byte的字符写入文件,另外我把实验中的大部分数组都声明为unsignedchar类型,在对字符串进行复制操作时调用了memcpy函数对字符串进行操作将更为方便。

这次的实验虽然基本完成了实验题目的要求,但是由于个人能力的原因,算法设计得有点复杂,加密解密需要花费太长的时间,因此还需要再改进。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 幼儿教育 > 幼儿读物

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1