DES算法实验报告
一、实验内容:
用C++实现DES算法,用于数据的加密和解密。
二、实验思路
1、如何将8位明文转换为64位明文
2、如何实现初始置换(IP)和初始逆置换(IP1)
3、如何进行各种迭代
4、如何产生密钥
三、实验步骤
1、定义已知数组: //IP置换数组,1-64
int IP[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};
//IP逆置换数组,1-64
int IP1[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};
//扩展变换E,48个元素,1-32
int Ex[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};
//F函数里面的P置换数组,1-32
int P_F[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};
//第1个S-box结构 ,0-15
const static int S[8][4][16]={
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,
//第2个S-box结构
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,
//第3个S-box结构
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,
//第4个S-box结构
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,
//第5个S-box结构
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,
//第6个S-box结构
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,
//第7个S-box结构
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,
//第8个S-box结构
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};
//密钥K1置换 ,进1-64(有效是56),出56
int K1[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};
//密钥K2压缩置换 ,进1-56,出48
int K2[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};
源程序:
#include<iostream>
#include<string>
using namespace std;
typedef char ElemType;
//IP置换数组,1-64
int IP[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};
//IP逆置换数组,1-64
int IP1[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};
//扩展变换E,48个元素,1-32
int Ex[48]={32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, //子密钥循环左移,16次 int shift[16]= {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2,1};
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};
//F函数里面的P置换数组,1-32
int P_F[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};
//第1个S-box结构 ,0-15
const static int S[8][4][16]={
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,
//第2个S-box结构
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,
//第3个S-box结构
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,
//第4个S-box结构
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,
//第5个S-box结构
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,
//第6个S-box结构
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,
//第7个S-box结构
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,
//第8个S-box结构
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};
//密钥K1置换 ,进1-64(有效是56),出56
int K1[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};
//密钥K2压缩置换 ,进1-56,出48
int K2[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};
//子密钥循环左移,16次
int shift[16]= {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2,1};
2、数据封装
int ByteToBit(ElemType ch,ElemType bit[8]);
int BitToByte(ElemType bit[8],ElemType *ch);
int Char8ToBit64(ElemType ch[8],ElemType bit[64]);
int Bit64ToChar8(ElemType bit[64],ElemType ch[8]);
int DES_MakeSubKeys(ElemType key[64],ElemType subKeys[16][48]); int DES_K1_Transform(ElemType key[64], ElemType tempbts[56]);
int DES_K2_Transform(ElemType key[56], ElemType tempbts[48]);
int DES_ROL(ElemType data[56], int time);
int DES_IP_Transform(ElemType data[64]);
int DES_IP1_Transform(ElemType data[64]);
int DES_Ex_Transform(ElemType data[48]);
int DES_P_Transform(ElemType data[32]);
int DES_SBOX(ElemType data[48]);
int DES_XOR(ElemType R[48], ElemType L[48],int count);
int DES_Swap(ElemType left[32],ElemType right[32]);
int DES_EncryptBlock(ElemType plainBlock[8], ElemType subKeys[16][48], cipherBlock[8]);
int DES_DecryptBlock(ElemType cipherBlock[8], ElemType subKeys[16][48], plainBlock[8]);
int DES_Encrypt(char *plainFile, char *keyStr,char *cipherFile);
int DES_Decrypt(char *cipherFile, char *keyStr,char *plainFile);
3、
//***********************开始定义函数*************************
//字节转换成二进制
void ByteToBit(){
ElemType ch,bit[8];
for(int i = 0;i < 8; i++){
*(bit+i) = ch%2;
ch=ch/2;
}
// return 0;
}
//将长度为8的字符串转为二进制位串
int Char8ToBit64(ElemType ch[8],ElemType bit[64]){
int i; ElemType ElemType
for(i = 0; i < 8; i++){
ByteToBit();
}
return 0;
}
//二进制转换成字节
void BitToByte(){
int i;
ElemType bit[8],*ch;
for(i = 0;i < 8; i++){
*ch= *(bit + i)<<i;
}
// return 0;
}
//将二进制位串转为长度为8的字符串
int Bit64ToChar8(ElemType bit[64],ElemType ch[8]){
int i;
memset(ch,0,8);
for(i = 0; i < 8; i++){
BitToByte();
}
return 0;
}
//生成子密钥
int DES_MakeSubKeys(ElemType key[64],ElemType subKeys[16][48]){
ElemType temp[56];
cout<<"Please input the key: ";
cin>>key;
DES_K1_Transform(key,temp);//K1置换
for(int i = 0; i < 16; i++){//16轮跌代,产生16个子密钥 DES_ROL(temp,shift[i]);//循环左移
DES_K2_Transform(temp,subKeys[i]);//K2置换,产生子密钥 }
return 0;
}
//密钥置换K1
int DES_K1_Transform(ElemType key[64], ElemType tempbts[56]){
for(int i = 0; i < 56; i++){
tempbts[i] = key[K1[i]];
}
return 0;
}
//密钥置换K2
int DES_K2_Transform(ElemType key[56], ElemType tempbts[48]){
for(int i = 0; i< 48; i++){
tempbts[i] = key[K2[i]];
}
return 0;
}
//循环左移
int DES_ROL(ElemType data[56], int time){
ElemType temp[56];
//保存将要循环移动到右边的位
memcpy(temp,data,time);
memcpy(temp+time,data+28,time);
//前28位移动
memcpy(data,data+time,28-time);
memcpy(data+28-time,temp,time);
//后28位移动
memcpy(data+28,data+28+time,28-time);
memcpy(data+56-time,temp+time,time);
return 0;
}
//IP置换
int DES_IP_Transform(ElemType data[64]){
ElemType temp[64];
for(int i = 0; i< 64; i++){
temp[i] = data[IP[i]];
}
memcpy(data,temp,64);
return 0;
}
//IP逆置换
int DES_IP1_Transform(ElemType data[64]){
ElemType temp[64];
for( int i = 0; i< 64; i++){
temp[i] = data[IP1[i]];
}
memcpy(data,temp,64);
return 0;
}
//扩展置换
int DES_E_Transform(ElemType data[48]){
ElemType temp[48];
for(int i= 0; i < 48; i++){
temp[i] = data[Ex[i]];
}
memcpy(data,temp,48);
return 0;
}
//P_F置换
int DES_P_Transform(ElemType data[32]){
int i;
ElemType temp[32];
for(i = 0; i < 32; i++){
temp[i] = data[P_F[i]];
}
memcpy(data,temp,32);
return 0;
}
//异或
int DES_XOR(ElemType R[48], ElemType L[48] ,int count){
for(int i = 0; i < count; i++){
R[i] ^= L[i];
}
return 0;
}
//S盒置换
int DES_SBOX(ElemType data[48]){
int i;
int line,row,output;
int cur1,cur2;
for(i = 0; i < 8; i++){
cur1 = i*6;
cur2 = i<<2;
//计算在S盒中的行与列
line = (data[cur1]<<1) + data[cur1+5];
row = (data[cur1+1]<<3) + (data[cur1+2]<<2)
+ (data[cur1+3]<<1) + data[cur1+4];
output = S[i][line][row];
//化为2进制
data[cur2] = (output&0X08)>>3;
data[cur2+1] = (output&0X04)>>2;
data[cur2+2] = (output&0X02)>>1;
data[cur2+3] = output&0x01;
}
return 0;
}
//交换
int DES_Swap(ElemType left[32], ElemType right[32]){
ElemType temp[32];
memcpy(temp,left,32);
memcpy(left,right,32);
memcpy(right,temp,32);
return 0;
}
//加密单个分组
int DES_EncryptBlock(ElemType plainBlock[8], ElemType subKeys[16][48], cipherBlock[8]){
ElemType plainBits[64];
ElemType copyRight[48];
Char8ToBit64(plainBlock,plainBits);
DES_IP_Transform(plainBits); //初始置换(IP置换) for(int i = 0; i < 16; i++){ ElemType
memcpy(copyRight,plainBits+32,32); DES_E_Transform(copyRight); 位扩展到48位
DES_XOR(copyRight,subKeys[i],48); DES_SBOX(copyRight); 果
DES_P_Transform(copyRight);
//16轮迭代
//将右半部分进行扩展置换,从32
//将右半部分与子密钥进行异或操作 //异或结果进入S盒,输出32位结
//P置换
DES_XOR(plainBits,copyRight,32);
if(i != 15){ //将明文左半部分与右半部分进行异或 //最终完成左右部的交换
DES_Swap(plainBits,plainBits+32);
} }
//逆初始置换(IP^1置换) DES_IP1_Transform(plainBits); Bit64ToChar8(plainBits,cipherBlock); return 0; }
//解密单个分组
int DES_DecryptBlock(ElemType cipherBlock[8], plainBlock[8]){
ElemType cipherBits[64]; ElemType copyRight[48]; int i;
Char8ToBit64(cipherBlock,cipherBits);
DES_IP_Transform(cipherBits);
for(i = 15; i >= 0; i--){
memcpy(copyRight,cipherBits+32,32); DES_E_Transform(copyRight); 32位扩展到48位
DES_XOR(copyRight,subKeys[i],48); 作
DES_SBOX(copyRight);
位结果
DES_P_Transform(copyRight); DES_XOR(cipherBits,copyRight,32);
异或
if(i != 0){
//最终完成左右部的交换
DES_Swap(cipherBits,cipherBits+32); }
ElemType subKeys[16][48],ElemType //初始置换(IP置换)
//16轮迭代 //将右半部分进行扩展置换,从//将右半部分与子密钥进行异或操
//异或结果进入S盒,输出32
//P置换
//将明文左半部分与右半部分进行
}
//逆初始置换(IP^1置换)
DES_IP1_Transform(cipherBits);
Bit64ToChar8(cipherBits,plainBlock);
return 0;
}
//加密明文
void DES_Encrypt(){
char *plainFile,*keyStr,*cipherFile;
ElemType plainBlock[8],cipherBlock[8],keyBlock[8]; ElemType bKey[64];
ElemType subKeys[16][48];
memcpy(keyBlock,keyStr,8); //设置密钥
Char8ToBit64(keyBlock,bKey); //将密钥转换为二进制流 DES_MakeSubKeys(bKey,subKeys); //生成子密钥
}
//解密密文
void DES_Decrypt(){
char *cipherFile, *keyStr,*plainFile;
int count,times = 0;
long fileLen;
ElemType plainBlock[8],cipherBlock[8],keyBlock[8]; ElemType bKey[64];
ElemType subKeys[16][48];
memcpy(keyBlock,keyStr,8); //设置密钥
Char8ToBit64(keyBlock,bKey); //将密钥转换为二进制流 DES_MakeSubKeys(bKey,subKeys); //生成子密钥 DES_DecryptBlock(cipherBlock,subKeys,plainBlock); cout<<plainFile<<endl;
}
void DES_input_plain(){
char *plainFile;
cout<<"Please input the plainTest: "; DES_EncryptBlock(plainBlock,subKeys,cipherBlock); cout<<cipherFile<<endl;
cin>>plainFile; }
void main(){
char plainFile,cipherFile; int keyStr;
DES_input_plain(); DES_Encrypt(); DES_Decrypt(); }
四、实验结果