DES加密运算步骤

  1. 输入64位明文数据,并进行初始置换IP;
  2. 在初始置换IP后,明文数据再被分为左右两部分,每部分32位,以L0,R0表示;
  3. 在秘钥的控制下,经过16轮运算(f);
  4. 16轮后,左、右两部分交换,并连接再一起,再进行逆置换;
  5. 输出64位密文。

初始置换

这里要使用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,

这里的意思是将输入的64位明文按照表排列,即第58位明文排在第一位,第50位明文排在第二位,依次类推获得一个新的64位的串

密钥生成器

密钥移位表

64位密钥压缩为56位表

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

56位密钥压缩为48位表
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

将这个56位表分成前28位和后28位,即C0和D0表

又将64位密钥按照C0和D0表置换成28位L0和28位R0(置换规则和前面一样)

将L0和R0按照加密轮数进行移位。(tips:每次移位是接着上次已经移位后的串继续移位)

将L0和R0拼接为一个56位的串key_56。

将key_56按照48位表置换得到key_48(置换规则和ip置换一样)

这里已经获得了一个key,按照移位表进行循环一共得到16个key。

密钥生成流程图

des

E/p扩展

新一轮加密的开始

第一轮使用I/P置换得到的64位串,下一轮使用P置换得到的64位串。

将得到的64位串分成两部分,前32位为左L0,后32位右R0。

将右32位进行E/P扩展变成48位。

E/P扩展置换表

置换规则和ip置换一样
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

E/P结束后我们得到了一个48位的串R1

R1与key异或

将R1与key进行异或运算得到新的R1

tmp+=bin(int(r1,2)^int(keys[i],2))[2:] #R1和key对应异或
        while len(tmp)<48:
            tmp='0'+tmp
        return tmp

S盒置换

有8个S盒置换表(太多这里先不写出来放在后面代码中)

流程如图,将上一步异或得到的R1每6位分为一组,共计8组。

每组6位,将高一位和低一位组合形成行,中间4位作为列进行S盒置换。

例如

​ 111001 那么对应11就是行,1100就是列。

每组我们能够获得4位的串,一共8组,将8组数进行拼接得到32位的新的R1串。

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,

将S盒置换后得到的32位R1进行P置换得到新的32位R1 (置换规则和IP置换一样)

这里将前面E/P置换得到的L0和这个R1进行异或运算得到新的R1

令L1=E/P置换得到的R0。

将L1和R1组合得到一个新的64位串

到这儿,我们已经进行了一轮加密。后面将这64位串传给E/P置换,进行下一轮。

IP逆置换

IP逆置换表


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,

经过前面16轮加密,我们得到了一个64位串。

但是我们每一轮结束有一个L1和R1交换的操作,最后一轮结束是不需要L1和R1交换

所以我们将这个64位串分割成左32位和右32位,然后左右交换组合新的64位串

将这个64位串进行ip逆置换,得到加密结果(置换规则和IP置换规则一样)

解密

解密就是将第16位key作为第一位key,第15位作为第二位key,依次类推。得到一个逆序的key,进行加密就ok。

因为解密是加密的一个逆过程。

DES流程图

key

代码

#data='1001100001110110010101000011001000010001010001110010010110000011'
#secret_key='0001001000110100010101100111100010010001001000110100010101100111'
#加密结果 0111110010101110111011000000001001001010111000011010110111001011
#加密结果 0x7caeec024ae1adcb


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

#ip逆置换表
ip_=[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]

#s盒
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 ] ]

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

#压缩密钥到56位
cre_56key=[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]

#压缩密钥到48位
cre_48key=[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]

#左移动次数
mobile_n=[1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1] 

#轮密钥
keys=[]

#E扩展矩阵
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]

#ip置换
def ip_replace(tem_data):
    c=[]
    for i in ip:
        c.append(tem_data[i-1])
    return c

#E/P扩展
def Extension(r0):
    r1=[]
    for i in E:
        r1.append(str(r0[i-1]))
    return r1

#轮密钥生成
def cre_keys(secret_key):
    temp=[]
    for i in cre_56key:
        temp.append(secret_key[i-1])
    c0=cre_56key[0:28]
    d0=cre_56key[28:]
    L0=[]
    R0=[]
    for i in c0:
        L0.append(secret_key[i-1])
    for i in d0:
        R0.append(secret_key[i-1])
    for i in range(16):
        L0=L0[mobile_n[i]:]+L0[0:mobile_n[i]]
        R0=R0[mobile_n[i]:]+R0[0:mobile_n[i]]
        temp_k=L0+R0
        
        key1=[]
        for i in cre_48key:
            key1.append(str(temp_k[i-1]))
        keys.append("".join(key1))

#S盒替换
def s_replace(r1):
    s_box=['s1[r][c]','s2[r][c]','s3[r][c]','s4[r][c]','s5[r][c]','s6[r][c]','s7[r][c]','s8[r][c]']
    s_dates=""
    for i in range(8):
        if i!=7:
            s_data=r1[i*6:(i+1)*6]
        else:
            s_data=r1[i*6:]
        r=int(s_data[0]+s_data[-1],2)
        c=int(s_data[1:-1],2)
        
        s_da=bin(eval(s_box[i]))[2:]
        
        patter=4-len(s_da)
        s_da='0'*patter+s_da
        s_dates+=s_da
    return s_dates

#P置换
def P_replace(l0,s_dates,old_r0):
    temp_r=''
    temp_l=''
    temp=''
    for i in p:
        temp_r+=s_dates[i-1]
    for i in l0:
        temp_l+=str(i)
    temp=bin(int(temp_l,2)^int(temp_r,2))[2:]
    while len(temp)<32:
        temp='0'+temp
    r1=[]
    l1=old_r0
    for i in temp:
        r1.append(int(i))
    temp_data=l1+r1
    return temp_data

#ip逆置换
def _ip_replace(temp_data):
    data=temp_data[32:]+temp_data[0:32]
    cipher=[]
    for i in ip_:
        cipher.append(data[i-1])
    return cipher

if __name__ == "__main__":
    #data=input('输入data:')
    #secret_key=input('输入密钥:')
    data='1001100001110110010101000011001000010001010001110010010110000011'
    secret_key='0001001000110100010101100111100010010001001000110100010101100111'
    tem_data=[]
    cre_keys(secret_key)
    for i in range(len(data)):
        if i==" ":
            continue
        tem_data.append(int(data[i]))
    c=ip_replace(tem_data)
    for i in range(16):
        l0=c[0:32]
        r0=c[32:]
        r1=Extension(r0)
        r1="".join(r1)
        tmp=""
        tmp+=bin(int(r1,2)^int(keys[i],2))[2:]
        while len(tmp)<48:
            tmp='0'+tmp
        s_dates=s_replace(tmp)
        
        c=P_replace(l0,s_dates,r0)
    cipher=_ip_replace(c)
    secret=''
    for i in cipher:
        secret+=str(i)
    print('DES加密结果:',secret)
    print('DES加密结果:',hex(int(secret,2)))