实验二DES算法.docx
《实验二DES算法.docx》由会员分享,可在线阅读,更多相关《实验二DES算法.docx(14页珍藏版)》请在冰豆网上搜索。
实验二DES算法
实验二DES算法
【实验目的】
●理解对称加密算法的原理和特点
●理解DES算法的加密原理
【实验人数】
每组2人
【系统环境】
Windows
【网络环境】
交换网络结构
【实验工具】
CIS工具箱。
【实验原理】
见《原理篇》实验一|练习二|任务一。
【实验步骤】
本练习将主机A和B作为一组,主机C和D作为一组,主机E和F作为一组。
首先使用“快照X”恢复Windows系统环境。
一.DES加密解密
(1)本机进入“工具箱”|“加密解密”|“DES加密算法”|“加密/解密”页签,在明文输入区输入明文_computer___________。
(2)在密钥窗口输入8(64位)个字符的密钥k,密钥k=_abcdefg_____.单击“加密”按钮,将密文345F4AEFC63A0E59导出到DES文件夹(D:
\Work\Eneryption\DES)中,通告同组主机获取密文,并将密钥k告诉同组主机。
(3)单击“导入”按钮,从同组主机的DES共享文件夹中将密文导入,然后在密钥窗口输入被同组主机通告的密钥k,点击“解密”按钮进行DES解密。
(4)将破解后的明文与同组主机记录的明文比较。
二.DES算法
进入“工具箱”|“加密解密”|“DES加密算法”|“演示”页签。
输入64位明文与密钥,执行加密操作,查看各演示模块。
在DES加密算法中,S-代替是最重要的部分,与其它代替比较起来,它提供了更好的安全性。
因此,掌握S-盒代替是掌握DES算法的关键。
由于加密软件与加密硬件本身的特点有很在的差异,所以在实现DES加密算法时,加密软件与加密硬件采用的不同的策略。
加密硬件一般采取标准折DES加密算法实现,高加密率是加密硬件的主要特点。
加密软件为了提高加密的效率,要遵守以下原则:
●展开加密循环与函数;
●避免内部循环中使用条件转移指令;
●变量长度与CPU内部寄存器长度相同;限制变量数量;
●避免使用耗时的指令。
所以,加密软件在实现DES算法时,一般都对算法加以修改,以提高加密效率。
在工具箱的DES算法软件实现中,我们使用了一种修改的DES算法,它的S-盒代替的输入为64位,而不是48位,这样可以在32位计算机很好的执行。
S-盒代替的转换表如下:
(图表)
表6-1-3DES算法S盒置换表
S1
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
0
14
4
13
1
2
15
11
8
3
10
6
12
5
9
0
7
1
0
15
7
4
14
2
13
1
10
6
12
11
9
5
3
8
2
4
1
14
8
13
6
2
11
15
12
9
7
3
10
5
0
3
15
12
8
2
4
9
1
7
5
11
3
14
10
0
6
13
S2
0
15
1
8
14
6
11
3
4
9
7
2
13
12
0
5
10
1
3
13
4
7
15
2
8
14
12
0
1
10
6
9
11
5
2
0
14
7
11
10
4
13
1
5
8
12
6
9
3
2
15
3
13
8
10
1
3
15
4
2
11
6
7
12
0
5
14
9
S3
0
10
0
9
14
6
3
15
5
1
13
12
7
11
4
2
8
1
13
7
0
9
3
4
6
10
2
8
5
14
12
11
15
1
2
13
6
4
9
8
15
3
0
11
1
2
12
5
10
14
7
3
1
10
13
0
6
9
8
7
4
15
14
3
11
5
2
12
S4
0
7
13
14
3
0
6
9
10
1
2
8
5
11
12
4
15
1
13
8
11
5
6
15
0
3
4
7
2
12
1
10
14
9
2
10
6
9
0
12
11
7
13
15
1
3
14
5
2
8
4
3
3
15
0
6
10
1
13
8
9
4
5
11
12
7
2
14
S5
0
2
12
4
1
7
10
11
6
8
5
3
15
13
0
14
9
1
14
11
2
12
4
7
13
1
5
0
15
10
3
9
8
6
2
4
2
1
11
10
13
7
8
15
9
12
5
6
3
0
14
3
11
8
12
7
1
14
2
13
6
15
0
9
10
4
5
3
S6
0
12
1
10
15
9
2
6
8
0
13
3
4
14
7
5
11
1
10
15
4
2
7
12
9
5
6
1
13
14
0
11
3
8
2
9
14
15
5
2
8
12
3
7
0
4
10
1
13
11
6
3
4
3
2
12
9
5
15
10
11
14
1
7
6
0
8
13
S7
0
4
11
2
14
15
0
8
13
3
12
9
7
5
10
6
1
1
13
0
11
7
4
9
1
10
14
3
5
12
2
15
8
6
2
1
4
11
13
12
3
7
14
10
15
6
8
0
5
9
2
3
6
11
13
8
1
4
10
7
9
5
0
15
14
2
3
12
S8
0
13
2
8
4
6
15
11
1
10
9
3
14
5
0
12
7
1
1
15
13
8
10
3
7
4
12
5
6
11
0
14
9
2
2
7
11
4
1
9
12
14
2
0
6
10
13
15
3
5
8
3
2
1
14
7
4
10
8
13
15
12
9
0
3
5
6
11
置换表包了8个S盒SO-S7,每个S盒中有64个元素。
每个S盒由左至右,由上至下读取,64个元素由0开始编号。
使用第1个S盒的第0个元素,SBox[7][9]=0x10040000,代表第7个S盒的第9个元素。
S盒代替具体第9个元素如下:
(1)输入分成两部分,每部分32位,分别记为S0和S1。
(2)将32位S0的第25至30位写入变量S01;
将32位S0的第17至22位写入变量S02;
将32位S0的第9至14位写入变量S03;
将32位S0的第1至6位写入变量S04。
(3)将32位S1的第25至30位写入变量S11;
将32位S1的第17至22位写入变量S12;
将32位S1的第9至14位写入变量S13;
将32位S1的第1至6位写入变量S14;
(4)查找置换表,将SBox[0][S01]、SBox[1][S11]、SBox[2][S02]、SBox[3][S12]、SBox[4][S03]、SBox[5][S13]、SBox[6][S04]、SBox[7][S14]进行或运算,得到的结果即为S盒的输出结果。
例如,64位输入为0x743DED2D02D3B264,那么S盒代替的过程如下:
(1)64位输入分为两部分,S0=0x743DED2D,S1=0x02D3B264。
(2)S01=0x34=52(10)
S02=0x3D=61(10)
S03=0x2D=45(10)
S04=0x2D=45(10)
(3)S11=0x02=2(10)
S12=0x13=19(10)
S13=0x32=50(10)
S14=0x24=36(10)
(4)SBox[0][52]=0x01000004
SBox[1][2]=0x00008000
SBox[2][61]=0x0000008
SBox[3][19]=0x00802001
SBox[4][45]=0x00000100
SBox[5][50]=0x00000000
SBox[6][45]=0x00000802
SBox[7][36]=0x00000040
将以上数据进行或操作,得到结果0x0180A94F就是S盒的输出。
了解了以上的S盒代替方法后,请写出输入为0x843DED9302D#B98B的S盒代替过程数据。
(1)S0=0x843DED93,S1=0x02D3B98B。
(2)S01=___0x04___=_4__10)
S02=___0x3D__=___61__10)
S03=___0x3D___=___61__(10)
S04=___0x13_=___19__(10)
(3)S11=___0x02___=___2___(10)
S12=___0x13___=___19___(10)
S13=___0x39___=__57____(10)
S14=___0x0B__=__11____(10)
三.源码应用(选做)
设计DES加密工具,利用DES加密算法对文件进行加密。
单击工具栏“VC6”按钮,启动VC++6.0。
选择“File”|“OpenWorkspace…”加载工程文件“C:
\JLCSS\Projects\Encrypt\DES.dsw”。
基于此工程进行程序设计。
Main代码如下:
(更改了其它函数的部分代码)
/******************************************************************************/
//工程:
DES
//功能:
DES加、解密文件
//作者:
jlcss|ExpNIS
/******************************************************************************/
#include
#include
#include
#include
#include"des.h"
#defineDECRYPT_FILE"DES加密密文.txt"
#defineENCRYPT_FILE"DES解密明文.txt"
//!
约束文件最大2M
#defineMAX_FILE1024*1024*2
/******************************************************************************/
//名称:
usage
//功能:
帮助信息
//参数:
应用程序名称
//返回:
提示信息
/******************************************************************************/
voidUsage(constchar*appname)
{
printf("\n\tusage:
des-e明文文件64位密钥\n");
printf("\tusage:
des-d密文文件64位密钥\n");
}
/******************************************************************************/
//名称:
FileIn
//功能:
读取磁盘文件到内存
//参数:
strFile:
文件名称;inBuff:
指向文件内容缓冲区
//返回:
实际读取内容大小(字节)
/******************************************************************************/
intFileIn(constchar*strFile,unsignedchar*&inBuff)
{
intiFileLen=0;
//!
打开密文文件
CFilefile(strFile,CFile:
:
modeRead);
iFileLen=(int)file.GetLength();
if(iFileLen>MAX_FILE)
{
printf("文件长度不能大于%dM,!
\n",MAX_FILE/(1024*1024));
gotoout;
}
inBuff=newunsignedchar[iFileLen+1];
if(!
inBuff)
gotoout;
file.Read(inBuff,iFileLen);
file.Close();
inBuff[iFileLen]=0;
out:
returniFileLen;
}
/******************************************************************************/
//名称:
FileOut
//功能:
加/解密结果输出到当前目录磁盘文件中
//参数:
strOut指向输出字符缓冲区,输出大小len,strFile为输出文件
//返回:
无
/******************************************************************************/
voidFileOut(constvoid*strOut,constchar*strFile)
{
//!
输出到文件
intlen=64;
CFileoutfile(strFile,CFile:
:
modeCreate|CFile:
:
modeWrite);
outfile.Write(strOut,len);
outfile.Close();
}
/******************************************************************************/
//名称:
CheckParse
//功能:
校验应用程序入口参数
//参数:
argc等于main主函数argc参数,argv指向main主函数argv参数
//返回:
若参数合法返回true,否则返回false
//备注:
简单的入口参数校验
/******************************************************************************/
boolCheckParse(intargc,char**argv)
{
if((argc!
=4)||
(argv[1][1]!
='e'&&argv[1][1]!
='d')||
(strlen(argv[3])>(64/8)))
{
Usage(argv[0]);
returnfalse;
}
returntrue;
}
/**********************************************************************************/
/**************为了使程序代码变的显得简洁易懂,特编写下边函数**********************/
/**********************************************************************************/
//用于清除回车键缓存的影响
voidsafe_flush(FILE*fp)
{
intch;
while((ch=fgetc(fp))!
=EOF&&ch!
='\n');
}
voidEncryption()
{
//k1:
密钥低位;k2:
密钥高位;c1:
32位密文(左);c2:
32密文(右);m1:
明文(左);m2:
明文(右);
intk1=0;
printf("请输入密钥低位:
");
scanf("%d",&k1);
intk2=0;
printf("请输入密钥高位:
");
scanf("%d",&k1);
intm1=0;
printf("请输入明文(左):
");
scanf("%d",&m1);
safe_flush(stdin);
intm2=0;
printf("请输入明文(右):
");
scanf("%u",&m2);
safe_flush(stdin);
unsignedc1=0;
unsignedc2=0;
charstrOut1[50];
charstrFile1[50];
printf("请输入你要加密后的文件路径:
");
gets(strFile1);
des_encrypt(k1,k2,m1,m2,c1,c2);
FileOut(strOut1,strFile1);
}
voidDecryption()
{
//k1:
密钥低位;k2:
密钥高位;c1:
32位密文(左);c2:
32密文(右);m1:
明文(左);m2:
明文(右);
intk1=0;
printf("请输入密钥低位:
");
scanf("%d",&k1);
intk2=0;
printf("请输入密钥高位:
");
scanf("%d",&k1);
intc1=0;
printf("请输入密文(左):
");
scanf("%d",&c1);
safe_flush(stdin);
intc2=0;
printf("请输入密文(右):
");
scanf("%u",&c2);
safe_flush(stdin);
unsignedm1=0;
unsignedm2=0;
charstrOut[80];
charstrFile[80];
printf("请输入你要解密后的文件路径:
");
gets(strFile);
des_decrypt(k1,k2,c1,c2,m1,m2);
FileOut(strOut,strFile);
}
intmenu()
{
printf("\n\n\t******************************************************\n\n");
printf("\t加密请输入:
1解密请输入:
2退出请输入:
3\n\n");
printf("\t******************************************************\n");
inttemp;
scanf("%d",&temp);
safe_flush(stdin);
if(temp==3)
{
printf("感谢使用加密解密程序!
\n");
return0;
}
elseif(temp!
=3)
{
if(temp==1||temp==2)
{
switch(temp)
{
case1:
Encryption();
menu();
break;
case2:
Decryption();
menu();
break;
default:
break;
}
}
else
{
printf("请输入一个正确的选择!
");
}
}
else
{
return0;
}
return0;
}
//!
程序主函数(UseMFCinaSharedDLL)
intmain(intargc,char**argv)
{
//!
在此处填写代码......
if(!
CheckParse(argc,argv))
{
menu();
}
returntrue;
}
运行结果如下:
(1)加密如下:
生成文件如下:
(2)解密如下:
生成文件如下: