DES加解密(详细的加密流程)_des加密解密原理及流程-CSDN博客
参考这两篇实现的,第一篇讲解比较详细,第二篇的例子和老师作业的例子相同
根据多个已确定的矩阵,对明文做多次置换得到的密文,过程较繁琐,当个模拟题做了
对于数据补全的内容没有实现,若以后有机会再补充
DES加密看似复杂,实则一点也不简单,对于其加密、破解过程理解依然肤浅,需进一步学习
'''
auther:Poppy
time:2024/4/25
'''
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_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]
PC1 = [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]
PC2 = [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]
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]
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]
key = [[] for i in range(17)]
s = [[] for i in range(10)]
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]]
def hex2Bin(x):
tmp = ''
for i in range(len(x)):
tmp += '{:04b}'.format(int(x[i], 16))
return tmp
def initData():
global oriString, oriKey, encod
encod = 1
print('输入1测试作业,输入其他数字测试其他明文')
type = int(input())
if type == 1:
oriString = '0123456789ABCDEF'
print('明文为', oriString)
oriString = hex2Bin(oriString)
oriKey = '133457799BBCDFF1'
print('密钥为', oriKey)
oriKey = hex2Bin(oriKey)
else:
print('选择进制,二进制输入bin或2,16进制输入hex或16')
tmp = input()
if tmp == 'bin' or tmp == '2':
print('请输入64位2进制数作为明文')
oriString = input()
print('请输入64位2进制数作为密钥')
oriKey = input()
elif tmp == 'hex' or tmp == '16':
print('请输入16位16进制数作为明文')
oriString = input()
oriString = hex2Bin(oriString)
print('请输入16位16进制数作为密钥')
oriKey = input()
oriKey = hex2Bin(oriKey)
print('加密请输入1,解密请输入2')
while True:
encod = int(input())
if encod in [1, 2]:
break
else:
print('输入错误,请输入1或2')
def initPermutation():
global L0, R0
tmp = [''] * 64
for i in range(64):
tmp[i] = oriString[IP[i] - 1]
L0, R0 = ''.join(tmp[:32]), ''.join(tmp[32:])
def get16Key():
# 去除8个校验位
tmp1 = ''
for i in range(56):
tmp1 += oriKey[PC1[i] - 1]
# test
# tmp1 = '11110000110011001010101011110101010101100110011110001111'
C0, D0 = ''.join(tmp1[:28]), ''.join(tmp1[28:])
q = [1, 2, 9, 16]
lt, rt = C0, D0
# 循环左移
for i in range(1, 17):
dx = 2
if i in q:
dx = 1
lt = lt[dx:] + lt[:dx]
rt = rt[dx:] + rt[:dx]
# 进行pc2置换
res = lt + rt
ke = ''
for j in range(48):
ke += res[PC2[j] - 1]
key[i] = ke
def fiter():
global cip
dx = 6
l, r = L0, R0
# 加解密处理
if encod == 1:
q = [i for i in range(1, 17)]
elif encod == 2:
q = [i for i in range(16, 0, -1)]
for i in q:
# E拓展
tmpe = ''
for j in range(48):
tmpe += r[E[j] - 1]
# 与对应密钥异或
tmpxor = ''
for j in range(48):
tmpxor += str(int(tmpe[j]) ^ int(key[i][j]))
# S盒代替
tmps = ''
for j in range(8):
tmp = tmpxor[j * dx:j * dx + dx]
x = int(tmp[0] + tmp[-1], 2)
y = int(tmp[1:-1], 2)
tmps += '{:04b}'.format(s[j + 1][x][y])
# P盒置换
tmpp = ''
for j in range(32):
tmpp += tmps[P[j] - 1]
tmplxor = ''
for j in range(32):
tmplxor += str(int(tmpp[j]) ^ int(l[j]))
l = r
r = tmplxor
nd = r + l
cip = ''
for i in range(64):
cip += nd[IP_1[i] - 1]
def printCipher():
print('二进制密文为:')
for i in range(64):
if i % 4 == 0 and i != 0:
print(' ', end='')
print(cip[i], end='')
print('\n十六进制密文为')
cip16 = ''
dx = 4
for i in range(16):
tmp = cip[i * dx:i * dx + dx]
tmp = int(tmp, 2)
tmp = hex(tmp)[2:].upper()
cip16 += tmp
print(cip16)
if __name__ == '__main__':
# 读入明文、密钥、加解密设置
initData()
# 初始置换生成L0,R0
initPermutation()
# 生成子密钥
get16Key()
# f函数迭代
fiter()
# 打印结果
printCipher()