实验二 DES加解密算法的实现.docx
《实验二 DES加解密算法的实现.docx》由会员分享,可在线阅读,更多相关《实验二 DES加解密算法的实现.docx(22页珍藏版)》请在冰豆网上搜索。
![实验二 DES加解密算法的实现.docx](https://file1.bdocx.com/fileroot1/2023-2/28/d48ce6b5-175b-4035-9d74-53c90fda265a/d48ce6b5-175b-4035-9d74-53c90fda265a1.gif)
实验二DES加解密算法的实现
实验二:
DES的编程实现
一、实验目的
在本实验中,用VC/C/C++/Java实现DES的加解密算法。
完成实验后将能够深入理解DES加解密算法及其在VC/C/C++/Java中的实现过程。
二、实验条件
熟悉VC/C/C++/Java开发环境和有关DES算法的有关知识;一台安装有VC/C/C++/Java的计算机。
三、实验要求
本实验要求:
输入十六位十六进制明文(占64Bit)和十六位十六进制密钥(占64Bit),输出十六位十六进制密文和六十四位二进制密文。
四、实验步骤
对数据进行加密传输能有效地保证数据的机密性,DES是一个保证数据机密性的经典算法,本实验拟在VC/C/C++/Java环境中实现DES算法。
以下以VC为例:
主要内容:
在VC中建立三个文件:
控制台应用程序的入口点:
testMain.cpp,DES2加密类cpp文件zlDES2.cpp,DES2加密类头文件zlDES2.h。
操作步骤:
(1)进入VC环境;
(2)在VC环境中,执行“文件|新建”命令,在“新建”对话框中(如图1)选择“文件”页,在其左侧的列表框中选择“Win32ConsoleApplication”,在右侧的“文件名”文本框中输入新文件名“DES”,在“位置”文本框中选择项目的存储路径(比如选择“e:
\des”)。
然后单击“确定”按钮。
图1“New(新建)”对话框
(3)“Win32ConsoleApplication-步骤1共1步”对话框中,选择“一个空工程”单选按钮,单击“完成”按钮,再单击“确定”按钮。
图2“Win32ConsoleApplication-步骤1共1步”对话框
(4)在VC环境中,在其左侧的工程工作区窗口下端中选择标签“FileView”,单击“DESfiles”前面的“+”号展开。
图3标签“FileView”
(5)鼠标右击“SourceFiles”,选择“添加文件到目录”,将testMain.cpp和zlDES.cpp添加进“SourceFiles”。
同样,鼠标右击“HeaderFiles”,选择“添加文件到目录”,将zlDES.h添加进“HeaderFiles”。
结果,如图4。
图4标签“FileView”
(6)选择“组建|编译”,分别编译testMain.cpp和zlDES.cpp。
然后再选择“组建|执行”,即可看到结果。
五、编写源代码
(1)DES算法详述(主要描述算法流程)
DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是64位,整个算法的主流程图如下:
其中每一轮轮结构为:
(2)可以参照如下VC++代码。
●DES算法代码:
⏹testMain.cpp
//#include"stdafx.h"
#include"zlDES.h"
voidmain()
{
zlDES*my_des=newzlDES();
//setkey
charsz_16key[17]={"3132333435363738"};
my_des->InitializeKey(sz_16key,0);
printf("密钥:
\n3132333435363738\n\n");
//----------------------standtest------------------------------
//encrypt
charsz_16txt[17]={"3031323334353637"};
printf("明文:
\n3031323334353637\n\n");
my_des->EncryptData(sz_16txt,0);
//Ciphertextinbin
printf("Ciphertextinbin:
\n%s\n\n",my_des->GetCiphertextInBinary());
//CiphertextinHex
printf("CiphertextinHex:
\n%s\n\n",my_des->GetCiphertextInHex());
}
⏹zlDES.cpp
/*----------------------------------------------------------------
//文件名:
zlDES.cpp
//文件功能描述:
DES2加密类cpp文件
//----------------------------------------------------------------*/
//#include"stdafx.h"
#include"zlDES.h"
//permutedchoicetable(PC1)密钥置换A
conststaticcharPC1_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
};
//permutedchoicekey(PC2)密钥置换B
conststaticcharPC2_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
};
//numberleftrotationsofpc1循环左移位数
conststaticcharShift_Table[16]={
1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1
};
//initialpermutation(IP)初始置换IP
conststaticcharIP_Table[64]={
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
};
//expansionoperationmatrix(E)扩展选位表E盒
conststaticcharE_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
};
//The(in)famousS-boxesS盒
conststaticcharS_Box[8][4][16]={
//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
};
//32-bitpermutationfunctionPusedontheoutputoftheS-boxesP盒
conststaticcharP_Table[32]={
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
};
//finalpermutationIP^-1逆置换IP-1
conststaticcharIPR_Table[64]={
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
};
zlDES:
:
zlDES()
{
memset(szCiphertextRaw,0,64);
memset(szPlaintextRaw,0,64);
memset(szCiphertextInBytes,0,8);
memset(szPlaintextInBytes,0,8);
memset(szCiphertextInBinary,0,65);
memset(szCiphertextInHex,0,17);
memset(szPlaintext,0,9);
memset(szFCiphertextAnyLength,0,8192);
memset(szCiphertextInHex,0,8192);
memset(szPlaintextInHex,0,17);
memset(szPlaintextInBinary,0,65);
}
zlDES:
:
~zlDES()
{
}
voidzlDES:
:
InitializeKey(char*srcHex,unsignedintkeyN)
{
//convert8char-byteskeyto64binary-bits
charsz_64key[64]={0};
Hex2Bits(srcHex,sz_64key,64);
//PC1
charsz_56key[56]={0};
for(intk=0;k<56;k++)
{
sz_56key[k]=sz_64key[PC1_Table[k]-1];
}
CreateSubKey(sz_56key,keyN);
}
voidzlDES:
:
CreateSubKey(char*sz_56key,unsignedintkeyN)
{
charszTmpL[28]={0};
charszTmpR[28]={0};
charszCi[28]={0};
charszDi[28]={0};
memcpy(szTmpL,sz_56key,28);
memcpy(szTmpR,sz_56key+28,28);
for(inti=0;i<16;i++)
{
//shifttoleft
//Left28bits
memcpy(szCi,szTmpL+Shift_Table[i],28-Shift_Table[i]);
memcpy(szCi+28-Shift_Table[i],szTmpL,Shift_Table[i]);
//Right28bits
memcpy(szDi,szTmpR+Shift_Table[i],28-Shift_Table[i]);
memcpy(szDi+28-Shift_Table[i],szTmpR,Shift_Table[i]);
//permutedchoice48bitskey
charszTmp56[56]={0};
memcpy(szTmp56,szCi,28);
memcpy(szTmp56+28,szDi,28);
for(intj=0;j<48;j++)
{
szSubKeys[keyN][i][j]=szTmp56[PC2_Table[j]-1];
}
//EvaluatenewszTmpLandszTmpR
memcpy(szTmpL,szCi,28);
memcpy(szTmpR,szDi,28);
}
}
voidzlDES:
:
EncryptData(char*_srcHex,unsignedintkeyN)
{
charszSrcBits[64]={0};
charsz_IP[64]={0};
charsz_Li[32]={0};
charsz_Ri[32]={0};
charsz_Final64[64]={0};
Hex2Bits(_srcHex,szSrcBits,64);
printf("二进制明文为:
\n%s\n\n",szSrcBits);
//IP
InitialPermuteData(szSrcBits,sz_IP);
memcpy(sz_Li,sz_IP,32);
memcpy(sz_Ri,sz_IP+32,32);
for(inti=0;i<16;i++)
{
FunctionF(sz_Li,sz_Ri,i,keyN);
}
//soD=LR
memcpy(sz_Final64,sz_Ri,32);
memcpy(sz_Final64+32,sz_Li,32);
//~IP
for(intj=0;j<64;j++)
{
szCiphertextRaw[j]=sz_Final64[IPR_Table[j]-1];
}
Bits2Hex(szCiphertextInHex,szCiphertextRaw,64);
}
voidzlDES:
:
DecryptData(char*_srcHex,unsignedintkeyN)
{
charszSrcBits[64]={0};
charsz_IP[64]={0};
charsz_Li[32]={0};
charsz_Ri[32]={0};
charsz_Final64[64]={0};
Hex2Bits(_srcHex,szSrcBits,64);
//IP---returnissz_IP
InitialPermuteData(szSrcBits,sz_IP);
//dividethe64bitsdatatotwoparts
memcpy(sz_Ri,sz_IP,32);//exchangeLtoR
memcpy(sz_Li,sz_IP+32,32);//exchangeRtoL
//16roundsFandxorandexchange
for(inti=0;i<16;i++)
{
FunctionF(sz_Ri,sz_Li,15-i,keyN);
}
memcpy(sz_Final64,sz_Li,32);
memcpy(sz_Final64+32,sz_Ri,32);
//~IP
for(intj=0;j<64;j++)
{
szPlaintextRaw[j]=sz_Final64[IPR_Table[j]-1];
}
Bits2Hex(szPlaintextInHex,szPlaintextRaw,64);
}
voidzlDES:
:
FunctionF(char*sz_Li,char*sz_Ri,unsignedintiKey,unsignedintkeyN)
{
charsz_48R[48]={0};
charsz_xor48[48]={0};
charsz_P32[32]={0};
charsz_Rii[32]={0};
charsz_Key[48]={0};
chars_Compress32[32]={0};
memcpy(sz_Key,szSubKeys[keyN][iKey],48);
ExpansionR(sz_Ri,sz_48R);
XOR(sz_48R,sz_Key,48,sz_xor48);
CompressFuncS(sz_xor48,s_Compress32);
PermutationP(s_Compress32,sz_P32);
XOR(sz_P32,sz_Li,32,sz_Rii);
memcpy(sz_Li,sz_Ri,32);
memcpy(sz_Ri,sz_Rii,32);
}
voidzlDES:
:
InitialPermuteData(char*_src,char*_dst)
{
//IP
for(inti=0;i<64;i++)
{
_dst[i]=_src[IP_Table[i]-1];
}
}
voidzlDES:
:
ExpansionR(char*_src,char*_dst)
{
for(inti=0;i<48;i++)
{
_dst[i]=_src[E_Table[i]-1];
}
}
voidzlDES:
:
XOR(char*szParam1,char*szParam2,unsignedintuiParamLength,char*szReturnValueBuffer)
{
for(unsignedinti=0;i{
szReturnValueBuffer[i]=szParam1[i]^szParam2[i];
}
}
voidzlDES:
:
CompressFuncS(char*_src48,char*_dst32)
{
charbTemp[8][6]={0};
chardstBits[4]={0};
for(inti=0;i<8;i++)
{
memcpy(bTemp[i],_src48+i*6,6);
intiX