对称密码算法DES.docx
《对称密码算法DES.docx》由会员分享,可在线阅读,更多相关《对称密码算法DES.docx(14页珍藏版)》请在冰豆网上搜索。
对称密码算法DES
实验二对称密码算法DES
一、实验目的:
1.通过实验,让学生掌握典型的加密算法的软件实现方法,对加密原理有更深入的认识。
二、实验要求
学生按照以下各个实验步骤的要求,通过查阅相关的资料,经过调查分析,掌握计算机对称加密算法DES实现等,培养学生分析问题和解决问题的能力。
学生按照实验步骤的要求完成并提交分析论文。
三、实验学时
4学时
四、实验环境
硬件设备:
计算机、局域网
系统软件:
Windows系统
支撑软件:
C或VisualC++等编译环境
五、实验内容
根据教材并上网查找资料,完成计算机对称加密算法DES实现,具体要求如下:
1.DES加解密软件调试通过
2.利用DES对某一数据文件进行单次加密和解密操作。
3.界面简洁、友好,便于操作。
验收要求:
验机通过,并提交实验报告,实验报告包括下列若干项:
1、DES的加密、解密算法流程框图
2、DES加密系统关键模块的实现(加必要代码注释)
3、DES加密前后的明文与密文
数据加密标准DES
DES使用一个56位的密钥以及附加的8位奇偶校验位,产生最大64位的分组大
小。
这是一个迭代的分组密码,使用称为Feistel的技术,其中将加密的文本块分成两
半。
使用子密钥对其中一半应用循环功能,然后将输出与另一半进行“异或”运算;接
着交换这两半,这一过程会继续下去,但最后一个循环不交换。
DES使用16个循环。
攻击DES的主要形式被称为蛮力的或彻底密钥搜索,即重复尝试各种密钥直到有一
个符合为止。
如果DES使用56位的密钥,则可能的密钥数量是2的56次方个。
随
着计算机系统能力的不断发展,DES的安全性比它刚出现时会弱得多,然而从非关键性
质的实际出发,仍可以认为它是足够的。
不过,DES现在仅用于旧系统的鉴定,而更多
地选择新的加密标准—高级加密标准(AdvancedEncryptionStandard,AES)。
DES的常见变体是三重DES,使用168位的密钥对资料进行三次加密的一种机制;
它通常(但非始终)提供极其强大的安全性。
如果三个56位的子元素都相同,则三重
DES向后兼容DES。
I
由于DES是加(解)密64位明(密)文,即为8个字节(8*8=64),可以据此初步判断这是
分组加密,加密的过程中会有16次循环与密钥置换过程,据此可以判断有可能是用到DES
密码算法,更精确的判断还得必须懂得一点DES的加密过程。
DES算法的安全性
一.安全性比较高的一种算法,目前只有一种方法可以破解该算法,那就是穷举法.
二.采用64位密钥技术,实际只有56位有效,8位用来校验的.譬如,有这样的一台PC机
器,它能每秒计算一百万次,那么256位空间它要穷举的时间为2285年.所以这种算法还是
比较安全的一种算法.
TripleDES。
该算法被用来解决使用DES技术的56位时密钥日益减弱的强度,其
方法是:
使用两个独立密钥对明文运行DES算法三次,从而得到112位有效密钥强度
。
TripleDES有时称为DESede(表示加密、解密和加密这三个阶段)。
功能:
实现DES加密算法的加密解密功能
des算法的实现代码
能够实现56位或56*n密钥的des算法,可以通过该程序提供的接口进行数据的加密,保证数据在传送过程的安全性
DES的加密、解密算法流程框图
C语言DES源码:
#include
#include
#include
#include
#include
#include"des.h"
#defineSUCCESS0
#defineFAIL-1
#defineREADFILESIZE512
#defineWZ_COMMEND_NUM4
#defineWZUSEHELPNUM19
#defineDESONE1
#defineDESTHREE2
#defineDESMULTI3
INT8*WZ_Commend_Help[]=
{
"基于DES的加密解密工具v1.0 ",/*0*/
"追求卓越,勇于创新 ",
"----著者:
吴真--- ",
" "
};
INT8*WZ_USE_HELP[]={
"输入5+n个参数:
",
"\t1.可执行文件名*.exe",
"\t2.操作类型1:
一层加密;2:
一层解密;",
"\t\t13:
N层单密钥加密;23:
N层单密钥解密;",
"\t\t39:
N层多密钥加密;49:
N层多密钥解密",
"\t3.读出数据的文件名*.txt",
"\t4.写入数据的文件名*.txt",
"\t5.密钥(8字节例如:
wuzhen12)",
"\t[6].N层单密钥的层数或者...二层加密|解密密钥",
"\t[7].三层加密|解密密钥",
"\t[8]....",
"\t[N].N层加密|解密密钥",
"\t例1:
des11.txt2.txt12345678",
"\t :
des22.txt3.txt12345678",
"\t例2:
des131.txt2.txttiantian5",
"\t :
des232.txt3.txttiantian5",
"\t例3:
des391.txt2.txt12345678tiantiangaoxinma",
"\t :
des492.txt3.txt12345678tiantiangaoxinma",
"******************************"
};
INT32hextofile(ULONG8*buf,FILE*writefile,ULONG32length);/*以16进制写入文件*/
INT32encodehex(ULONG8*tobuf,ULONG8*frombuf,ULONG32len);/*16进制解码*/
INT32file_enc(FILE*readfile,FILE*writefile,
ULONG8*key,ULONG32keynum,
ULONG8**superkey,ULONG32n_superkey,
ULONG8flag);
INT32file_dec(FILE*readfile,FILE*writefile,
ULONG8*key,ULONG32keynum,
ULONG8**superkey,ULONG32n_superkey,
ULONG8flag);
voidwz_print_help();
INT32main(INT32argc,INT8*argv[])
{
INT8*FILENAME1,*FILENAME2;
FILE*fp,*fp2;
ULONG8*key;
ULONG8**superkey;/*n层加密解密密钥*/
ULONG8n_superkey;
ULONG32num;
if(argc>=5&&(atoi(argv[1])==39||atoi(argv[1])==49))
{
n_superkey=argc-4;
superkey=(INT8**)calloc(1,n_superkey*sizeof(void*));
for(num=0;num {
superkey[num]=argv[4+num];
}
}
elseif(argc==6&&(atoi(argv[1])==13||atoi(argv[1])==23)&&(atoi(argv[5]))>0)
{
}
elseif(argc==5&&(atoi(argv[1])==1||atoi(argv[1])==2))
{
}
else
{
wz_print_help();
returnFAIL;
}
FILENAME1=argv[2];
FILENAME2=argv[3];
if((fp=fopen(FILENAME1,"rb"))==NULL ||(fp2=fopen(FILENAME2,"wb"))==NULL)
{
printf("Can'topenfile\n");
returnFAIL;
}
key=argv[4];
switch(atoi(argv[1]))
{
case1:
/*加密*/
file_enc(fp,fp2,key,0,NULL,0,DESONE);
printf("\n\tDES一层加密完毕,密文存于%s文件\n",FILENAME2);
break;
case2:
file_dec(fp,fp2,key,0,NULL,0,DESONE);
printf("\n\tDES一层解密完毕,密文存于%s文件\n",FILENAME2);
break;
case13:
file_enc(fp,fp2,key,atoi(argv[5]),NULL,0,DESTHREE);
printf("\n\tDES%u层单密钥加密完毕,密文存于%s文件\n",atoi(argv[5]),FILENAME2);
break;
case23:
file_dec(fp,fp2,key,atoi(argv[5]),NULL,0,DESTHREE);
printf("\n\tDES%u层单密钥解密完毕,密文存于%s文件\n",atoi(argv[5]),FILENAME2);
break;
case39:
file_enc(fp,fp2,NULL,0,superkey,n_superkey,DESMULTI);
printf("\n\tDES多密钥加密完毕,密文存于%s文件\n",FILENAME2);
free(superkey);
superkey=NULL;
break;
case49:
file_dec(fp,fp2,NULL,0,superkey,n_superkey,DESMULTI);
printf("\n\tDES多密钥加密完毕,密文存于%s文件\n",FILENAME2);
free(superkey);
superkey=NULL;
break;
default:
printf("请选择是加密|解密plesechooseencrypt|deencrypt\n");
break;
}
fclose(fp);
fclose(fp2);
returnSUCCESS;
}
voidwz_print_help()
{
INT32i;
printf("\t");
for( i=0;i<22;i++)
{
printf("%c",5);
}
printf("\n");
for(i=0;i {
printf("\t%c\t%s%c\n",5,WZ_Commend_Help[i],5);
}
printf("\t");
for( i=0;i<22;i++)
{
printf("%c",5);
}
printf("\n");
for(i=0;i {
printf("\t%s\n",WZ_USE_HELP[i]);
}
return;
}
INT32file_enc(FILE*readfile,FILE*writefile,
ULONG8*key,ULONG32keynum,
ULONG8**superkey,ULONG32n_superkey,
ULONG8flag)
{
INT32filelen=0,readlen=0,writelen=0;
ULONG32totalfilelen=0;/*统计实际的文件的长度*/
ULONG8readbuf[READFILESIZE]={0};
filelen=fread(readbuf,sizeof(INT8),READFILESIZE,readfile);
while(filelen==READFILESIZE)
{
totalfilelen+=READFILESIZE;
switch(flag)
{
caseDESONE:
des(readbuf,key,READFILESIZE);
break;
caseDESTHREE:
des3(readbuf,key,keynum,READFILESIZE);
break;
caseDESMULTI:
desN(readbuf,superkey,n_superkey,READFILESIZE);
break;
}
hextofile(readbuf,writefile,READFILESIZE);/*以16进制形式写入文件*/
memset(readbuf,0,READFILESIZE);
filelen=fread(readbuf,sizeof(INT8),READFILESIZE,readfile);
}
/*这是从文件中读出的最后一批数据,长度可能会等于0,所以要先判断*/
if(filelen>0)
{
/*如果从文件中读出的长度不等于0,那么肯定有8个字节以上的空间
文件长度存在最后8个字节中*/
totalfilelen+=filelen;
memcpy(&readbuf[READFILESIZE-8],(ULONG8*)&totalfilelen,4);
switch(flag)
{
caseDESONE:
des(readbuf,key,READFILESIZE);
break;
caseDESTHREE:
des3(readbuf,key,keynum,READFILESIZE);
break;
caseDESMULTI:
desN(readbuf,superkey,n_superkey,READFILESIZE);
break;
}
hextofile(readbuf,writefile,READFILESIZE);/*以16进制形式写入文件*/
memset(readbuf,0,READFILESIZE);
}
else/*filelen==0*/
{
memcpy(&readbuf[0],(ULONG8*)&totalfilelen,4);
switch(flag)
{
caseDESONE:
des(readbuf,key,8);
break;
caseDESTHREE:
des3(readbuf,key,keynum,8);
break;
caseDESMULTI:
desN(readbuf,superkey,n_superkey,8);
break;
}
hextofile(readbuf,writefile,8);/*以16进制形式写入文件*/
}
returnSUCCESS;
}
INT32file_dec(FILE*readfile,FILE*writefile,
ULONG8*key,ULONG32keynum,
ULONG8**superkey,ULONG32n_superkey,
ULONG8flag)
{
INT32filelen=0,readlen=0,writelen=0;
ULONG32totalfilelen=0;/*统计实际的文件的长度*/
INT32num=0;
ULONG8readbuf[READFILESIZE]={0};
ULONG8sendbuf[READFILESIZE*2]={0};
fseek(readfile,-16,SEEK_END);/*最后16个字节的表示文件长度的空间*/
filelen=fread(sendbuf,sizeof(INT8),16,readfile);
encodehex(readbuf,sendbuf,8);
switch(flag)
{
caseDESONE:
Ddes(readbuf,key,8);
break;
caseDESTHREE:
Ddes3(readbuf,key,keynum,8);
break;
caseDESMULTI:
DdesN(readbuf,superkey,n_superkey,8);
break;
}
/*解密*/
memcpy((ULONG8*)&totalfilelen,&readbuf[0],4);/*得到文件总长*/
memset(readbuf,0,8);
memset(sendbuf,0,16);
num=totalfilelen/READFILESIZE;/*有几个READFILESIZE组*/
totalfilelen%=READFILESIZE;
fseek(readfile,0,SEEK_SET);/*跳到文件头*/
while(num--)
{
filelen=fread(sendbuf,sizeof(INT8),READFILESIZE*2,readfile);
encodehex(readbuf,sendbuf,READFILESIZE);
switch(flag)
{
caseDESONE:
Ddes(readbuf,key,READFILESIZE);
break;
caseDESTHREE:
Ddes3(readbuf,key,keynum,READFILESIZE);
break;
caseDESMULTI:
DdesN(readbuf,superkey,n_superkey,READFILESIZE);
break;
}
writelen=fwrite(readbuf,sizeof(INT8),READFILESIZE,writefile);
memset(readbuf,0,READFILESIZE);
memset(sendbuf,0,READFILESIZE*2);
}
if(totalfilelen>0)/*最后一块有多余的元素*/
{
filelen=fread(sendbuf,sizeof(INT8),READFILESIZE*2,readfile);
encodehex(readbuf,sendbuf,READFILESIZE);
switch(flag)
{
caseDESONE:
Ddes(readbuf,key,READFILESIZE);
break;
caseDESTHREE:
Ddes3(readbuf,key,keynum,READFILESIZE);
break;
caseDESMULTI:
DdesN(readbuf,superkey,n_superkey,READFILESIZE);
break;
}
writelen=fwrite(readbuf,sizeof(INT8),totalfilelen,writefile);
memset(readbuf,0,READFILESIZE);
memset(sendbuf,0,READFILESIZE*2);
}
returnSUCCESS;
}
INT32hextofile(ULONG8*buf,FILE*writefile,ULONG32length)
{
ULONG32writelen=0;
/*以16进制形式写入文件*/
while(writelen {
if(buf[writelen]==0)
{
fprintf(writefile,"%x",0);
fprintf(writefile,"%x",0);
}
elseif(buf[writelen]<0x10)
{
fprintf(writefile,"%x",0);
fprintf(writefile,"%x",buf[writelen]);
}
else
{
fprintf(writefile,"%x",buf[writelen]);
}
writelen++;
}
returnSUCCESS;
}
INT32encodehex(ULONG8*tobuf,ULONG8*frombuf,ULONG32len)
{
ULONG8*readfirst=frombuf;
ULONG8*r