密码学DES的C++实现(完整)

编程入门 行业动态 更新时间:2024-10-07 09:23:25

<a href=https://www.elefans.com/category/jswz/34/1761750.html style=密码学DES的C++实现(完整)"/>

密码学DES的C++实现(完整)

下述为DES代码实现的完整过程,其中包括密钥扩展、DES实现、CBC模式(密码分组链接模式)和ECB模式(电码本模式),经过本人测试可直接运行使用,所有代码为本人原创,禁止转载

下述有分块介绍模块的详细介绍,但是如果各位不感兴趣可以直接拉到最下面,有完整代码

  1. DES的基本原理

其入口参数有三个:key、data、mode。Key为加密解密使用的密钥,data为加密解密的数据,mode为其工作模式。当模式为加密模式时,明文按照64位进行分组,形成明文组,key用于对数据加密,当模式为解密模式时,key用于对数据解密。实际运用中,密钥只用到了64位中的56位,这样才具有高的安全性。

初始化

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 };// 逆初始置换
int IP_1[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 };// 扩展置换表
int E[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 };// S盒
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}},{{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}},{{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}},{{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}},{{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}},{{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}},{{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}},{{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}}
};// P置换
int P[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 };int PC1[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
};int s[16] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
//  密钥第二次置换表
int PC2[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
};
  1. 分组密码工作模式

密钥扩展

void generate_key(int origin_key[], int key[16][48])    //密钥扩展算法
{int C[28], D[28];for (int i = 0; i < 28; i++){C[i] = origin_key[PC1[i]];D[i] = origin_key[PC1[28+i]];}for (int i = 0; i < 16; i++){int temp = s[i];      //左移次数while (temp--){//c,d为循环左移暂存区int c = C[0];int d = D[0];for (int j = 1; j < 28; j++){C[j - 1] = C[j];D[j - 1] = D[j];}C[27] = c;D[27] = d;}int result[56];for (int j = 0; j < 28; j++){result[j] = C[j];result[28 + j] = D[j];}for (int j = 0; j < 48; j++)key[i][j] = result[PC2[j]-1];}
}

Feistel结构

void Feistel(int L[], int R[], int* key)         //Feistel结构
{int L_[32], R_[32];int RF[33];F(R, key,RF);for (int i = 0; i < 32; i++){L_[i] = R[i];R_[i] = L[i] ^ RF[i];}for (int i = 0; i < 32; i++){L[i] = L_[i];R[i] = R_[i];}
}

DES的工作模式:电码本模式(CB)、密码分组链接模式(CBC)。

char* DES(int key[16][48], int data[], char mode)
{int L[32],R[32];int temp[64];static char proclaim[9];memcpy(temp, data, sizeof(int) * 64);if (mode == '1')      //加密{for (int i = 0; i < 64; i++)       //初始置换data[i] = temp[IP[i] - 1];for (int i = 0; i < 32; i++)       //数据拆分成两部分{L[i] = data[i];R[i] = data[32 + i];}for (int times = 0; times < 16; times++){Feistel(L, R, key[times]);cout << "第" << times << "轮加密结果:";for (int i = 0; i < 32; i++)cout << L[i];for (int i = 0; i < 32; i++)cout << R[i];cout << endl;}int result[64];for (int i = 0; i < 32; i++)     //32bit互换{result[i] = R[i];result[32 + i] = L[i];}for (int i = 0; i < 64; i++)       //逆初始置换data[i] = result[IP_1[i] - 1];cout << "加密的二进制串为:";for (int i = 0; i < 64; i++)cout << data[i];cout << endl;int num = 8;while (num--)          //二进制数组转换为字符串{int t = 8;int ch = 0;while (t--){ch = data[(7 - num) * 8 + (7 - t)] + ch * 2;}proclaim[(7 - num)] = ch;}proclaim[8] = '\0';cout << "加密得到的密文为:" << proclaim << endl;}else                  //解密{for (int i = 0; i < 64; i++)       //初始置换data[i] = temp[IP[i] - 1];for (int i = 0; i < 32; i++)       //数据拆分成两部分{L[i] = data[i];R[i] = data[32 + i];}for (int times = 15; times >= 0; times--)Feistel(L, R, key[times]);int result[64];for (int i = 0; i < 32; i++)       //32bit互换{result[i] = R[i];result[32 + i] = L[i];}for (int i = 0; i < 64; i++)       //逆初始置换data[i] = result[IP_1[i] - 1];cout << "解密的二进制串为:";for (int i = 0; i < 64; i++)cout << data[i];cout << endl;int num = 8;while (num--)          //二进制数组转换为字符串{int t = 8;int ch = 0;while (t--){ch = data[(7 - num) * 8 + (7 - t)] + ch * 2;}proclaim[(7 - num)] = ch;}proclaim[8] = '\0';}return proclaim;
}

 F函数

void F(int R[], int* key,int Rf[])                         //F函数
{int RR[48];for (int i = 0; i < 48; i++)        //E置换并与密钥异或{RR[47 - i] = R[32 - E[i]];RR[47 - i] = RR[47 - i] ^ key[47 - i];}int x = 0;for (int i = 0; i < 8; i++)     //S_i置换{int row = RR[47 - i] * 2 + RR[47 - i - 5];int column = RR[47 - i - 1] * 8 + RR[47 - i - 2] * 4 + RR[47 - i - 3] * 2 + RR[47 - i - 4];int result = S[i / 6][row][column];bitset<4> bit(result);for (int j = 0; j < 4; j++)Rf[31 - x - j] = bit[3 - j];x = x + 4;}int temp[32];memcpy(temp, Rf, sizeof(int) * 32);for (int i = 0; i < 32; i++)Rf[32 - i] = temp[32 - P[i]];
}

字符串转换二进制串

void Bit_char(char* data,int bit_data[])       //字符串转换为二进制bit
{int temp = 0;int i;for (i = 0; i < 8; i++){if (data[i] != '\0'){bitset<8> bit = bitset<8>(data[i]);for (int j = 7; j >= 0; j--)bit_data[temp++] = bit[j];}elsebreak;}while (temp < 64){bit_data[temp++] = 0;}
}

ECB模式的加密过程:

void ECB(int key[16][48], int data[64][64],char modle)       //电码本模式
{char* str;if (modle == '1'){str = DES(key, data[0], '1');ofstream ECB_1("ECB_1.txt");ECB_1 << str;ECB_1.close();ofstream ECB_11("ECB_11.txt", ios::binary | ios::out);ECB_11.write((char*)&data[0], sizeof(data[0]));ECB_11.close();for (int i = 1; i < 64; i++)     //加密{str=DES(key, data[i], '1');ofstream ECB_1("ECB_1.txt", std::ios_base::app);ECB_1 << str;ECB_1.close();ofstream ECB_11("ECB_11.txt", ios::binary | ios::out | ios::app);ECB_11.write((char*)&data[i], sizeof(data[i]));ECB_11.close();}cout << "加密结果已存入ECB_1.txt中,二进制结果存入ECB11.txt中" << endl;}else{str = DES(key, data[0], '2');ofstream ECB_2("ECB_2.txt");ECB_2 << str;ECB_2.close();for (int i = 1; i < 64; i++)     //解密{str=DES(key, data[i], '2');ofstream ECB_2("ECB_2.txt", std::ios_base::app);ECB_2 << str;ECB_2.close();}cout << "解密结果已存入ECB_2.txt文件中" << endl;}
}

CBC模式的加密过程:

void CBC(int key[16][48], int data[64][64], char modle)       //密码分组链接模式
{char IV[9] = "E0191410";int IV_bit[64];Bit_char(IV, IV_bit);int chip[64][64];for (int i = 0; i < 64; i++)for (int j = 0; j < 64; j++)chip[i][j] = data[i][j];if (modle == '1'){char* str;for (int i = 0; i < 64; i++)data[0][i] = data[0][i] ^ IV_bit[i];str=DES(key, data[0], modle);ofstream CBC_11("CBC_11.txt", ios::binary | ios::out);CBC_11.write((char*)&data[0], sizeof(data[0]));CBC_11.close();ofstream CBC_1("CBC_1.txt");CBC_1 << str;CBC_1.close();for (int i = 1; i < 64; i++){for (int j = 0; j < 64; j++)data[i][j] = data[i][j] ^ data[i - 1][j];DES(key, data[i], modle);ofstream CBC_11("CBC_11.txt", ios::binary | ios::out | ios::app);CBC_11.write((char*)&data[i], sizeof(data[i]));CBC_11.close();ofstream CBC_1("CBC_1.txt", std::ios_base::app);CBC_1 << str;CBC_1.close();}cout << "加密结果已存入CBC_1.txt中,加密的二进制结果已存入CBC_11.txt中" << endl;}else{char str[513];str[512] = '\0';int tt = 0;DES(key, data[0], modle);for (int i = 0; i < 64; i++)data[0][i] = data[0][i] ^ IV_bit[i];//二进制转换为字符串int num = 8;while (num--)          //二进制数组转换为字符串{int t = 8;int ch = 0;while (t--){ch = data[0][(7 - num) * 8 + (7 - t)] + ch * 2;}str[tt++] = ch;}for (int i = 1; i < 64; i++){DES(key, data[i], '2');for (int j = 0; j < 64; j++)data[i][j] = data[i][j] ^ chip[i - 1][j];//二进制转换为字符串int num = 8;while (num--)          //二进制数组转换为字符串{int t = 8;int ch = 0;while (t--){ch = data[i][(7 - num) * 8 + (7 - t)] + ch * 2;}str[tt++] = ch;}}ofstream CBC_2("CBC_2.txt");CBC_2 << str;CBC_2.close();}
}

测试代码(主函数main代码)

void main()
{char data[9];char key[9];char mode;int bit_data[64];char choose;cout << "1、DES加密、解密\n2、分组密码模式\n请选择:";cin >> choose;if (choose != '1' && choose != '2'){cout << "输入有误,退出程序";exit(0);}else if (choose == '1'){cout << "1、加密\n2、解密\n您选择:";cin >> mode;if (mode != '1' && mode != '2'){cout << "输入有误,退出程序";exit(0);}else if (mode == '1'){cout << "请输入需要加密的8字节明文:";cin >> data;Bit_char(data, bit_data);}else{fstream file;file.open("result_1.txt", ios::binary | ios::in);file.read((char*)&data, sizeof(data));file.close();Bit_char(data, bit_data);cout << "已从result_1.txt文件中加载获取密文" << endl;}cout << "请输入加密所需的8字节密钥:";cin >> key;int bit_key[64];char *str;Bit_char(key, bit_key);int k[16][48];generate_key(bit_key, k);str=DES(k, bit_data, mode);if (mode == '1'){//加密结果存入文件中ofstream file("result_1.txt");file << str;file.close();cout << "加密结果已存入result_1.txt文件中" << endl;}if (mode == '2'){//加密结果存入文件中ofstream file("result_2.txt");file << str;file.close();cout << "解密结果已存入result_2.txt文件中" << endl;}}else{cout << "1、电码本模式\n2、密码分组链接模式\n请选择:";cin >> mode;cout << "请输入加密所需的8字节密钥:";cin >> key;int bit_key[64];Bit_char(key, bit_key);static int k[16][48];generate_key(bit_key, k);char modle;cout << "1、加密\n2、解密\n请选择:";cin >> modle;int data_bit[64][64];if (modle == '1'){fstream file;char source[512];file.open("source.txt", ios::in);file.read((char*)&source, sizeof(source));file.close();for (int i = 0; i < 64; i++)   //字符转换为二进制串{for (int j = 0; j < 8; j++)data[j] = source[i * 8 + j];Bit_char(data, data_bit[i]);}}if (mode != '1' && mode != '2'){cout << "输入有误,退出程序";exit(0);}if (mode == '1'){int data_all[4096];if(modle=='2'){fstream ECB;ECB.open("ECB_11.txt", ios::binary | ios::in);ECB.read((char*)&data_all, sizeof(data_all));ECB.close();cout << "已从ECB_11.txt文件中加载获取密文" << endl;for (int i = 0; i < 64; i++){for (int j = 0; j < 64; j++){data_bit[i][j] = data_all[i * 64 + j];}}}ECB(k, data_bit, modle);}else{int data_all[4096];if (modle == '2'){fstream CBC;CBC.open("CBC_11.txt", ios::binary | ios::in);CBC.read((char*)&data_all, sizeof(data_all));CBC.close();cout << "已从CBC_11.txt文件中加载获取密文" << endl;for (int i = 0; i < 64; i++){for (int j = 0; j < 64; j++){data_bit[i][j] = data_all[i * 64 + j];}}}CBC(k, data_bit, modle);}}
}

 完整代码

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include <fstream>
#include<bitset>
#include<string>
using namespace std;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 };// 逆初始置换
int IP_1[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 };// 扩展置换表
int E[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 };// S盒
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}},{{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}},{{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}},{{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}},{{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}},{{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}},{{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}},{{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}}
};// P置换
int P[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 };int PC1[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
};int s[16] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
//  密钥第二次置换表
int PC2[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
};void Bit_char(char* data,int bit_data[])       //字符串转换为二进制bit
{int temp = 0;int i;for (i = 0; i < 8; i++){if (data[i] != '\0'){bitset<8> bit = bitset<8>(data[i]);for (int j = 7; j >= 0; j--)bit_data[temp++] = bit[j];}elsebreak;}while (temp < 64){bit_data[temp++] = 0;}
}void F(int R[], int* key,int Rf[])                         //F函数
{int RR[48];for (int i = 0; i < 48; i++)        //E置换并与密钥异或{RR[47 - i] = R[32 - E[i]];RR[47 - i] = RR[47 - i] ^ key[47 - i];}int x = 0;for (int i = 0; i < 8; i++)     //S_i置换{int row = RR[47 - i] * 2 + RR[47 - i - 5];int column = RR[47 - i - 1] * 8 + RR[47 - i - 2] * 4 + RR[47 - i - 3] * 2 + RR[47 - i - 4];int result = S[i / 6][row][column];bitset<4> bit(result);for (int j = 0; j < 4; j++)Rf[31 - x - j] = bit[3 - j];x = x + 4;}int temp[32];memcpy(temp, Rf, sizeof(int) * 32);for (int i = 0; i < 32; i++)Rf[32 - i] = temp[32 - P[i]];
}void Feistel(int L[], int R[], int* key)         //Feistel结构
{int L_[32], R_[32];int RF[33];F(R, key,RF);for (int i = 0; i < 32; i++){L_[i] = R[i];R_[i] = L[i] ^ RF[i];}for (int i = 0; i < 32; i++){L[i] = L_[i];R[i] = R_[i];}
}void generate_key(int origin_key[], int key[16][48])    //密钥扩展算法
{int C[28], D[28];for (int i = 0; i < 28; i++){C[i] = origin_key[PC1[i]];D[i] = origin_key[PC1[28+i]];}for (int i = 0; i < 16; i++){int temp = s[i];      //左移次数while (temp--){//c,d为循环左移暂存区int c = C[0];int d = D[0];for (int j = 1; j < 28; j++){C[j - 1] = C[j];D[j - 1] = D[j];}C[27] = c;D[27] = d;}int result[56];for (int j = 0; j < 28; j++){result[j] = C[j];result[28 + j] = D[j];}for (int j = 0; j < 48; j++)key[i][j] = result[PC2[j]-1];}
}char* DES(int key[16][48], int data[], char mode)
{int L[32],R[32];int temp[64];static char proclaim[9];memcpy(temp, data, sizeof(int) * 64);if (mode == '1')      //加密{for (int i = 0; i < 64; i++)       //初始置换data[i] = temp[IP[i] - 1];for (int i = 0; i < 32; i++)       //数据拆分成两部分{L[i] = data[i];R[i] = data[32 + i];}for (int times = 0; times < 16; times++){Feistel(L, R, key[times]);cout << "第" << times << "轮加密结果:";for (int i = 0; i < 32; i++)cout << L[i];for (int i = 0; i < 32; i++)cout << R[i];cout << endl;}int result[64];for (int i = 0; i < 32; i++)     //32bit互换{result[i] = R[i];result[32 + i] = L[i];}for (int i = 0; i < 64; i++)       //逆初始置换data[i] = result[IP_1[i] - 1];cout << "加密的二进制串为:";for (int i = 0; i < 64; i++)cout << data[i];cout << endl;int num = 8;while (num--)          //二进制数组转换为字符串{int t = 8;int ch = 0;while (t--){ch = data[(7 - num) * 8 + (7 - t)] + ch * 2;}proclaim[(7 - num)] = ch;}proclaim[8] = '\0';cout << "加密得到的密文为:" << proclaim << endl;}else                  //解密{for (int i = 0; i < 64; i++)       //初始置换data[i] = temp[IP[i] - 1];for (int i = 0; i < 32; i++)       //数据拆分成两部分{L[i] = data[i];R[i] = data[32 + i];}for (int times = 15; times >= 0; times--)Feistel(L, R, key[times]);int result[64];for (int i = 0; i < 32; i++)       //32bit互换{result[i] = R[i];result[32 + i] = L[i];}for (int i = 0; i < 64; i++)       //逆初始置换data[i] = result[IP_1[i] - 1];cout << "解密的二进制串为:";for (int i = 0; i < 64; i++)cout << data[i];cout << endl;int num = 8;while (num--)          //二进制数组转换为字符串{int t = 8;int ch = 0;while (t--){ch = data[(7 - num) * 8 + (7 - t)] + ch * 2;}proclaim[(7 - num)] = ch;}proclaim[8] = '\0';}return proclaim;
}void ECB(int key[16][48], int data[64][64],char modle)       //电码本模式
{char* str;if (modle == '1'){str = DES(key, data[0], '1');ofstream ECB_1("ECB_1.txt");ECB_1 << str;ECB_1.close();ofstream ECB_11("ECB_11.txt", ios::binary | ios::out);ECB_11.write((char*)&data[0], sizeof(data[0]));ECB_11.close();for (int i = 1; i < 64; i++)     //加密{str=DES(key, data[i], '1');ofstream ECB_1("ECB_1.txt", std::ios_base::app);ECB_1 << str;ECB_1.close();ofstream ECB_11("ECB_11.txt", ios::binary | ios::out | ios::app);ECB_11.write((char*)&data[i], sizeof(data[i]));ECB_11.close();}cout << "加密结果已存入ECB_1.txt中,二进制结果存入ECB11.txt中" << endl;}else{str = DES(key, data[0], '2');ofstream ECB_2("ECB_2.txt");ECB_2 << str;ECB_2.close();for (int i = 1; i < 64; i++)     //解密{str=DES(key, data[i], '2');ofstream ECB_2("ECB_2.txt", std::ios_base::app);ECB_2 << str;ECB_2.close();}cout << "解密结果已存入ECB_2.txt文件中" << endl;}
}void CBC(int key[16][48], int data[64][64], char modle)       //密码分组链接模式
{char IV[9] = "E0191410";int IV_bit[64];Bit_char(IV, IV_bit);int chip[64][64];for (int i = 0; i < 64; i++)for (int j = 0; j < 64; j++)chip[i][j] = data[i][j];if (modle == '1'){char* str;for (int i = 0; i < 64; i++)data[0][i] = data[0][i] ^ IV_bit[i];str=DES(key, data[0], modle);ofstream CBC_11("CBC_11.txt", ios::binary | ios::out);CBC_11.write((char*)&data[0], sizeof(data[0]));CBC_11.close();ofstream CBC_1("CBC_1.txt");CBC_1 << str;CBC_1.close();for (int i = 1; i < 64; i++){for (int j = 0; j < 64; j++)data[i][j] = data[i][j] ^ data[i - 1][j];DES(key, data[i], modle);ofstream CBC_11("CBC_11.txt", ios::binary | ios::out | ios::app);CBC_11.write((char*)&data[i], sizeof(data[i]));CBC_11.close();ofstream CBC_1("CBC_1.txt", std::ios_base::app);CBC_1 << str;CBC_1.close();}cout << "加密结果已存入CBC_1.txt中,加密的二进制结果已存入CBC_11.txt中" << endl;}else{char str[513];str[512] = '\0';int tt = 0;DES(key, data[0], modle);for (int i = 0; i < 64; i++)data[0][i] = data[0][i] ^ IV_bit[i];//二进制转换为字符串int num = 8;while (num--)          //二进制数组转换为字符串{int t = 8;int ch = 0;while (t--){ch = data[0][(7 - num) * 8 + (7 - t)] + ch * 2;}str[tt++] = ch;}for (int i = 1; i < 64; i++){DES(key, data[i], '2');for (int j = 0; j < 64; j++)data[i][j] = data[i][j] ^ chip[i - 1][j];//二进制转换为字符串int num = 8;while (num--)          //二进制数组转换为字符串{int t = 8;int ch = 0;while (t--){ch = data[i][(7 - num) * 8 + (7 - t)] + ch * 2;}str[tt++] = ch;}}ofstream CBC_2("CBC_2.txt");CBC_2 << str;CBC_2.close();}
}void main()
{char data[9];char key[9];char mode;int bit_data[64];char choose;cout << "1、DES加密、解密\n2、分组密码模式\n请选择:";cin >> choose;if (choose != '1' && choose != '2'){cout << "输入有误,退出程序";exit(0);}else if (choose == '1'){cout << "1、加密\n2、解密\n您选择:";cin >> mode;if (mode != '1' && mode != '2'){cout << "输入有误,退出程序";exit(0);}else if (mode == '1'){cout << "请输入需要加密的8字节明文:";cin >> data;Bit_char(data, bit_data);}else{fstream file;file.open("result_1.txt", ios::binary | ios::in);file.read((char*)&data, sizeof(data));file.close();Bit_char(data, bit_data);cout << "已从result_1.txt文件中加载获取密文" << endl;}cout << "请输入加密所需的8字节密钥:";cin >> key;int bit_key[64];char *str;Bit_char(key, bit_key);int k[16][48];generate_key(bit_key, k);str=DES(k, bit_data, mode);if (mode == '1'){//加密结果存入文件中ofstream file("result_1.txt");file << str;file.close();cout << "加密结果已存入result_1.txt文件中" << endl;}if (mode == '2'){//加密结果存入文件中ofstream file("result_2.txt");file << str;file.close();cout << "解密结果已存入result_2.txt文件中" << endl;}}else{cout << "1、电码本模式\n2、密码分组链接模式\n请选择:";cin >> mode;cout << "请输入加密所需的8字节密钥:";cin >> key;int bit_key[64];Bit_char(key, bit_key);static int k[16][48];generate_key(bit_key, k);char modle;cout << "1、加密\n2、解密\n请选择:";cin >> modle;int data_bit[64][64];if (modle == '1'){fstream file;char source[512];file.open("source.txt", ios::in);file.read((char*)&source, sizeof(source));file.close();for (int i = 0; i < 64; i++)   //字符转换为二进制串{for (int j = 0; j < 8; j++)data[j] = source[i * 8 + j];Bit_char(data, data_bit[i]);}}if (mode != '1' && mode != '2'){cout << "输入有误,退出程序";exit(0);}if (mode == '1'){int data_all[4096];if(modle=='2'){fstream ECB;ECB.open("ECB_11.txt", ios::binary | ios::in);ECB.read((char*)&data_all, sizeof(data_all));ECB.close();cout << "已从ECB_11.txt文件中加载获取密文" << endl;for (int i = 0; i < 64; i++){for (int j = 0; j < 64; j++){data_bit[i][j] = data_all[i * 64 + j];}}}ECB(k, data_bit, modle);}else{int data_all[4096];if (modle == '2'){fstream CBC;CBC.open("CBC_11.txt", ios::binary | ios::in);CBC.read((char*)&data_all, sizeof(data_all));CBC.close();cout << "已从CBC_11.txt文件中加载获取密文" << endl;for (int i = 0; i < 64; i++){for (int j = 0; j < 64; j++){data_bit[i][j] = data_all[i * 64 + j];}}}CBC(k, data_bit, modle);}}
}

附加问题:DES与AES的不同之处

AES特征
AES是分组密码

数据是128比特,密钥是128/192/256比特

比3DES安全性高、速度快

提供完整的规范和设计细节

能在多种平台上以较快的速度实现

DES的特征 
分组加密算法:明文和密文为64位分组长度;

对称算法:加密和解密除密钥编排不同外,使用同一算法;

密钥长度:64位,但每个字节第8位为奇偶校验位,可忽略;

密钥可为任意的56位数,但存在弱密钥,尽量避开;

采用混乱和扩散的组合,每个组合先替代后置换,共16轮;

只使用了标准的算术和逻辑运算,易于实现。 

详细资源:

实现DES的工作模式(包括DES和CBC、ECB)-网络安全文档类资源-CSDN文库

更多推荐

密码学DES的C++实现(完整)

本文发布于:2024-02-14 04:03:15,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1761727.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:密码学   完整   DES

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!