本帖最后由 LegendSaber 于 2021-10-24 12:52 编辑
曾经学习DES算法时候写过的一份C语言实现的DES加解密算法。现在提供给大家参考
首先,由于DES是在比特层面对输入进行加密的。所以,首先需要做到将输入的字符与其二进制形式的互相转换,这部分代码在CChar中实现
[C] 纯文本查看 复制代码
#include "CChar.h"
void CharToBit(char input[], char output[])
{
int i = 0, j = 0, k = 0;
for (i = 0; i < 8; i++)
{
for (j = 0; j < 8; j++)
{
k = 7 - j;
output[i * 8 + j] = (input[i] >> k) & 0x1;
}
}
}
void BitToChar(char input[], char output[])
{
int i = 0, j = 0, k = 0;
for (i = 0; i < 8; i++)
{
for (j = 0; j < 8; j++)
{
k = 7 - j;
output[i] |= (input[i * 8 + j] << k);
}
}
}
其次,为了完成DES加密需要用到的密钥以及置换表等等这部分内容在table.h中定义
[C] 纯文本查看 复制代码 #ifndef __MY_TABLE_
#define __MY_TABLE_
//存储程序所需要的表与密钥
//初始置换表IP
const char IP_Table[64] = { 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,
56,48,40,32,24,16,8,0,
58,50,42,34,26,18,10,2,
60,52,44,36,28,20,12,4,
62,54,46,38,30,22,14,6};
//逆初始置换表IP^-1
const char IP_1_Table[64] = { 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,
32,0,40,8,48,16,56,24};
//扩展表E
const char E_Table[48] = { 31, 0, 1, 2, 3, 4,
3, 4, 5, 6, 7, 8,
7, 8, 9, 10, 11, 12,
11, 12, 13, 14, 15, 16,
15, 16, 17, 18, 19, 20,
19, 20, 21, 22, 23, 24,
23, 24, 25, 26, 27, 28,
27, 28, 29, 30, 31, 0};
//置换表P
const char P_Table[32] = { 15, 6, 19, 20, 11, 27, 16,
0, 14, 22, 25, 4, 17, 30, 9,
1, 7, 23, 13, 31, 26, 2, 8,
18, 12, 29, 5, 21, 10, 3, 24};
//S盒
const char S[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
{{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}},
//S3
{{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}},
//S4
{{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}},
//S5
{{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}},
//S6
{{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}},
//S7
{{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}},
//S8
{{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}}
};
//置换选择1
int PC_1[56] = { 56,48,40,32,24,16,8,
0,57,49,41,33,25,17,
9,1,58,50,42,34,26,
18,10,2,59,51,43,35,
62,54,46,38,30,22,14,
6,61,53,45,37,29,21,
13,5,60,52,44,36,28,
20,12,4,27,19,11,3};
//置换选择2
int PC_2[48] = { 13,16,10,23,0,4,2,27,
14,5,20,9,22,18,11,3,
25,7,15,6,26,19,12,1,
40,51,30,36,46,54,29,39,
50,44,32,46,43,48,38,55,
33,52,45,41,49,35,28,31};
//循环左移的位数
const char RoundLeft[16] = {1, 1, 2, 2,
2, 2, 2, 2,
1, 2, 2, 2,
2, 2, 1, 1};
//加密密钥
const char cKey[9] = {"12345678"};
char bKey[56] = { 0 };
//IV向量
char cIV[9] = {"IVVector"};
#endif
最后就是在主函数中对输入进行16轮的DES加密
[C] 纯文本查看 复制代码 #include <cstdio>
#include <cstring>
#include "table.h"
#include "CChar.h"
void DESAlgorithm(char cOrigData[]); //DES算法主体
//对左边32比特进行加密
void XOREncryptLeft(char cLeftChar[], char cRightChar[], int iIndex);
void InitBitKey(); //将密钥初始化为比特形式且进行置换
void EncryptByCBC(char cOrigData[], char cOrigData2[]); //采用CBC模式加密
void EncryptByCFB(char cOrigData[], char cOrigData2[]); //采用CFB模式加密
int main()
{
char cOrigData[9] = {"1900Code"};
char cOrigData2[9] = {"I 1900"};
printf("加密前的数据: %s %s\n", cOrigData, cOrigData2);
EncryptByCBC(cOrigData, cOrigData2);
EncryptByCFB(cOrigData, cOrigData2);
getchar();
return 0;
}
void EncryptByCFB(char cOrigData[], char cOrigData2[])
{
InitBitKey();
DESAlgorithm(cIV);
for (int i = 0; i < 9; i++) cOrigData[i] ^= cIV[i];
printf("CFB模式加密后的数据:%s ", cOrigData);
InitBitKey();
DESAlgorithm(cOrigData);
for (int i = 0; i < 9; i++) cOrigData2[i] ^= cOrigData[i];
printf("%s\n", cOrigData2);
for (int i = 0; i < 9; i++) cOrigData2[i] ^= cOrigData[i];
InitBitKey();
DESAlgorithm(cOrigData);
for (int i = 0; i < 9; i++) cOrigData[i] ^= cIV[i];
printf("CFB模式解密的数据:%s %s\n", cOrigData, cOrigData2);
InitBitKey();
DESAlgorithm(cIV);
}
void EncryptByCBC(char cOrigData[], char cOrigData2[])
{
InitBitKey();
for (int i = 0; i < 9; i++) cOrigData[i] ^= cIV[i];
DESAlgorithm(cOrigData);
InitBitKey();
for (int i = 0; i < 9; i++) cOrigData2[i] ^= cOrigData[i];
DESAlgorithm(cOrigData2);
printf("CBC模式加密后结果: %s %s\n", cOrigData, cOrigData2);
InitBitKey();
DESAlgorithm(cOrigData2);
for (int i = 0; i < 9; i++) cOrigData2[i] ^= cOrigData[i];
InitBitKey();
DESAlgorithm(cOrigData);
for (int i = 0; i < 9; i++) cOrigData[i] ^= cIV[i];
printf("CBC模式解密后的数据: %s %s\n", cOrigData, cOrigData2);
}
void DESAlgorithm(char cOrigData[])
{
char cLeft[32] = { 0 }, cRight[32] = { 0 }, cOrigChar[64] = { 0 };
char cTmp = 0, cOrigCpyChar[64] = { 0 };
CharToBit(cOrigData, cOrigChar);
memset(cOrigCpyChar, 0, sizeof(cOrigCpyChar));
memcpy(cOrigCpyChar, cOrigChar, 64); //进行初始置换
for (int i = 0; i < 64; i++)
{
cOrigChar[i] = cOrigCpyChar[IP_Table[i]];
}
for (int i = 0; i < 32; i++)
{
cLeft[i] = cOrigChar[i];
cRight[i] = cOrigChar[32 + i];
}
for (int i = 0; i < 16; i++) //进行16轮的加密
{
XOREncryptLeft(cLeft, cRight, i);
//除最后一轮,交换左右两边的比特
if (i < 15)
{
for (int j = 0; j < 32; j++)
{
cTmp = cLeft[j];
cLeft[j] = cRight[j];
cRight[j] = cTmp;
}
}
}
for (int i = 0; i < 32; i++)
{
cOrigChar[i] = cLeft[i];
cOrigChar[32 + i] = cRight[i];
}
memset(cOrigCpyChar, 0, sizeof(cOrigCpyChar));
memcpy(cOrigCpyChar, cOrigChar, 64); //进行逆初始置换
for (int i = 0; i < 64; i++)
{
cOrigChar[i] = cOrigCpyChar[IP_1_Table[i]];
}
memset(cOrigData, 0, sizeof(cOrigData));
BitToChar(cOrigChar, cOrigData);
}
void XOREncryptLeft(char cLeftChar[], char cRightChar[], int iIndex)
{
char cExtendChar[48] = { 0 };
int i = 0, moveNum = 0, col = 0, row = 0, j = 0, k = 0, l = 0;
char cLeftKey[28] = { 0 }, cRightKey[28] = { 0 };
char bEncryptKey[48] = { 0 };
char bSData[32] = { 0 };
char cSData = 0;
//进行扩展E置换
for (i = 0; i < 48; i++)
{
cExtendChar[i] = cRightChar[E_Table[i]];
}
for (i = 0; i < 28; i++)
{
cLeftKey[i] = bKey[i];
cRightKey[i] = bKey[28 + i];
}
moveNum = RoundLeft[iIndex];
for (i = 0; i < 28 - moveNum; i++)
{
cLeftKey[i] = cLeftKey[i + moveNum];
cRightKey[i] = cRightKey[i + moveNum];
}
for (i = 28 - moveNum; i < 28; i++)
{
cLeftKey[i] = 0;
cRightKey[i] = 0;
}
for (i = 0; i < 28; i++)
{
bKey[i] = cLeftKey[i];
bKey[28 + i] = cRightKey[i];
}
for (i = 0; i < 48; i++) bEncryptKey[i] = bKey[PC_2[i]];
for (i = 0; i < 48; i++) cExtendChar[i] |= bEncryptKey[i];
for (i = 0; i < 8; i++)
{
row = (cExtendChar[i * 8] - '0') * 2 + (cExtendChar[i * 8 + 5] - '0');
col = (cExtendChar[i * 8 + 1] - '0') * 8 + (cExtendChar[i * 8 + 2] - '0') * 4
+ (cExtendChar[i * 8 + 3] - '0') * 2 + (cExtendChar[i * 8 + 4] - '0');
cSData = S[iIndex][row][col];
if (cSData >= 8)
{
bSData[i * 4] = 1;
cSData -= 8;
}
if (cSData >= 4)
{
bSData[i * 4 + 1] = 1;
cSData -= 4;
}
if (cSData >= 2)
{
bSData[i * 4 + 2] = 1;
cSData -= 2;
}
if (cSData == 1) bSData[i * 4 + 3] = 1;
}
for (i = 0; i < 32; i++) cLeftChar[i] |= bSData[i];
}
void InitBitKey()
{
int i = 0, j = 0, k = 0;
char bCpyKey[56] = { 0 };
for (i = 0; i < 7; i++)
{
for (j = 0; j < 8; j++)
{
k = 7 - j;
bKey[i * 8 + j] = (cKey[i] >> k) & 0x1;
}
}
memset(bCpyKey, 0, sizeof(bCpyKey));
memcpy(bCpyKey, bKey, 56);
for (i = 0; i < 56; i++)
{
bKey[i] = bCpyKey[PC_1[i]];
}
}
可以看到最终的输出,程序成功对输入的字符进行DES的加密解密
|