DES加密算法实现

  好久没写博客了,正好趁着实现网络工程与安全的DES算法的功夫,把代码发上来。

  DES的介绍可见:DES加密

  原理不赘述了。。实在太多,其实就是一个形式化算法,按部就班的实现就可以,只不过有些繁琐,我写了3个晚上 = =。

  主要实现了利用DES算法对一个文本文档加密,然后再将其内容解密。

程序截图

  明文和密钥

  加密然后解密

  密文和解密后文本

代码

  1 //该程序实现了文本文档的DES加密和解密。
  2
  3 #include <iostream>
  4 #include <string.h>
  5 #include <stdio.h>
  6 #include <stdlib.h>
  7 using namespace std;
  8
  9 //IP置换表
 10 char IP[64] = {
 11     57,49,41,33,25,17,9,1,
 12     59,51,43,35,27,19,11,3,
 13     61,53,45,37,29,21,13,5,
 14     63,55,47,39,31,23,15,7,
 15     56,48,40,32,24,16,8,0,
 16     58,50,42,34,26,18,10,2,
 17     60,52,44,36,28,20,12,4,
 18     62,54,46,38,30,22,14,6};
 19
 20 //IP^-1 置换表
 21 char IP_1[64] = {
 22     39,7,47,15,55,23,63,31,
 23     38,6,46,14,54,22,62,30,
 24     37,5,45,13,53,21,61,29,
 25     36,4,44,12,52,20,60,28,
 26     35,3,43,11,51,19,59,27,
 27     34,2,42,10,50,18,58,26,
 28     33,1,41,9,49,17,57,25,
 29     32,0,40,8,48,16,56,24};
 30
 31 //扩展置换表E
 32 int E[48] = {31, 0, 1, 2, 3, 4,
 33               3, 4, 5, 6, 7, 8,
 34               7, 8,9,10,11,12,
 35               11,12,13,14,15,16,
 36               15,16,17,18,19,20,
 37               19,20,21,22,23,24,
 38               23,24,25,26,27,28,
 39               27,28,29,30,31, 0};
 40
 41 //置换函数P
 42 int P[32] = {15,6,19,20,28,11,27,16,
 43               0,14,22,25,4,17,30,9,
 44               1,7,23,13,31,26,2,8,
 45               18,12,29,5,21,10,3,24};
 46
 47 //S盒
 48 int S[8][4][16] ={
 49              {{14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7},
 50               {0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8},
 51              {4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0},
 52              {15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13}},
 53
 54               {{15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10},
 55               {3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5},
 56               {0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15},
 57               {13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9}},
 58
 59               {{10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8},
 60               {13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1},
 61               {13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7},
 62               {1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12}},
 63
 64               {{7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15},
 65               {13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9},
 66               {10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4},
 67               {3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14}},
 68
 69               {{2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9},
 70               {14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6},
 71               {4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14},
 72               {11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3}},
 73
 74               {{12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11},
 75               {10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8},
 76               {9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6},
 77               {4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13}},
 78
 79               {{4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1},
 80               {13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6},
 81               {1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2},
 82               {6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12}},
 83
 84               {{13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7},
 85               {1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2},
 86               {7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8},
 87               {2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11}}};
 88 //置换选择1
 89 int PC_1[56] = {56,48,40,32,24,16,8,
 90               0,57,49,41,33,25,17,
 91               9,1,58,50,42,34,26,
 92               18,10,2,59,51,43,35,
 93               62,54,46,38,30,22,14,
 94               6,61,53,45,37,29,21,
 95               13,5,60,52,44,36,28,
 96               20,12,4,27,19,11,3};
 97
 98 //置换选择2
 99 int PC_2[48] = {13,16,10,23,0,4,2,27,
100               14,5,20,9,22,18,11,3,
101               25,7,15,6,26,19,12,1,
102               40,51,30,36,46,54,29,39,
103               50,44,32,47,43,48,38,55,
104               33,52,45,41,49,35,28,31};
105
106 //对左移次数的规定
107 int LS[17] = {0,1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
108
109 //存放子密钥
110 unsigned __int64 K[17];
111
112 //将含64个二进制字符的字符串转换为二进制形式存储在long long int中
113 unsigned __int64 str2bit(unsigned char s[])
114 {
115     unsigned __int64 bin = 0;
116     int i;
117     for(i=0;i<64;i++){
118         bin = bin<<1 | (s[i]-‘0‘);    //s[i]>>j & 1 表示取s[i]的第j位
119     }
120     return bin;
121 }
122
123 //将含8位字符串转换为二进制形式存储在long long int中,例ABCDEFGH转换为64位二进制数
124 unsigned __int64 bstr2bit(unsigned char s[])
125 {
126     unsigned __int64 bin = 0;
127     int i,j;
128     for(i=0;i<8;i++){
129         for(j=0;j<8;j++){
130             bin = bin  |  ( (unsigned __int64)((s[i]>>j)%2) << (j+8*(7-i)) );    //将s[i]的第j位(低位开始)取出放到bin的对应位置
131         }
132     }
133     return bin;
134 }
135
136 //将 unsigned __int64 形式的按十六进制串输出(64位有效的二进制数串)
137 void DisplayHex64(unsigned __int64 bin)
138 {
139     int i,t=0;
140     for(i=63;i>=0;i--){
141         t = t<<1 | ((bin>>i) & 1);
142         if(i%4==0){
143             if(0<=t && t<=9)
144                 printf("%d",t);
145             else if(10<=t && t<=15)
146                 printf("%c",65+t-10);
147             t=0;
148         }
149         if(i%8==0)
150             printf(" ");
151     }
152     printf("\n");
153 }
154 //将 unsigned __int64 形式的按十六进制串输出(48位有效的二进制数串)
155 void DisplayHex48(unsigned __int64 bin)
156 {
157     int i,t=0;
158     for(i=47;i>=0;i--){
159         t = t<<1 | ((bin>>i) & 1);
160         if(i%4==0){
161             if(0<=t && t<=9)
162                 printf("%d",t);
163             else if(10<=t && t<=15)
164                 printf("%c",65+t-10);
165             t=0;
166         }
167         if(i%8==0)
168             printf(" ");
169     }
170     printf("\n");
171 }
172 //将 unsigned __int64 形式的按十六进制串输出(32位有效的二进制数串)
173 void DisplayHex32(unsigned __int64 bin)
174 {
175     int i,t=0;
176     for(i=31;i>=0;i--){
177         t = t<<1 | ((bin>>i) & 1);
178         if(i%4==0){
179             if(0<=t && t<=9)
180                 printf("%d",t);
181             else if(10<=t && t<=15)
182                 printf("%c",65+t-10);
183             t=0;
184         }
185         if(i%8==0)
186             printf(" ");
187     }
188     printf("\n");
189 }
190 //将 unsigned __int64 形式的按十六进制串输出(28位有效的二进制数串)
191 void DisplayHex28(unsigned __int64 bin)
192 {
193     int i,t=0;
194     for(i=27;i>=0;i--){
195         t = t<<1 | ((bin>>i) & 1);
196         if(i%4==0){
197             if(0<=t && t<=9)
198                 printf("%d",t);
199             else if(10<=t && t<=15)
200                 printf("%c",65+t-10);
201             t=0;
202         }
203         if(i%8==0)
204             printf(" ");
205     }
206     printf("\n");
207 }
208
209 //将 unsigned __int64 形式的二进制串和十六进制输出(64位有效的二进制数串)
210 void DisplayBin64(unsigned __int64 bin)
211 {
212     int i;
213     for(i=63;i>=0;i--){
214         printf("%d",(bin>>i) %2);
215     }
216     printf("\n");
217     DisplayHex64(bin);
218 }
219
220 //将 unsigned __int64 形式的二进制串和十六进制输出(48位有效的二进制数串)
221 void DisplayBin48(unsigned __int64 bin)
222 {
223     int i;
224     for(i=47;i>=0;i--){
225         printf("%d",(bin>>i) %2);
226     }
227     printf("\n");
228     DisplayHex48(bin);
229 }
230
231 //将 unsigned __int64 形式的二进制串和十六进制输出(32位有效的二进制数串)
232 void DisplayBin32(unsigned __int64 bin)
233 {
234     int i;
235     for(i=31;i>=0;i--){
236         printf("%d",(bin>>i) %2);
237     }
238     printf("\n");
239     DisplayHex32(bin);
240 }
241
242 //将 unsigned __int64 形式的二进制串和十六进制输出(28位有效的二进制数串)
243 void DisplayBin28(unsigned __int64 bin)
244 {
245     int i;
246     for(i=27;i>=0;i--){
247         printf("%d",(bin>>i) %2);
248     }
249     printf("\n");
250     DisplayHex28(bin);
251 }
252
253
254 /* ------------------------------ 【1】初始置换IP ------------------------------
255  *        把明文顺序打乱重新排列,置换输出为64位,
256  *    数据置换后的第一位,第二位分别是原来的58、50位
257  */
258
259 unsigned __int64 InitReplace(unsigned __int64 bin)    //初始置换IP
260 {
261     unsigned __int64 t = 0;
262     int i;
263     for(i=0;i<64;i++){
264         t = t | ( (bin>>(63-IP[i])) %2) << (63-i);
265     }
266     return t;
267 }
268
269 /* ------------------------------ 【2】将置换输出的64位数据分成左右两半 ------------------------------
270  *        左一半称为L0,右一半称为R0,各32位。
271  */
272
273 void DivideLR(unsigned __int64 binip,unsigned __int64 &L0,unsigned __int64 &R0)    //将置换输出的64位数据分为L0(32位),R0(32位)两部分
274 {
275     unsigned __int64 one = 1;
276     L0 = binip >> 32;
277     R0 = binip % (one<<32);
278 }
279
280 /* ------------------------------ 【3】计算函数的16轮迭代 ------------------------------
281  *        1~16轮加密迭代
282  */
283
284 //置换选择1,64->56
285 unsigned __int64 FunPC_1(unsigned __int64 bink)
286 {
287     unsigned __int64 binpc_1 = 0;
288     int i;
289     for(i=0;i<56;i++)
290         binpc_1 |= ( (bink>>(63-PC_1[i])) %2) << (55-i);
291     return binpc_1;
292 }
293
294 //获得第i轮C,D,即Ci-1,Di-1 ==> Ci,Di
295 void getNextCD(int i,unsigned __int64 &C,unsigned __int64 &D)
296 {
297     unsigned __int64 t=0,one=1;
298     t = C >> (28-LS[i]);
299     C = (C<<LS[i])%(one<<28);
300     C |= t;
301     t = D >> (28-LS[i]);
302     D = (D<<LS[i])%(one<<28);
303     D |= t;
304 }
305
306 //置换选择2,56->48
307 unsigned __int64 FunPC_2(unsigned __int64 t)
308 {
309     //获得子密钥k
310     unsigned __int64 k=0;
311     int i;
312     for(i=0;i<48;i++)
313         k |= ( (t>>(55-PC_2[i])) %2) << (47-i);
314     return k;
315 }
316
317 //子密钥生成
318 void ProduceK(unsigned __int64 bink)
319 {
320     unsigned __int64 binpc_1,one=1,C=0,D=0;
321     binpc_1 = FunPC_1(bink);    //置换选择1
322
323     //分成2个28位
324     C = binpc_1 >> 28;
325     D = binpc_1 % (one << 28);
326
327     int i;
328     for(i=1;i<=16;i++){
329         //确定子密钥K[i]
330         getNextCD(i,C,D);
331         printf("第%d轮:\n",i);
332         printf("C[%d] = ",i);
333         DisplayBin28(C);
334         printf("D[%d] = ",i);
335         DisplayBin28(D);
336         printf("\n");
337
338         unsigned __int64 t=0;
339         t = ((C<<28) | D)%(one<<56);
340         K[i] = FunPC_2(t);    //进行置换选择2,将56位->48位子密钥
341     }
342 }
343
344 //扩展置换E,32->48
345 unsigned __int64 FunE(unsigned __int64 R)
346 {
347     unsigned __int64 t = 0;
348     int i;
349     for(i=0;i<48;i++)
350         t |= ( (R>>(31-E[i])) %2) << (47-i);
351     return t;
352 }
353
354 //S盒代换
355 unsigned __int64 FunS(unsigned __int64 RX)
356 {
357     int x,y,i;
358     unsigned __int64 one = 1,t,RS = 0;
359     for(i=0;i<8;i++){
360         t = ( RX >> (6*(7-i)) ) % (one<<6);
361         x = t>>5;
362         x = (x<<1) | (t%2);
363         y = (t<<1)%(one<<6)>>2;
364         RS = RS<<4 | S[i][x][y];
365     }
366     return RS;
367 }
368
369 //置换P运算
370 unsigned __int64 FunP(unsigned __int64 RS)
371 {
372     unsigned __int64 RP = 0;
373     int i;
374     for(i=0;i<32;i++)
375         RP |= ( (RS>>(31-P[i])) %2) << (31-i);
376     return RP;
377 }
378
379 //轮函数f(R,K)
380 unsigned __int64 f(int i,unsigned __int64 R,unsigned __int64 k)
381 {
382     unsigned __int64 RE,RX,RS,RP;
383     RE = FunE(R);    //将32位Ri-1扩展置换为48位
384     RX = RE ^ k;    //将48位RE与子密钥k异或运算
385     RS = FunS(RX);    //S盒代换
386     RP = FunP(RS);        //置换P运算
387     return RP;
388 }
389
390 unsigned __int64 Iteration16(unsigned __int64 L0,unsigned __int64 R0)    //进行16次迭代计算
391 {
392     int i;
393     unsigned __int64 Ri = R0;
394     unsigned __int64 Li = L0;
395     printf("L0=");
396     DisplayBin32(L0);
397     printf("R0=");
398     DisplayBin32(R0);
399     printf("\n");
400     for(i=1;i<=16;i++){
401         printf("第%d轮加密:\n",i);
402         unsigned __int64 t = Ri;
403
404         //轮函数
405         Ri = f(i,Ri,K[i]);
406         printf("f(R%d,K%d)=",i-1,i);
407         DisplayBin32(Ri);
408
409         //Li-1和轮函数结果异或运算得到Ri
410         Ri = Li ^ Ri;
411         //轮函数运算结果即是Li
412         Li = t;
413
414         //输出Li和Ri
415         printf("L%d=",i);
416         DisplayBin32(Li);
417         printf("R%d=",i);
418         DisplayBin32(Ri);
419         printf("\n");
420     }
421
422     return Ri<<32 | Li;
423 }
424
425 unsigned __int64 InverseIteration16(unsigned __int64 L0,unsigned __int64 R0)    //进行逆16次迭代计算,为解密过程
426 {
427     int i;
428     unsigned __int64 Ri = R0;
429     unsigned __int64 Li = L0;
430     printf("L0=");
431     DisplayBin32(L0);
432     printf("R0=");
433     DisplayBin32(R0);
434     printf("\n");
435     for(i=16;i>=1;i--){
436         printf("第%d轮加密:\n",17-i);
437         unsigned __int64 t = Ri;
438
439         //轮函数
440         Ri = f(i,Ri,K[i]);
441         printf("f(R%d,K%d)=",i-1,i);
442         DisplayBin32(Ri);
443
444         //Li-1和轮函数结果异或运算得到Ri
445         Ri = Li ^ Ri;
446         //轮函数运算结果即是Li
447         Li = t;
448
449         //输出Li和Ri
450         printf("L%d=",i);
451         DisplayBin32(Li);
452         printf("R%d=",i);
453         DisplayBin32(Ri);
454         printf("\n");
455     }
456
457     return Ri<<32 | Li;
458 }
459
460
461
462 /* ------------------------------ 【4】逆初始置换IP^-1 ------------------------------
463  *        把数据打乱重排,产生64位密文。
464  */
465
466 unsigned __int64 InverseInitReplace(unsigned __int64 bin)    //进行逆初始置换IP^-1
467 {
468     unsigned __int64 t = 0;
469     int i;
470     for(i=0;i<64;i++){
471         t = t | ( (bin>>(63-IP_1[i])) %2) << (63-i);
472     }
473     return t;
474 }
475
476 void printOut(FILE* fo,unsigned __int64 bin)
477 {
478     char ans[8]={0},t=0;
479     int i,cnt=0;
480     for(i=63;i>=0;i--){
481         t = t<<1 | ((bin>>i)%2);
482         if(i%8==0){
483             ans[cnt++] = t;
484             t = 0;
485         }
486     }
487     fwrite(ans,1,8,fo);
488 }
489
490 //加密函数
491 void Encryption()
492 {
493     //文件读入
494     FILE* fm = fopen(".\\Plaintext.txt","rb");    //明文文件
495     FILE* fk = fopen(".\\key.txt","r");    //密钥文件
496     FILE* fo = fopen(".\\Ciphertext.txt","wb");    //密文文件
497
498     if(fm==NULL){
499         printf("明文文件input.txt打开失败\n");
500     }
501     if(fk==NULL){
502         printf("密钥文件key.txt打开失败\n");
503     }
504     if(fo==NULL){
505         printf("加密后文件output.txt打开失败\n");
506     }
507
508     unsigned char s[165]={0},key[65]={0};
509     int i;
510
511     fscanf(fk,"%s",key);    //读取密钥
512
513     while(fread(s,1,8,fm)){
514         printf("----------------------------------------------------------------------------\n");
515         printf("\n");
516         printf("当前读取的明文串为:\n");
517         printf("%s\n",s);
518         unsigned __int64 bin = bstr2bit(s);    //将加密串转换为2进制形式
519         printf("\n");
520         unsigned __int64 bink = str2bit(key);    //将密钥串转换为2进制形式
521         printf("\n");
522
523         //输出
524         printf("\n");
525         printf("【输入】\n");
526         printf("输入的二进制明文串:\n");
527         DisplayBin64(bin);
528         printf("输入的二进制密钥串:\n");
529         DisplayBin64(bink);
530         printf("\n");
531
532         //IP置换
533         printf("明文初始化置换后:\n");
534         unsigned __int64 binip = InitReplace(bin);
535         DisplayBin64(binip);
536         printf("\n");
537
538         //获得L0,R0
539         printf("将明文分割为L0,R0两部分:\n");
540         unsigned __int64 L0,R0;
541         DivideLR(binip,L0,R0);    //将binip分割为L0和R0
542         //输出L0,R0
543         printf("L0为:");
544         DisplayBin32(L0);
545         printf("R0为:");
546         DisplayBin32(R0);
547         printf("\n");
548
549         //生成16个子密钥,并输出
550         printf("--------------- 子密钥生成过程 ---------------\n");
551         memset(K,0,sizeof(K));
552         ProduceK(bink);
553         printf("生成的16个子密钥:\n");
554         for(i=1;i<=16;i++){
555             printf("K[%d]为 ",i);
556             DisplayBin48(K[i]);
557             //printf("\n");
558         }
559         printf("\n");
560
561         //16次加密迭代
562         printf("---------------  16轮加密迭代 --------------- \n");
563         unsigned __int64 binIter = Iteration16(L0,R0);
564         printf("迭代加密后的结果:\n");
565         DisplayBin64(binIter);
566         printf("\n");
567
568         //逆初始置换IP_1
569         unsigned __int64 binip_1 = InverseInitReplace(binIter);
570         printf("最后,逆初始置换:\n");
571         DisplayBin64(binip_1);
572         printf("\n");
573
574         //输出最终加密结果
575         printf("【加密结果】\n明文 \"%s\" 的DES加密的结果为:\n",s);
576         DisplayBin64(binip_1);
577
578         printf("\n");
579         printf("----------------------------------------------------------------------------\n");
580         printf("\n");
581
582         //将加密结果写到加密文件中
583         printOut(fo,binip_1);
584
585         memset(s,0,sizeof(s));
586     }
587     //文件关闭
588     fclose(fm);
589     fclose(fk);
590     fclose(fo);
591 }
592
593 //解密函数
594 void Decryption()
595 {
596     //文件读入
597     FILE* fm = fopen(".\\Ciphertext.txt","rb");    //密文文件
598     FILE* fk = fopen(".\\key.txt","r");    //密钥文件
599     FILE* fo = fopen(".\\DecrypPlaintext.txt","wb");    //解密后文件
600
601     if(fm==NULL){
602         printf("密文文件 Ciphertext.txt 打开失败\n");
603     }
604     if(fk==NULL){
605         printf("密钥文件 key.txt 打开失败\n");
606     }
607     if(fo==NULL){
608         printf("解密后文件 DecrypPlaintext.txt 打开失败\n");
609     }
610
611     unsigned char s[165]={0},key[65]={0};
612     int i;
613
614     fscanf(fk,"%s",key);    //读取密钥
615
616     while(fread(s,1,8,fm)){
617         printf("----------------------------------------------------------------------------\n");
618         printf("\n");
619         printf("当前读取的密文串为:\n");
620         printf("%s\n",s);
621         unsigned __int64 bin = bstr2bit(s);    //将密文串转换为2进制形式
622         printf("\n");
623         unsigned __int64 bink = str2bit(key);    //将密钥串转换为2进制形式
624         printf("\n");
625
626         //输出
627         printf("----------------------------------------------------------------------------\n");
628         printf("\n");
629         printf("【输入】\n");
630         printf("输入的二进制密文串:\n");
631         DisplayBin64(bin);
632         printf("输入的二进制密钥串:\n");
633         DisplayBin64(bink);
634         printf("\n");
635
636         //IP置换
637         printf("密文初始化置换后:\n");
638         unsigned __int64 binip = InitReplace(bin);
639         DisplayBin64(binip);
640         printf("\n");
641
642         //获得L0,R0
643         printf("将密文分割为L0,R0两部分:\n");
644         unsigned __int64 L0,R0;
645         DivideLR(binip,L0,R0);    //将binip分割为L0和R0
646         //输出L0,R0
647         printf("L0为:");
648         DisplayBin32(L0);
649         printf("R0为:");
650         DisplayBin32(R0);
651         printf("\n");
652
653         //生成16个子密钥,并输出
654         printf("--------------- 子密钥生成过程 ---------------\n");
655         memset(K,0,sizeof(K));
656         ProduceK(bink);
657         printf("生成的16个子密钥:\n");
658         for(i=1;i<=16;i++){
659             printf("K[%d]为 ",i);
660             DisplayBin48(K[i]);
661             //printf("\n");
662         }
663         printf("\n");
664
665         //16次加密迭代
666         printf("---------------  16轮加密迭代 --------------- \n");
667         unsigned __int64 binIter = InverseIteration16(L0,R0);
668         printf("迭代解密后的结果:\n");
669         DisplayBin64(binIter);
670         printf("\n");
671
672         //逆初始置换IP_1
673         unsigned __int64 binip_1 = InverseInitReplace(binIter);
674         printf("最后,逆初始置换:\n");
675         DisplayBin64(binip_1);
676         printf("\n");
677
678         //输出最终加密结果
679         printf("【解密结果】\n密文 \"%s\" 的DES解密的结果为:\n",s);
680         DisplayBin64(binip_1);
681
682         printf("\n");
683         printf("----------------------------------------------------------------------------\n");
684
685         //将加密结果写到加密文件中
686         printOut(fo,binip_1);
687
688         memset(s,0,sizeof(s));
689     }
690     //文件关闭
691     fclose(fm);
692     fclose(fk);
693     fclose(fo);
694 }
695
696 int Menu(int &Case)
697 {
698     int in;
699
700     FILE* fk = fopen(".\\key.txt","r");    //密钥文件
701     if(fk==NULL){
702         printf("密钥文件key.txt打开失败\n");
703     }
704
705     unsigned char key[100];
706     fscanf(fk,"%s",key);    //读取密钥
707     unsigned __int64 bink = str2bit(key);    //将密钥串转换为2进制形式
708     printf("【%d】当前密钥(key)为:(二进制形式)\n",Case++);
709     DisplayBin64(bink);
710     printf("(密钥存储在 key.txt 中)\n");
711     printf("\n");
712
713     printf("请选择,是使用DES算法加密还是解密?\n");
714     printf("(加密过程:Plaintext.txt => Ciphertext.txt\n");
715     printf(" 解密过程:Ciphertext.txt => DecrypPlaintext.txt )\n");
716     printf("[1] 加密\n");
717     printf("[2] 解密\n");
718     printf("[0] 退出程序\n");
719
720     scanf("%d",&in);
721     getchar();
722     fflush(stdin);    //    清空缓冲区
723
724     if(in==0 || in==1 || in==2){
725         return in;
726     }
727     else{
728         printf("输入错误,请重新输入!\n");
729         printf("\n");
730         printf("----------------------------------------------------------------------------\n");
731         printf("\n");
732         return -1;
733     }
734 }
735
736 /*
737  * 主函数
738  */
739 int main()
740 {
741     int Case=1,in;
742     while(1){
743         in = Menu(Case);
744         switch(in){
745         case -1:    //输入错误,进入下次循环
746             break;
747         case 0:        //退出程序
748             printf("谢谢使用 :)\n");
749             return 0;
750         case 1:        //加密
751             Encryption();
752             break;
753         case 2:        //解密
754             Decryption();
755             break;
756         }
757     }
758     return 0;
759 }

Freecode : www.cnblogs.com/yym2013

时间: 2024-10-11 22:10:25

DES加密算法实现的相关文章

JAVA使用DES加密算法加密解密

程序中使用了.properties文件作为参数配置文档,好处是灵活配置各项参数 一旦对数据库的一些参数进行了配置,势必涉及数据库的IP,端口,用户名和密码 properties文件全是unicode编码明文存储,程序打包交付后,其他人能够很容易使用解压软件打开jar查看你的.properties文件 所以一些敏感变量需要加密处理 首先需要了解一些基本的加密算法,比如MD5,比如DES和RSA MD5是一种不可逆的加密算法,使用散列后特征码的方式表现需要加密的字符或者文件,常用在系统登陆的密码比对

浅谈DES加密算法

一.DES加密算法介绍 1.要求密钥必须是8个字节,即64bit长度 2.因为密钥是byte[8] , 代表字符串也可以是非可见的字节,可以与Base64编码算法一起使用 3.加密.解密都需要通过字节数组作为数据和密钥进行处理 二.对称加密 DES加密算法属于对称加密. 即利用指定的密钥,按照密码的长度截取数据,分成数据块,和密钥进行复杂的移位.算数运算或者数据处理等操作,形成只有特定的密码才能够解开的数据. 加密与解密用的是同一个密钥 三.相关类 1.Cipher: Java/Android要

DES加密算法详解- -

DES加密算法详解- - 对加密解密一直挺喜欢的,可还是没有怎么好好学习过,希望这是一个好的开始. 在网上搜了一下关于DES的说明,发现有些杂乱,所以还是有必要整合一下. 写了一点代码,还没有完成,不过,还不能编译通过,^_^ 刚看了一下,发现还是说得够模糊的,有机会再整理一下. 昏倒,一直运行不对,今天才仔细查出来,原来问题是出在Des_Data_P(const_b32& input, _b32 output), 我的output用了传值调用,失败呀.应该是Des_Data_P(const _

DES加密算法原理

DES的每个分组是64位,既明文和密钥都是64位(密钥实际用56位,每字节第8位为校验).这个算法的核心是Feistel密码,由于其设计的巧妙,加密解密都用一个函数,具体原理请查阅其他资料.DES的流程基本是执行16轮下面的运算: 1 初始变换Initial Permutation 2 右边32位f函数 2.1 E置换 2.2 与轮密钥XOR 2.3 S盒替换 2.4 P置换 2.5 和左边32位XOR 3 左右交换,最终变换final permutation 需要特别注意的是,最后一轮是不需要

DES加密算法的实现

本文内容: 1. 对称加密 2. 数据加密标准 3. 用c++程序实现DES加密和解密 4. 实验效果 一.对称加密 对称加密也称为常规加密.私钥或单钥加密. 一个对称加密由5部分组成: - 明文(plaintext):这是原始信息或数据,作为算法的输入. - 加密算法(encryption algorithm):加密算法对明文进行各种替换和转换. - 密钥(secret key):密钥也是算法的输入.算法进行的具体替换和转换取决于密钥. - 密文(ciphertext):这是产生的已被打乱的消

android和.net webservice中的DES加密算法

也是看了一堆的例子,本身并不会写加密算法,好在只要会用就行了,我们把在app中使用的参数加密,然后在.net端的webservice中进行解密,本身并没有什么问题,但是android下和.net下的des加密算法有些不同,写下供以后使用. android端的DES. public class DES { private static byte[] iv = { 1, 2, 3, 4, 5, 6, 7, 8 }; //加密. public static String encryptDES(Stri

.net中DES加密算法研究

/// <summary> /// DES加密算法 /// </summary> /// <param name="toEncrypt">要加密的16进制字符串</param> /// <param name="_DESKey">16进制密钥</param> /// <returns>加密后的结果</returns> public string DESEncrypt(st

在.NET Core 里使用 BouncyCastle 的DES加密算法

.NET Core上面的DES等加密算法要等到1.2 才支持,我们可是急需这个算法的支持,文章<使用 JavaScriptService 在.NET Core 里实现DES加密算法>需要用Nodejs,很多人觉得这个有点不好,今天就给大家介绍下BouncyCastle (Portable.BouncyCastle)https://www.nuget.org/packages/Portable.BouncyCastle/库为我们提供的原生的.NET Core的支持库的Des算法.BouncyCa

对称密码——DES加密算法

前言 本篇博文将介绍对称密码算法中的DES密码的算法原理与代码实现(Java) DES算法原理 DES加密算法是对称加密算法(加密和解密使用同一个密钥)中的一种,DES也是分组密码,以64位为分组对明文进行加密. DES算法会对明文进行16轮的迭代加密,具体的算法过程可以看下面这图(来自文末参考博文中的图,做了一些修改).看一遍有点绕就那笔跟着走一遍. 下面这张图是每次迭代的的一个提取,我们从中可以直接观察到的就是迭代的两个规律: Li = Ri-1 Ri = Li-1 ^ F(Ri-1, Ki

DES加密算法详细原理以及Java代码实现

本周的密码学实验要求使用任意编程语言来实现des加密算法,于是我在查阅了相关资料后有了以下成果. 首先,DES算法作为经典的分块密码(block cipher),其主要的实现过程由两部分组成,分别是密钥的生成以及明文的处理. 加密的大致流程如图所示 作为分块密码,密钥的输入以及明文的输入均为64位2进制数. 下面首先来说密钥的生成过程. 密钥处理部分如图所示 密钥的输入为64位,例如00010011 00110100 01010111 01111001 10011011 10111100 110