des加密算法(des加解密算法实现)

2023-03-18 21:41:46 密码用途 思思

des加密算法如下:

一、DES加密算法简介

DES(Data Encryption Standard)是目前最为流行的加密算法之一。DES是对称的,也就是说它使用同一个密钥来加密和解密数据。

DES还是一种分组加密算法,该算法每次处理固定长度的数据段,称之为分组。DES分组的大小是64位,如果加密的数据长度不是64位的倍数,可以按照某种具体的规则来填充位。

从本质上来说,DES的安全性依赖于虚假表象,从密码学的术语来讲就是依赖于“混乱和扩散”的原则。混乱的目的是为隐藏任何明文同密文、或者密钥之间的关系,而扩散的目的是使明文中的有效位和密钥一起组成尽可能多的密文。两者结合到一起就使得安全性变得相对较高。

DES算法具体通过对明文进行一系列的排列和替换操作来将其加密。过程的关键就是从给定的初始密钥中得到16个子密钥的函数。要加密一组明文,每个子密钥按照顺序(1-16)以一系列的位操作施加于数据上,每个子密钥一次,一共重复16次。每一次迭代称之为一轮。要对密文进行解密可以采用同样的步骤,只是子密钥是按照逆向的顺序(16-1)对密文进行处理。

二、DES加密算法加密原理

DES是采用分组加密。使用64位的分组长度和56位的密钥长度,将64位的输入经过一系列变换得到64位的输出。DES算法利用多次组合替代算法和换位算法,通过混淆和扩散的相互作用,把明文编辑成密码强度很高的密文。解密则使用了相同的步骤和相同的密钥。

64位数据为一组进行加密;

初始置换根据一张8*8的置换表,将64位的明文打乱

与56位的密钥经16轮次迭代运算形成的初始密文

最后经过初始逆置换得到分组的最终密文

DES 加密算法解析

第一步是用密钥初始化des

初始化的过程主要是用传入的密钥生成16对长度为48的Kn 子密钥

生成48位子密钥Kn的函数主要是 __create_sub_keys , 主要设计两个换位表pc1和pc2

key = self.__permutate(des.__pc1, self.__String_to_BitList(self.getKey())) 开始先用换位表生成56位的初始key值(同pc1表的位数)

之后划分成两部分self.L和self.R各28位,然后是一个循环16此的左移操作,最后用pc2换位表生成第一个子密钥Kn[0]

我们传入数据调用encrypt函数即可, DES.encrypt('flag{isisisikey}') 我们先来看encrypt函数

encrypt函数主要调用了crypt函数,继续跟进crypt函数,开始一部分是cbc模式获取iv的过程,这里先暂时不考虑cbc,直接看关键部分

这里就设计到分组加密的核心了,为什么DES又叫分组加密,有一操作是 block = self.__String_to_BitList(data[i:i+8]) 把加密数据每八个字节分成一个block,然后调用 __String_to_BitList 会将八字节字符转换为64bit的二进制,每个block再调用 __des_crypt 函数加密

开始几步和子密钥生成函数类似,用一个ip换位表初始化block,然后划分成self,L和self.R 各32位。

之后又是一个16轮的计算,我们分析一下每轮操作

self.R = self.__permutate(des.__expansion_table, self.R) 利用一个扩展表将32bit扩展成48位,扩展表:

B = [self.R[:6], self.R[6:12], self.R[12:18], self.R[18:24], self.R[24:30], self.R[30:36], self.R[36:42], self.R[42:]] 将48位的self.R 分成6*8为,之后一个循环就是经典的是s-box的置换操作

s-box盒一个八个,m是前后2bit,n是中间6bit, v是s-box的(n,m)处的值

self.R = self.__permutate(des.__p, Bn) 是P-box置换盒。 最后返回64bit的processed_block, 经过BitList_to_String函数处理就变成8字节的字符流了,最后把每个block分组join一块就是最后的密文。

我们再来总结一下这个过程

子密钥生成算法

des 加密算法

附上完整版des加解密算法脚本

des算法加密解密的实现

一.加密

DES算法处理的数据对象是一组64比特的明文串。设该明文串为m=m1m2…m64 (mi=0或1)。明文串经过64比特的密钥K来加密,最后生成长度为64比特的密文E。其加密过程图示如下:

DES算法加密过程

对DES算法加密过程图示的说明如下:待加密的64比特明文串m,经过IP置换后,得到的比特串的下标列表如下:

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

该比特串被分为32位的L0和32位的R0两部分。R0子密钥K1(子密钥的生成将在后面讲)经过变换f(R0,K1)(f变换将在下面讲)输出32位的比特串f1,f1与L0做不进位的二进制加法运算。运算规则为:

f1与L0做不进位的二进制加法运算后的结果赋给R1,R0则原封不动的赋给L1。L1与R0又做与以上完全相同的运算,生成L2,R2…… 一共经过16次运算。最后生成R16和L16。其中R16为L15与f(R15,K16)做不进位二进制加法运算的结果,L16是R15的直接赋值。

R16与L16合并成64位的比特串。值得注意的是R16一定要排在L16前面。R16与L16合并后成的比特串,经过置换IP-1后所得比特串的下标列表如下:

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

经过置换IP-1后生成的比特串就是密文e.。

下面再讲一下变换f(Ri-1,Ki)。

它的功能是将32比特的输入再转化为32比特的输出。其过程如图所示:

对f变换说明如下:输入Ri-1(32比特)经过变换E后,膨胀为48比特。膨胀后的比特串的下标列表如下:

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 31

膨胀后的比特串分为8组,每组6比特。各组经过各自的S盒后,又变为4比特(具体过程见后),合并后又成为32比特。该32比特经过P变换后,其下标列表如下:

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

经过P变换后输出的比特串才是32比特的f (Ri-1,Ki)。

下面再讲一下S盒的变换过程。任取一S盒。见图:

在其输入b1,b2,b3,b4,b5,b6中,计算出x=b1*2+b6, y=b5+b4*2+b3*4+b2*8,再从Si表中查出x 行,y 列的值Sxy。将Sxy化为二进制,即得Si盒的输出。(S表如图所示)

至此,DES算法加密原理讲完了。在VC++6.0下的程序源代码为:

for(i=1;i=64;i++)

m1[i]=m[ip[i-1]];//64位明文串输入,经过IP置换。

下面进行迭代。由于各次迭代的方法相同只是输入输出不同,因此只给出其中一次。以第八次为例://进行第八次迭代。首先进行S盒的运算,输入32位比特串。

for(i=1;i=48;i++)//经过E变换扩充,由32位变为48位

RE1[i]=R7[E[i-1]];

for(i=1;i=48;i++)//与K8按位作不进位加法运算

RE1[i]=RE1[i]+K8[i];

for(i=1;i=48;i++)

{

if(RE1[i]==2)

RE1[i]=0;

}

for(i=1;i7;i++)//48位分成8组

{

s11[i]=RE1[i];

s21[i]=RE1[i+6];

s31[i]=RE1[i+12];

s41[i]=RE1[i+18];

s51[i]=RE1[i+24];

s61[i]=RE1[i+30];

s71[i]=RE1[i+36];

s81[i]=RE1[i+42];

}//下面经过S盒,得到8个数。S1,s2,s3,s4,s5,s6,s7,s8分别为S表

s[1]=s1[s11[6]+s11[1]*2][s11[5]+s11[4]*2+s11[3]*4+s11[2]*8];

s[2]=s2[s21[6]+s21[1]*2][s21[5]+s21[4]*2+s21[3]*4+s21[2]*8];

s[3]=s3[s31[6]+s31[1]*2][s31[5]+s31[4]*2+s31[3]*4+s31[2]*8];

s[4]=s4[s41[6]+s41[1]*2][s41[5]+s41[4]*2+s41[3]*4+s41[2]*8];

s[5]=s5[s51[6]+s51[1]*2][s51[5]+s51[4]*2+s51[3]*4+s51[2]*8];

s[6]=s6[s61[6]+s61[1]*2][s61[5]+s61[4]*2+s61[3]*4+s61[2]*8];

s[7]=s7[s71[6]+s71[1]*2][s71[5]+s71[4]*2+s71[3]*4+s71[2]*8];

s[8]=s8[s81[6]+s81[1]*2][s81[5]+s81[4]*2+s81[3]*4+s81[2]*8];

for(i=0;i8;i++)//8个数变换输出二进制

{

for(j=1;j5;j++)

{

temp[j]=s[i+1]%2;

s[i+1]=s[i+1]/2;

}

for(j=1;j5;j++)

f[4*i+j]=temp[5-j];

}

for(i=1;i33;i++)//经过P变换

frk[i]=f[P[i-1]];//S盒运算完成

for(i=1;i33;i++)//左右交换

L8[i]=R7[i];

for(i=1;i33;i++)//R8为L7与f(R,K)进行不进位二进制加法运算结果

{

R8[i]=L7[i]+frk[i];

if(R8[i]==2)

R8[i]=0;

}

[ 原创文档 本文适合中级读者 已阅读21783次 ] 文档 代码 工具

DES算法及其在VC++6.0下的实现(下)

作者:航天医学工程研究所四室 朱彦军

在《DES算法及其在VC++6.0下的实现(上)》中主要介绍了DES算法的基本原理,下面让我们继续:

二.子密钥的生成

64比特的密钥生成16个48比特的子密钥。其生成过程见图:

子密钥生成过程具体解释如下:

64比特的密钥K,经过PC-1后,生成56比特的串。其下标如表所示:

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

该比特串分为长度相等的比特串C0和D0。然后C0和D0分别循环左移1位,得到C1和D1。C1和D1合并起来生成C1D1。C1D1经过PC-2变换后即生成48比特的K1。K1的下标列表为:

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

C1、D1分别循环左移LS2位,再合并,经过PC-2,生成子密钥K2……依次类推直至生成子密钥K16。

注意:Lsi (I =1,2,….16)的数值是不同的。具体见下表:

迭代顺序 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

生成子密钥的VC程序源代码如下:

for(i=1;i57;i++)//输入64位K,经过PC-1变为56位 k0[i]=k[PC_1[i-1]];

56位的K0,均分为28位的C0,D0。C0,D0生成K1和C1,D1。以下几次迭代方法相同,仅以生成K8为例。 for(i=1;i27;i++)//循环左移两位

{

C8[i]=C7[i+2];

D8[i]=D7[i+2];

}

C8[27]=C7[1];

D8[27]=D7[1];

C8[28]=C7[2];

D8[28]=D7[2];

for(i=1;i=28;i++)

{

C[i]=C8[i];

C[i+28]=D8[i];

}

for(i=1;i=48;i++)

K8[i]=C[PC_2[i-1]];//生成子密钥k8

注意:生成的子密钥不同,所需循环左移的位数也不同。源程序中以生成子密钥 K8为例,所以循环左移了两位。但在编程中,生成不同的子密钥应以Lsi表为准。

三.解密

DES的解密过程和DES的加密过程完全类似,只不过将16圈的子密钥序列K1,K2……K16的顺序倒过来。即第一圈用第16个子密钥K16,第二圈用K15,其余类推。

第一圈:

加密后的结果

L=R15, R=L15⊕f(R15,K16)⊕f(R15,K16)=L15

同理R15=L14⊕f(R14,K15), L15=R14。

同理类推:

得 L=R0, R=L0。

其程序源代码与加密相同。在此就不重写。

四.示例

例如:已知明文m=learning, 密钥 k=computer。

明文m的ASCII二进制表示:

m= 01101100 01100101 01100001 01110010

01101110 01101001 01101110 01100111

密钥k的ASCII二进制表示:

k=01100011 01101111 01101101 01110000

01110101 01110100 01100101 01110010

明文m经过IP置换后,得:

11111111 00001000 11010011 10100110 00000000 11111111 01110001 11011000

等分为左右两段:

L0=11111111 00001000 11010011 10100110 R0=00000000 11111111 01110001 11011000

经过16次迭代后,所得结果为:

L1=00000000 11111111 01110001 11011000 R1=00110101 00110001 00111011 10100101

L2=00110101 00110001 00111011 10100101 R2=00010111 11100010 10111010 10000111

L3=00010111 11100010 10111010 10000111 R3=00111110 10110001 00001011 10000100

L4=00111110101100010000101110000100 R4=11110111110101111111101000111110

L5=11110111110101111111101000111110 R5=10010110011001110100111111100101

L6=10010110011001110100111111100101 R6=11001011001010000101110110100111

L7=11001011001010000101110110100111 R7=01100011110011101000111011011001

L8=01100011110011101000111011011001 R8=01001011110100001111001000000100

L9=01001011110100001111001000000100 R9=00011101001101111010111011100001

L10=00011101001101111010111011100001 R10=11101110111110111111010100000101

L11=11101110111110111111010100000101 R11=01101101111011011110010111111000

L12=01101101111011011110010111111000 R12=11111101110011100111000110110111

L13=11111101110011100111000110110111 R13=11100111111001011010101000000100

L14=11100111111001011010101000000100 R14=00011110010010011011100001100001

L15=00011110010010011011100001100001 R15=01010000111001001101110110100011

L16=01010000111001001101110110100011 R16=01111101101010000100110001100001

其中,f函数的结果为:

f1=11001010001110011110100000000011 f2=00010111000111011100101101011111

f3=00001011100000000011000000100001 f4=11100000001101010100000010111001

f5=10101000110101100100010001100001 f6=00111100111111111010011110011001

f7=11110101101010011100000100111100 f8=10000000111110001010111110100011

f9=01111110111110010010000000111000 f10=10100101001010110000011100000001

f11=01110000110110100100101100011001 f12=00010011001101011000010010110010

f13=10001010000010000100111111111100 f14=11100011100001111100100111010110

f15=10110111000000010111011110100111 f16=01100011111000011111010000000000

16个子密钥为:

K1=11110000101111101110111011010000 K2=11100000101111101111011010010101

K3=11110100111111100111011000101000 K4=11100110111101110111001000011010

K5=11101110110101110111011100100110 K6=11101111110100110101101110001011

K7=00101111110100111111101111100110 K8=10111111010110011101101101010000

K9=00011111010110111101101101000100 K10=00111111011110011101110100001001

K11=00011111011011011100110101101000 K12=01011011011011011011110100001010

K13=11011101101011011010110110001111 K14=11010011101011101010111110000000

K15=11111001101111101010011011010011 K16=11110001101111100010111000000001

S盒中,16次运算时,每次的8 个结果为:

第一次:5,11,4,1,0,3,13,9;

第二次:7,13,15,8,12,12,13,1;

第三次:8,0,0,4,8,1,9,12;

第四次:0,7,4,1,7,6,12,4;

第五次:8,1,0,11,5,0,14,14;

第六次:14,12,13,2,7,15,14,10;

第七次:12,15,15,1,9,14,0,4;

第八次:15,8,8,3,2,3,14,5;

第九次:8,14,5,2,1,15,5,12;

第十次:2,8,13,1,9,2,10,2;

第十一次:10,15,8,2,1,12,12,3;

第十二次:5,4,4,0,14,10,7,4;

第十三次:2,13,10,9,2,4,3,13;

第十四次:13,7,14,9,15,0,1,3;

第十五次:3,1,15,5,11,9,11,4;

第十六次:12,3,4,6,9,3,3,0;

子密钥生成过程中,生成的数值为:

C0=0000000011111111111111111011 D0=1000001101110110000001101000

C1=0000000111111111111111110110 D1=0000011011101100000011010001

C2=0000001111111111111111101100 D2=0000110111011000000110100010

C3=0000111111111111111110110000 D3=0011011101100000011010001000

C4=0011111111111111111011000000 D4=1101110110000001101000100000

C5=1111111111111111101100000000 D5=0111011000000110100010000011

C6=1111111111111110110000000011 D6=1101100000011010001000001101

C7=1111111111111011000000001111 D7=0110000001101000100000110111

C8=1111111111101100000000111111 D8=1000000110100010000011011101

C9=1111111111011000000001111111 D9=0000001101000100000110111011

C10=1111111101100000000111111111 D10=0000110100010000011011101100

C11=1111110110000000011111111111 D11=0011010001000001101110110000

C12=1111011000000001111111111111 D12=1101000100000110111011000000

C13=1101100000000111111111111111 D13=0100010000011011101100000011

C14=0110000000011111111111111111 D14=0001000001101110110000001101

C15=1000000001111111111111111101 D15=0100000110111011000000110100

C16=0000000011111111111111111011 D16=1000001101110110000001101000