DES加解密C语言实现

Author Avatar
Xzhah 5月 07, 2018
  • 在其它设备中阅读本文章

* main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
extern "C"
#include "DES.h"
#include<Windows.h>
#include<math.h>
//加密模式
void ECB(FILE *fd, FILE *Sf, int *K, int mode) { //ECB模式加\解密
int M[64] = {0}, C[64] = {0};
while (readFile64(fd, M)) {
DES(M, K, C, mode);
writeFile64(Sf, C);
int aaa;
for (int i = 0; i < 64; ++i) {
if(i%4==0)
aaa=0;
//printf("%d", in[i]);
int b=(3-(i%4));
int c=2;
aaa=aaa+C[i]*pow((float)c,b);
if(i%4==3)
{
if(aaa<10)
{
printf("%d", aaa);

}
else{
if(aaa==10)
printf("A");
if(aaa==11)
printf("B");
if(aaa==12)
printf("C");
if(aaa==13)
printf("D");
if(aaa==14)
printf("E");
if(aaa==15)
printf("F");

}
}}
memset(M, 0, sizeof(M));
}
rewind(fd);
}

void CBC(FILE *fd, FILE *Sf, int *IV, int *K, int mode) { //CBC模式加\解密
int M[64] = {0}, C[64];
while (readFile64(fd, M)) {
if (mode == 0)fIV(M, IV);
DES(M, K, C, mode);
if (mode == 1)fIV(C, IV);
if (mode == 1)memcpy((void *) IV, (void *) M, sizeof(M));
writeFile64(Sf, C);
int aaa;
for (int i = 0; i < 64; ++i) {
if(i%4==0)
aaa=0;
//printf("%d", in[i]);
int b=(3-(i%4));
int c=2;
aaa=aaa+C[i]*pow((float)c,b);
if(i%4==3)
{
if(aaa<10)
{
printf("%d", aaa);

}
else{
if(aaa==10)
printf("A");
if(aaa==11)
printf("B");
if(aaa==12)
printf("C");
if(aaa==13)
printf("D");
if(aaa==14)
printf("E");
if(aaa==15)
printf("F");

}
}}
memset(M, 0, sizeof(M));
if (mode == 0)memcpy((void *) IV, (void *) C, sizeof(C));
}
rewind(fd);
}

void print_usage(char *cmd) { //打印参数错误提示信息
fprintf(stderr, " %s usage:\n", cmd);
fprintf(stderr, "%s PlainText Key IV SaveFile mode(0 or 1)\n", cmd);

}

int main(int argc, char **argv) {
printf("*******DES 加密演示程序(CPP)**********\n");
printf("***如果一个分组不足64bit,低位补0。***\n");

char M_PATH[100], K_PATH[100], S_PATH[100], IV_PATH[100], S_PATH_T[100];
int mode,its, K[64] = {0};
printf("加密请输入0,解密请输入1:\n");
scanf("%d", &mode);
if (mode == 0) { //加密模式
int IV[64] = {0};
printf("ECB模式请输入0,CBC模式请输入1:\n");
scanf("%d", &its);
printf("请输入待加密文件的路径:\n");
scanf("%s", M_PATH);
printf("请输入加密密钥的文件路径:\n");
scanf("%s", K_PATH);
if(its==1){
printf("请输入CBC模式的初始化向量文件路径:\n");
scanf("%s", IV_PATH);}
printf("请输入加密文件输出文件名:\n");
scanf("%s", S_PATH);

//char *aa="\x4E\x65\x74\x77\x6F\x72\x6B\x20\x53\x65\x63\x75\x72\x69\x74\x79";
//FILE *Mf1 = fopen(M_PATH, "wb+");
//fwrite(aa, 16, 1, Mf1);
//closeFile(Mf1);
//char *kk="\x57\x69\x6C\x6C\x69\x61\x6D\x53";
//FILE *Kf1 = fopen(K_PATH, "wb+");
//fwrite(kk, 8, 1, Mf1);
//closeFile(Kf1);
//char *ivv="\x50\x72\x65\x6E\x74\x69\x63\x65";
//FILE *Vf1 = fopen(IV_PATH, "wb+");
//fwrite(ivv, 8, 1, Vf1);
//closeFile(Vf1);
FILE *Mf = fopen(M_PATH, "rb");
FILE *Kf = fopen(K_PATH, "rb");
FILE * IVf;
if(its==1){
IVf = fopen(IV_PATH, "rb");}
FILE *Sf_ECB;
FILE *Sf_CBC;
strcpy(S_PATH_T, S_PATH);
if(its==0){
//strcat(S_PATH_T, "_ECB.txt");
Sf_ECB = fopen(S_PATH_T, "wb+");}
if(its==1){
strcpy(S_PATH_T, S_PATH);
//strcat(S_PATH_T, "_CBC.txt");
Sf_CBC = fopen(S_PATH_T, "wb+");}

readFile64(Kf, K);
if(its==1){
readFile64(IVf, IV);}

closeFile(Kf);
if(its==1){closeFile(IVf);}
if(its==0){
ECB(Mf, Sf_ECB, K, mode);}
if(its==1){
CBC(Mf, Sf_CBC, IV, K, mode);}

closeFile(Mf);
if(its==0){
closeFile(Sf_ECB);}
if(its==1){
closeFile(Sf_CBC);}
} else { //解密模式
printf("请输入密文文件路径:\n");
scanf("%s", M_PATH);
printf("请输入密钥的文件路径:\n");
scanf("%s", K_PATH);
printf("请输入解密结果输出文件名:\n");
scanf("%s", S_PATH);
printf("请输入模式,ECB输入0,CBC输入1:\n");
scanf("%d", &mode);

FILE *Mf = fopen(M_PATH, "rb");
FILE *Kf = fopen(K_PATH, "rb");
FILE *Sf = fopen(S_PATH, "wb+");
readFile64(Kf, K);

if (mode == 0) { //ECB模式解密
mode = 1;
ECB(Mf, Sf, K, mode);
} else { //CBC模式解密
mode = 1;
int IV[64] = {0};
printf("请输入CBC模式的初始化向量文件路径:\n");
scanf("%s", IV_PATH);
FILE *IVf = fopen(IV_PATH, "rb");
readFile64(IVf, IV);
closeFile(IVf);
CBC(Mf, Sf, IV, K, mode);
}
closeFile(Mf);
closeFile(Kf);
closeFile(Sf);





}
system("pause");
return 0;
}

* DES.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#ifndef DES_H_
#define DES_H_
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>


void DES(int *M, int *Key, int *C, int mode);

void Keygen(int *K);

void IP(int *M, int *L0, int *R0);

void FP(int *C, int *L16, int *R16);

void LtoR(int *Ri, int *Li_1, int *Ri_1, int *Ki);

void f(int *f_re, int *Ri_1, int *Ki);

void E(int *Ri_1, int *Ei);

void S(int *Si, int *Pi, int *Sbox, int index);

void P(int *Pi, int *f_re);

void InttoBarr(int dec, int *arr, int index, int bit);

void RotateKeyLeft(int *K, int index);

void PC2(int *C, int *D, int id);

void fIV(int *M, int *IV);
void ascToBinary(int character, int *ones, int index);

char BinaryToasc(int *ones, int index);

void readBinary(char *temp, int *s);

void writeBinary(int *temp, char *s);

int readFile64(FILE *fd, int *s);

void writeFile64(FILE *fd, int *s);

FILE *readFilefromPATH(const void *PATH);

FILE *writeFilefromPATH(const void *PATH);

void closeFile(FILE *fd);

#endif //DES_H_

* DES.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
#include "DES.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
int Keyi[16][48];

int table_IP[] = {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 table_arcIP[] = {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 table_E[] = {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};
int table_P[] = {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 table_PC1[] = {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 table_LS[] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
int table_PC2[] = {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};

int 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};

int 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};

int 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};

int 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};

int 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};

int 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};

int 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};

int 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};


void DES(int *M, int *Key, int *C, int mode) {
int L[2][32] = {0}, R[2][32] = {0};
memset(C, 0, sizeof(C));
Keygen(Key);
IP(M, L[0], R[0]);
switch (mode) {
case 0:
for (int i = 1; i <= 16; ++i) {
memcpy((void *) L[i % 2], (void *) R[(i + 1) % 2], sizeof(R[(i + 1) % 2]));
LtoR(R[i % 2], L[(i + 1) % 2], R[(i + 1) % 2], Keyi[i - 1]);
}
break;
case 1:
for (int i = 1; i <= 16; ++i) {
memcpy((void *) L[i % 2], (void *) R[(i + 1) % 2], sizeof(R[(i + 1) % 2]));
LtoR(R[i % 2], L[(i + 1) % 2], R[(i + 1) % 2], Keyi[16 - i]);
}
break;
default:
break;
}
FP(C, L[0], R[0]);

}

void Keygen(int *K) {
int C[28], D[28];
for (int i = 0; i < 56; ++i) {
if (i < 28) {
C[i] = K[table_PC1[i] - 1];
} else {
D[i - 28] = K[table_PC1[i] - 1];
}
}
for (int i = 0; i < 16; ++i) {
RotateKeyLeft(C, table_LS[i]);
RotateKeyLeft(D, table_LS[i]);
PC2(C, D, i);
}

}

void IP(int *M, int *L0, int *R0) {
for (int i = 0; i < 32; ++i) {
L0[i] = M[table_IP[i] - 1];
}
for (int i = 32; i < 64; ++i) {
R0[i - 32] = M[table_IP[i] - 1];
}
}

void FP(int *C, int *L16, int *R16) {
int index;
for (int i = 0; i < 64; ++i) {
index = table_arcIP[i];
if (index <= 32) {
C[i] = R16[index - 1];
} else {
C[i] = L16[index - 33];
}
}
}

void LtoR(int *Ri, int *Li_1, int *Ri_1, int *Ki) {
int f_re[32];
f(f_re, Ri_1, Ki);
for (int i = 0; i < 32; ++i) {
Ri[i] = Li_1[i] ^ f_re[i];
}
}

void f(int *f_re, int *Ri_1, int *Ki) {
int Ei[48], Si[48], Pi[32], *Sbox;
E(Ri_1, Ei);
for (int i = 0; i < 48; ++i) {
Si[i] = Ei[i] ^ Ki[i];
}
for (int i = 0; i < 8; ++i) {
switch (i) {
case 0:
Sbox = S1;
break;
case 1:
Sbox = S2;
break;
case 2:
Sbox = S3;
break;
case 3:
Sbox = S4;
break;
case 4:
Sbox = S5;
break;
case 5:
Sbox = S6;
break;
case 6:
Sbox = S7;
break;
case 7:
Sbox = S8;
break;
}
S(Si, Pi, Sbox, i * 6);
}
P(Pi, f_re);
}

void E(int *Ri_1, int *Ei) {
for (int i = 0; i < 48; ++i) {
Ei[i] = Ri_1[table_E[i] - 1];
}
}

void S(int *Si, int *Pi, int *Sbox, int index) {
int index_p = index * 2 / 3;
int C = 0, D = 0;
C = Si[0 + index] * 2 + Si[5 + index];
D = Si[1 + index] * 8 + Si[2 + index] * 4 + Si[3 + index] * 2 + Si[4 + index] * 1;
InttoBarr(Sbox[C * 16 + D], Pi, index_p, 4);
}

void P(int *Pi, int *f_re) {
for (int i = 0; i < 32; ++i) {
f_re[i] = Pi[table_P[i] - 1];
}
}

void InttoBarr(int dec, int *arr, int index, int bit) {
for (int i = bit - 1; i >= 0; i--) {
if (dec & (1 << i))
arr[(bit - i - 1) + index] = 1;
else
arr[(bit - i - 1) + index] = 0;
}
}

void RotateKeyLeft(int *K, int index) {
int temp;
for (int j = 0; j < index; ++j) {
temp = K[0];
for (int i = 0; i < 27; ++i) {
K[i] = K[i + 1];
}
K[27] = temp;
}
}

void PC2(int *C, int *D, int id) {
int index;
for (int i = 0; i < 48; ++i) {
index = table_PC2[i];
if (index <= 28) {
Keyi[id][i] = C[index - 1];
} else {
Keyi[id][i] = D[index - 29];
}
}
}

void fIV(int *M, int *IV) {
for (int i = 0; i < 64; ++i) {
M[i] ^= IV[i];
}
}

void ascToBinary(int character,int *ones,int index) {
int p = 128;
for (int i=0;i<8;i++) {
ones[i + index] = (character & p) ? 1 : 0;
p /= 2;
}
}

char BinaryToasc(int *ones, int index) {
int re = 0, p = 128;
for (int i = 0; i < 8; ++i) {
re += ones[i + index] * p;
p /= 2;
}
return re;
}

void readBinary(char *temp, int *s) {
int k = 0;
for (int i = 0; i < 64; i += 8) {
ascToBinary(temp[k++], s, i);
}
}

void writeBinary(int *temp, char *s) {
int k = 0;
for (int i = 0; i < 64; i += 8) {
s[k++] = BinaryToasc(temp, i);
}
}

int readFile64(FILE *fd, int *s) {
char temp[64] = {'\0'};
int c;
for (int i = 0; i < 8; ++i) {
c = fgetc(fd);
if (c != EOF) {
temp[i] = (char) c;
} else {
printf("\nEND:%d\n", c);
if (i == 0)return 0;
temp[i] = '\0';
}
}
readBinary(temp, s);
return 1;
}

void writeFile64(FILE *fd, int *s) {
char t[64] = {'\0'};
writeBinary(s, t);
fwrite(t, 8, 1, fd);
}



void closeFile(FILE *fd) {
fclose(fd);
}

* 结果

PS(还是逆DES舒服)