求教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 = b‘abcdefgh‘ # 密钥 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 + (‘