求教des算法的详细过程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求教des算法的详细过程相关的知识,希望对你有一定的参考价值。

开始是一个p置换,把加密的明文和密文打乱,然后是怎么压缩一下,最后是个16个s盒,再初始置换得到密文。具体什么流程大家详细讲下,还有那里面的公式我看不明白

图为最详细的流程 

下附上完整C程序,我自己做的,你看看。

#include "stdio.h"

#include "memory.h"

#include "time.h"

#include "stdlib.h"

  

#define PLAIN_FILE_OPEN_ERROR -1

#define KEY_FILE_OPEN_ERROR -2

#define CIPHER_FILE_OPEN_ERROR -3

#define OK 1 

typedef char ElemType; 

 /*初始置换表IP*/

int 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*/

int 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*/

int 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*/

int P_Table[32] = 15,6,19,20,28,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盒*/

int 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*/

  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,

  /*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,

  /*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,

  /*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,

  /*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,

  /*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,

  /*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;

/*置换选择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;

  

/*对左移次数的规定*/

int MOVE_TIMES[16] = 1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1;  

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_PC1_Transform(ElemType key[64], ElemType tempbts[56]);

int DES_PC2_Transform(ElemType key[56], ElemType tempbts[48]);

int DES_ROL(ElemType data[56], int time);

int DES_IP_Transform(ElemType data[64]);

int DES_IP_1_Transform(ElemType data[64]);

int DES_E_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], ElemType cipherBlock[8]);

int DES_DecryptBlock(ElemType cipherBlock[8], ElemType subKeys[16][48], ElemType plainBlock[8]);

int DES_Encrypt(char *plainFile, char *keyStr,char *cipherFile);

int DES_Decrypt(char *cipherFile, char *keyStr,char *plainFile);  

/*字节转换成二进制*/

int ByteToBit(ElemType ch, ElemType bit[8])

 int cnt;

 for(cnt = 0;cnt < 8; cnt++)

  *(bit+cnt) = (ch>>cnt)&1;

 

 return 0;

  

/*二进制转换成字节*/

int BitToByte(ElemType bit[8],ElemType *ch)

 int cnt;

 for(cnt = 0;cnt < 8; cnt++)

  *ch |= *(bit + cnt)<<cnt;

 

 return 0;

  

/*将长度为8的字符串转为二进制位串*/

int Char8ToBit64(ElemType ch[8],ElemType bit[64])

 int cnt;

 for(cnt = 0; cnt < 8; cnt++)  

  ByteToBit(*(ch+cnt),bit+(cnt<<3));

 

 return 0;

  

/*将二进制位串转为长度为8的字符串*/

int Bit64ToChar8(ElemType bit[64],ElemType ch[8])

 int cnt;

 memset(ch,0,8);

 for(cnt = 0; cnt < 8; cnt++)

  BitToByte(bit+(cnt<<3),ch+cnt);

 

 return 0;

  

/*生成子密钥*/

int DES_MakeSubKeys(ElemType key[64],ElemType subKeys[16][48])

 ElemType temp[56];

 int cnt;

 DES_PC1_Transform(key,temp);/*PC1置换*/

 for(cnt = 0; cnt < 16; cnt++)/*16轮跌代,产生16个子密钥*/

  DES_ROL(temp,MOVE_TIMES[cnt]);/*循环左移*/

  DES_PC2_Transform(temp,subKeys[cnt]);/*PC2置换,产生子密钥*/

 

 return 0;

  

/*密钥置换1*/

int DES_PC1_Transform(ElemType key[64], ElemType tempbts[56])

 int cnt; 

 for(cnt = 0; cnt < 56; cnt++)

  tempbts[cnt] = key[PC_1[cnt]];

 

 return 0;

  

/*密钥置换2*/

int DES_PC2_Transform(ElemType key[56], ElemType tempbts[48])

 int cnt;

 for(cnt = 0; cnt < 48; cnt++)

  tempbts[cnt] = key[PC_2[cnt]];

 

 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])

 int cnt;

 ElemType temp[64];

 for(cnt = 0; cnt < 64; cnt++)

  temp[cnt] = data[IP_Table[cnt]];

 

 memcpy(data,temp,64);

 return 0;

  

/*IP逆置换*/

int DES_IP_1_Transform(ElemType data[64])

 int cnt;

 ElemType temp[64];

 for(cnt = 0; cnt < 64; cnt++)

  temp[cnt] = data[IP_1_Table[cnt]];

 

 memcpy(data,temp,64);

 return 0;

  

/*扩展置换*/

int DES_E_Transform(ElemType data[48])

 int cnt;

 ElemType temp[48];

 for(cnt = 0; cnt < 48; cnt++)

  temp[cnt] = data[E_Table[cnt]];

 

 memcpy(data,temp,48);

 return 0;

  

/*P置换*/

int DES_P_Transform(ElemType data[32])

 int cnt;

 ElemType temp[32];

 for(cnt = 0; cnt < 32; cnt++)

  temp[cnt] = data[P_Table[cnt]];

 

 memcpy(data,temp,32);

 return 0;

  

/*异或*/

int DES_XOR(ElemType R[48], ElemType L[48] ,int count)

 int cnt;

 for(cnt = 0; cnt < count; cnt++)

  R[cnt] ^= L[cnt];

 

 return 0;

  

/*S盒置换*/

int DES_SBOX(ElemType data[48])

 int cnt;

 int line,row,output;

 int cur1,cur2;

 for(cnt = 0; cnt < 8; cnt++)

  cur1 = cnt*6;

  cur2 = cnt<<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[cnt][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], ElemType cipherBlock[8])

 ElemType plainBits[64];

 ElemType copyRight[48];

 int cnt;

  

 Char8ToBit64(plainBlock,plainBits);  

 /*初始置换(IP置换)*/

 DES_IP_Transform(plainBits);

  

 /*16轮迭代*/

 for(cnt = 0; cnt < 16; cnt++) 

  memcpy(copyRight,plainBits+32,32);

  /*将右半部分进行扩展置换,从32位扩展到48位*/

  DES_E_Transform(copyRight);

  /*将右半部分与子密钥进行异或操作*/

  DES_XOR(copyRight,subKeys[cnt],48); 

  /*异或结果进入S盒,输出32位结果*/

  DES_SBOX(copyRight);

  /*P置换*/

  DES_P_Transform(copyRight);

  /*将明文左半部分与右半部分进行异或*/

  DES_XOR(plainBits,copyRight,32);

  if(cnt != 15)

/*最终完成左右部的交换*/

DES_Swap(plainBits,plainBits+32);

  

 

 /*逆初始置换(IP^1置换)*/

 DES_IP_1_Transform(plainBits);

 Bit64ToChar8(plainBits,cipherBlock);

 return 0;

  

/*解密单个分组*/

int DES_DecryptBlock(ElemType cipherBlock[8], ElemType subKeys[16][48],ElemType plainBlock[8])

 ElemType cipherBits[64];

 ElemType copyRight[48];

 int cnt;

  

 Char8ToBit64(cipherBlock,cipherBits); 

 /*初始置换(IP置换)*/

 DES_IP_Transform(cipherBits);

 

 /*16轮迭代*/

 for(cnt = 15; cnt >= 0; cnt--)

  memcpy(copyRight,cipherBits+32,32);

  /*将右半部分进行扩展置换,从32位扩展到48位*/

  DES_E_Transform(copyRight);

  /*将右半部分与子密钥进行异或操作*/

  DES_XOR(copyRight,subKeys[cnt],48);  

  /*异或结果进入S盒,输出32位结果*/

  DES_SBOX(copyRight);

  /*P置换*/

  DES_P_Transform(copyRight);  

  /*将明文左半部分与右半部分进行异或*/

  DES_XOR(cipherBits,copyRight,32);

  if(cnt != 0)

/*最终完成左右部的交换*/

DES_Swap(cipherBits,cipherBits+32);

  

 

 /*逆初始置换(IP^1置换)*/

 DES_IP_1_Transform(cipherBits);

 Bit64ToChar8(cipherBits,plainBlock);

 return 0;

  

/*加密文件*/

int DES_Encrypt(char *plainFile, char *keyStr,char *cipherFile)

 FILE *plain,*cipher;

 int count;

 ElemType plainBlock[8],cipherBlock[8],keyBlock[8];

 ElemType bKey[64];

 ElemType subKeys[16][48];

 if((plain = fopen(plainFile,"rb")) == NULL)

  return PLAIN_FILE_OPEN_ERROR;

 

 if((cipher = fopen(cipherFile,"wb")) == NULL)

  return CIPHER_FILE_OPEN_ERROR;

 

 /*设置密钥*/

 memcpy(keyBlock,keyStr,8);

 /*将密钥转换为二进制流*/

 Char8ToBit64(keyBlock,bKey);

 /*生成子密钥*/

 DES_MakeSubKeys(bKey,subKeys);

 

 while(!feof(plain))

  /*每次读8个字节,并返回成功读取的字节数*/

  if((count = fread(plainBlock,sizeof(char),8,plain)) == 8)

DES_EncryptBlock(plainBlock,subKeys,cipherBlock);

fwrite(cipherBlock,sizeof(char),8,cipher);  

  

 

 if(count)

  /*填充*/

  memset(plainBlock + count,'\\0',7 - count);

  /*最后一个字符保存包括最后一个字符在内的所填充的字符数量*/

  plainBlock[7] = 8 - count;

  DES_EncryptBlock(plainBlock,subKeys,cipherBlock);

  fwrite(cipherBlock,sizeof(char),8,cipher);

 

 fclose(plain);

 fclose(cipher);

 return OK;

  

/*解密文件*/

int DES_Decrypt(char *cipherFile, char *keyStr,char *plainFile)

 FILE *plain, *cipher;

 int count,times = 0;

 long fileLen;

 ElemType plainBlock[8],cipherBlock[8],keyBlock[8];

 ElemType bKey[64];

 ElemType subKeys[16][48];

 if((cipher = fopen(cipherFile,"rb")) == NULL)

  return CIPHER_FILE_OPEN_ERROR;

 

 if((plain = fopen(plainFile,"wb")) == NULL)

  return PLAIN_FILE_OPEN_ERROR;

 

  

 /*设置密钥*/

 memcpy(keyBlock,keyStr,8);

 /*将密钥转换为二进制流*/

 Char8ToBit64(keyBlock,bKey);

 /*生成子密钥*/

 DES_MakeSubKeys(bKey,subKeys);

  

 /*取文件长度 */

 fseek(cipher,0,SEEK_END);/*将文件指针置尾*/

 fileLen = ftell(cipher); /*取文件指针当前位置*/

 rewind(cipher); /*将文件指针重指向文件头*/

 while(1)

  /*密文的字节数一定是8的整数倍*/

  fread(cipherBlock,sizeof(char),8,cipher);

  DES_DecryptBlock(cipherBlock,subKeys,plainBlock);  

  times += 8;

  if(times < fileLen)

fwrite(plainBlock,sizeof(char),8,plain);

  

  else

break;

  

 

 /*判断末尾是否被填充*/

 if(plainBlock[7] < 8)

  for(count = 8 - plainBlock[7]; count < 7; count++)

if(plainBlock[count] != '\\0')

 break;

  

 

 if(count == 7)/*有填充*/

  fwrite(plainBlock,sizeof(char),8 - plainBlock[7],plain);

 

 else/*无填充*/

  fwrite(plainBlock,sizeof(char),8,plain);

 

  

 fclose(plain);

 fclose(cipher);

 return OK;

  

int main()

 clock_t a,b;

 a = clock();

 DES_Encrypt("1.txt","key.txt","2.txt");

 b = clock();

 printf("加密消耗%d毫秒\\n",b-a);

 

 system("pause");

 a = clock();

 DES_Decrypt("2.txt","key.txt","3.txt");

 b = clock();

 printf("解密消耗%d毫秒\\n",b-a);

 getchar();

 return 0;

参考技术A     des算法的详细过程:
  1-1、变换密钥
  取得64位的密钥,每个第8位作为奇偶校验位。
  1-2、变换密钥。
  1-2-1、舍弃64位密钥中的奇偶校验位,根据下表(PC-1)进行密钥变换得到56位的密钥,在变换中,奇偶校验位以被舍弃。
  Permuted Choice 1 (PC-1)
  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
  1-2-2、将变换后的密钥分为两个部分,开始的28位称为C[0],最后的28位称为D[0]。
  1-2-3、生成16个子密钥,初始I=1。
  1-2-3-1、同时将C[I]、D[I]左移1位或2位,根据I值决定左移的位数。见下表
  I: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
  左移位数: 1 1 2 2 2 2 2 2 1 2 2 2 2 2 2 1
  1-2-3-2、将C[I]D[I]作为一个整体按下表(PC-2)变换,得到48位的K[I]
  Permuted Choice 2 (PC-2)
  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-2-3-3、从1-2-3-1处循环执行,直到K[16]被计算完成。
  2、处理64位的数据
  2-1、取得64位的数据,如果数据长度不足64位,应该将其扩展为64位(例如补零)
  2-2、将64位数据按下表变换(IP)
  Initial Permutation (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
  2-3、将变换后的数据分为两部分,开始的32位称为L[0],最后的32位称为R[0]。
  2-4、用16个子密钥加密数据,初始I=1。
  2-4-1、将32位的R[I-1]按下表(E)扩展为48位的E[I-1]
  Expansion (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
  2-4-2、异或E[I-1]和K[I],即E[I-1] XOR K[I]
  2-4-3、将异或后的结果分为8个6位长的部分,第1位到第6位称为B[1],第7位到第12位称为B[2],依此类推,第43位到第48位称为B[8]。
  2-4-4、按S表变换所有的B[J],初始J=1。所有在S表的值都被当作4位长度处理。
  2-4-4-1、将B[J]的第1位和第6位组合为一个2位长度的变量M,M作为在S[J]中的行号。
  2-4-4-2、将B[J]的第2位到第5位组合,作为一个4位长度的变量N,N作为在S[J]中的列号。
  2-4-4-3、用S[J][M][N]来取代B[J]。
  Substitution Box 1 (S[1])
  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
  S[2]
  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
  S[3]
  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
  S[4]
  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
  S[5]
  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
  S[6]
  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
  S[7]
  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
  S[8]
  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
  2-4-4-4、从2-4-4-1处循环执行,直到B[8]被替代完成。
  2-4-4-5、将B[1]到B[8]组合,按下表(P)变换,得到P。
  Permutation 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
  2-4-6、异或P和L[I-1]结果放在R[I],即R[I]=P XOR L[I-1]。
  2-4-7、L[I]=R[I-1]
  2-4-8、从2-4-1处开始循环执行,直到K[16]被变换完成。
  2-4-5、组合变换后的R[16]L[16](注意:R作为开始的32位),按下表(IP-1)变换得到最后的结果。
  Final Permutation (IP**-1)
  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
  以上就是DES算法的描述。

加密和解密的总结

一.加密算法的分类

  1.对称加密算法具有更高的加密速度,但双方都需要事先知道秘钥,秘钥在传输过程中可能会被窃取,因此安全性没有非对称加密高

    常见的对称加密算法:DES, AES, 3DES等等

  2.非对称加密算法的加密速度低于对称加密算法,但是安全性更高

    非对称加密算法:RSA, DSA, ECC 等算法

  3.利用字典的格式转换加密

    MAKETRANS()

二.详细分析

  1.DES加密

    即数据加密标准,是一种使用秘钥加密的块算法

    入口参数有三个:key, Data,  Mode

      key为7个字节共56位,是DES算法的工作秘钥;

      Data为DES的工作方式,有两种:加密和解密

    3DES是DES向AES过渡的加密算法,使用两个秘钥,执行三次DES算法,

    加密的过程是加密-解密-加密

    解密的过程是解密-加密-解密

 1 from Crypto.Cipher import DES
 2 key = babcdefgh # 密钥 8位或16位,必须为bytes
 3  
 4 def pad(text):
 5   """
 6   # 加密函数,如果text不是8的倍数【加密文本text必须为8的倍数!】,那就补足为8的倍数
 7   :param text: 
 8   :return: 
 9   """
10   while len(text) % 8 != 0:
11     text +=  
12   return text
13  
14  
15 des = DES.new(key, DES.MODE_ECB) # 创建一个DES实例
16 text = Python rocks!
17 padded_text = pad(text)
18 encrypted_text = des.encrypt(padded_text.encode(utf-8)) # 加密
19 print(encrypted_text)
20 # rstrip(‘ ‘)返回从字符串末尾删除所有字符串的字符串(默认空白字符)的副本
21 plain_text = des.decrypt(encrypted_text).decode().rstrip( ) # 解密
22 print(plain_text)

  2.AES加密

    高级加密标准(英语:Advanced EncryptionStandard,缩写:AES),这个标准用来替代原先的DES

    AES的区块长度固定为128 比特,密钥长度则可以是128,192或256比特(16、24和32字节)

    大致步骤:

      1、密钥扩展(KeyExpansion),

      2、初始轮(Initial Round),

      3、重复轮(Rounds),每一轮又包括:SubBytes、ShiftRows、MixColumns、AddRoundKey,

      4、最终轮(Final Round),最终轮没有MixColumns。

普通方式

 1 from Cryptodome.Cipher import AES
 2 from binascii import b2a_hex, a2b_hex
 3 #秘钥,此处需要将字符串转为字节
 4 key = abcdefgh
 5 #加密内容需要长达16位字符,所以进行空格拼接
 6 def pad(text):
 7   while len(text) % 16 != 0:
 8     text +=  
 9   return text
10 #加密秘钥需要长达16位字符,所以进行空格拼接
11 def pad_key(key):
12   while len(key) % 16 != 0:
13     key +=  
14   return key
15 #进行加密算法,模式ECB模式,把叠加完16位的秘钥传进来
16 aes = AES.new(pad_key(key).encode(), AES.MODE_ECB)
17 #加密内容,此处需要将字符串转为字节
18 text = hello
19 #进行内容拼接16位字符后传入加密类中,结果为字节类型
20 encrypted_text = aes.encrypt(pad(text).encode())
21 encrypted_text_hex = b2a_hex(encrypted_text)
22 print(encrypted_text_hex)
23  
24  
25 # #此处是为了验证是否能将字节转为字符串后,进行解密成功
26 # #实际上a 就是 encrypted_text ,也就是加密后的内容
27 # #用aes对象进行解密,将字节类型转为str类型,错误编码忽略不计
28 de = str(aes.decrypt(a2b_hex(encrypted_text_hex)), encoding=utf-8,errors="ignore")
29 # #获取str从0开始到文本内容的字符串长度。
30 print(de[:len(text)])

面向对象方式

 1 from Cryptodome.Cipher import AES
 2 from binascii import b2a_hex, a2b_hex
 3  
 4 AES_LENGTH = 16
 5  
 6 class prpcrypt():
 7   def __init__(self, key):
 8     self.key = key
 9     self.mode = AES.MODE_ECB
10     self.cryptor = AES.new(self.pad_key(self.key).encode(), self.mode)
11  
12   # 加密函数,如果text不是16的倍数【加密文本text必须为16的倍数!】,那就补足为16的倍数
13   # 加密内容需要长达16位字符,所以进行空格拼接
14   def pad(self,text):
15     while len(text) % AES_LENGTH != 0:
16       text +=  
17     return text
18  
19   # 加密密钥需要长达16位字符,所以进行空格拼接
20   def pad_key(self,key):
21     while len(key) % AES_LENGTH != 0:
22       key +=  
23     return key
24  
25   def encrypt(self, text):
26  
27     # 这里密钥key 长度必须为16(AES-128)、24(AES-192)、或32(AES-256)Bytes 长度.目前AES-128足够用
28     # 加密的字符需要转换为bytes
29     # print(self.pad(text))
30     self.ciphertext = self.cryptor.encrypt(self.pad(text).encode())
31     # 因为AES加密时候得到的字符串不一定是ascii字符集的,输出到终端或者保存时候可能存在问题
32     # 所以这里统一把加密后的字符串转化为16进制字符串
33     return b2a_hex(self.ciphertext)
34  
35     # 解密后,去掉补足的空格用strip() 去掉
36  
37   def decrypt(self, text):
38     plain_text = self.cryptor.decrypt(a2b_hex(text)).decode()
39     return plain_text.rstrip( )
40  
41  
42 if __name__ == __main__:
43   pc = prpcrypt(abcdef) # 初始化密钥
44   e = pc.encrypt("0123456789ABCDEF")
45   d = pc.decrypt(e)
46   print(e, d)
47   e = pc.encrypt("00000000000000000000000000")
48   d = pc.decrypt(e)
49   print(e, d)

  3.RSA加密

    公钥加密算法,一种非对称密码算法

    公钥加密,私钥解密

    公有三个参数:rsa_n, rsa_e, message

    rsa_n, rsa_e 用于生成公钥

    message:需要加密的消息

 1 import rsa
 2 from binascii import b2a_hex, a2b_hex
 3  
 4  
 5  
 6 class rsacrypt():
 7   def __init__(self, pubkey, prikey):
 8     self.pubkey = pubkey
 9     self.prikey = prikey
10  
11   def encrypt(self, text):
12     self.ciphertext = rsa.encrypt(text.encode(), self.pubkey)
13     # 因为rsa加密时候得到的字符串不一定是ascii字符集的,输出到终端或者保存时候可能存在问题
14     # 所以这里统一把加密后的字符串转化为16进制字符串
15     return b2a_hex(self.ciphertext)
16  
17   def decrypt(self, text):
18     decrypt_text = rsa.decrypt(a2b_hex(text), prikey)
19     return decrypt_text
20  
21  
22 if __name__ == __main__:
23   pubkey, prikey = rsa.newkeys(256)
24   rs_obj = rsacrypt(pubkey,prikey)
25   text=hello
26   ency_text = rs_obj.encrypt(text)
27   print(ency_text)
28   print(rs_obj.decrypt(ency_text))
29  
30 """
31 b‘7cb319c67853067abcd16aad25b3a8658e521f83b1e6a6cf0c4c2e9303ad3e14‘
32 b‘hello‘
33 """

  4.使用base64或pycrypto模块

    1.使用base64

1 s1 = base64.encodestring(hello world)
2 s2 = base64.decodestring(s1)
3 print s1, s2
4 
5 #  结果
6 #  aGVsbG8gd29ybGQ=
7 #  hello world

      优点:方法简单

      缺点:不保险,别人拿到密文可以解密出明文

      编码原理:将3个字节转换成4个字节((3 X 8)=24=(4X6)),先读入3个字节,每读一个字节,左移8位,再右移四次,每次6位,这样就有4个字节了。

      解密原理:将4个字节转换成3个字节,先读入4个6位(用或运算),每次左移6位,再右移3次,每次8位,这样就还原了。

    2.使用pycrypto模块

 1 from Crypto.Cipher import AES
 2 obj = AES.new(This is a key123, AES.MODE_CBC, This is an IV456)
 3 message = "The answer is no"
 4 ciphertext = obj.encrypt(message)
 5 print(ciphertext)
 6 #   ‘xd6x83x8dd!VTx92xaa`Ax05xe0x9bx8bxf1‘
 7 obj2 = AES.new(This is a key123, AES.MODE_CBC, This is an IV456)
 8 decryptext = obj2.decrypt(ciphertext)
 9 print(decryptext)
10 #  ‘The answer is no‘

      AES只是个基本算法,实现AES有若干模式。其中的CBC模式因为其安全性而被TLS(就是https的加密标准)和IPSec(win采用的)作为技术标准。

      简单地说,CBC使用密码和salt(起扰乱作用)按固定算法(md5)产生key和iv。然后用key和iv(初始向量,加密第一块明文)加密(明文)和解密(密文)。

 1 import sys
 2 from Crypto.Cipher import AES
 3 from binascii import b2a_hex, a2b_hex
 4   
 5 class prpcrypt():
 6   def __init__(self, key):
 7     self.key = key
 8     self.mode = AES.MODE_CBC
 9     
10   #加密函数,如果text不是16的倍数【加密文本text必须为16的倍数!】,那就补足为16的倍数
11   def encrypt(self, text):
12     cryptor = AES.new(self.key, self.mode, self.key)
13     #这里密钥key 长度必须为16(AES-128)、24(AES-192)、或32(AES-256)Bytes 长度.目前AES-128足够用
14     length = 16
15     count = len(text)
16     add = length - (count % length)
17     text = text + ( * add)
18     self.ciphertext = cryptor.encrypt(text)
19     #因为AES加密时候得到的字符串不一定是ascii字符集的,输出到终端或者保存时候可能存在问题
20     #所以这里统一把加密后的字符串转化为16进制字符串
21     return b2a_hex(self.ciphertext)
22     
23   #解密后,去掉补足的空格用strip() 去掉
24   def decrypt(self, text):
25     cryptor = AES.new(self.key, self.mode, self.key)
26     plain_text = cryptor.decrypt(a2b_hex(text))
27     return plain_text.rstrip()
28   
29 if __name__ == __main__:
30   pc = prpcrypt(keyskeyskeyskeys)   #初始化密钥
31   e = pc.encrypt("00000")
32   d = pc.decrypt(e)           
33   print(e, d)
34   e = pc.encrypt("00000000000000000000000000")
35   d = pc.decrypt(e)         
36   print(e, d)

  5.Python  maketrans()方法  也可以用来进行加密

    描述:用于创建字符串映射的转换表,对于接受两个参数的最简单的调用方式,第一个参数是字符串,表示需要转换的字符,第二个参数也是字符串表示转换的目标

    注:两个字符串的长度必须相同,为一一对应的关系

    语法: str.maketrans(in_tab, out_tab)

    参数:in_tab - 字符串中要替换的字符串组成的字符串

        out_tab - 相应的映射字符的字符串

1 from string import maketrans   # 必须调用 maketrans 函数。
2 
3 intab = "aeiou"
4 outtab = "12345"
5 trantab = maketrans(intab, outtab)
6 
7 str = "this is string example....wow!!!"
8 print(str.translate(trantab))

参考链接:https://www.jb51.net/article/152209.htm

以上是关于求教des算法的详细过程的主要内容,如果未能解决你的问题,请参考以下文章

DES加密解密算法(简单易懂超级详细)

DES算法和RSA算法的区别

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

数据加密标准DES详细过程总结代码(自运行可实现)

java des 加密 解密 密钥随机取得方法

密码学部分 数据加密标准(DES)相关知识来回答,越详细约好