DES加密算法Python分析与多重DES中间件攻击
DES的Python实现
为了方便后续对其中某一个模块进行修改进而分析它的安全性,因此我将DES加密的每一个步骤都封装成了函数
完整代码
# 给定明文字符串,输出第一个IP置换后的结果,为一个列表
def IP(plaintext):
IP_table = [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]
result = []
for i in range(64):
result.append(plaintext[IP_table[i] - 1])
return result
# IP逆置换,输入64位的密文列表,输出64位的明文列表
def IP_1(ciphertext):
IP_1_table = [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]
result = []
for i in range(64):
result.append(ciphertext[IP_1_table[i] - 1])
return result
# 给定一个64位列表,输出左右两部分子列表
def LeftAndRight_64(text):
left = text[:32]
right = text[32:]
return left, right
# 给定一个56位列表,输出左右两部分子列表
def LeftAndRight_56(text):
left = text[:28]
right = text[28:]
return left, right
# 初始密钥64->56,同时执行PC-1置换,输入64位密钥字符串,输出56位密钥列表
def PC_1(key):
PC_1_table = [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]
result = []
for i in range(56):
result.append(key[PC_1_table[i] - 1])
return result
# 56位密钥列表左移+PC-2,输入初始的经过PC-1置换后的密钥与轮数,输出左移后的结果列表
# 压缩置换后变成48位的轮密钥列表
def PC_2(K, round):
# 左移位数
shift = [1, 1, 2, 2, 2, 2, 2, 2,
1, 2, 2, 2, 2, 2, 2, 1]
PC_2_table = [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]
# 左移
left, right = LeftAndRight_56(K)
for i in range(round):
left = left[shift[i]:] + left[:shift[i]]
right = right[shift[i]:] + right[:shift[i]]
# 合并进行PC-2置换
result = left + right
result2 = []
for i in range(48):
result2.append(result[PC_2_table[i] - 1])
return result2
# E扩展,输入32位的右半部分,输出48位的扩展结果,输入输出都是列表
def E(right):
E_table = [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]
result = []
for i in range(48):
result.append(right[E_table[i] - 1])
return result
# S盒代换,输入48位的扩展结果与轮密钥,输出32位的S盒代换结果,输入输出都是列表
def S(right_E, SubK):
# 与轮密钥执行一次异或
result = []
for i in range(48):
result.append(int(right_E[i]) ^ int(SubK[i]))
# S盒代换
S_table = [
# 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]
]
]
# S盒代换
result2 = []
for i in range(8):
row = int(str(result[i * 6]) + str(result[i * 6 + 5]), 2)
col = int(''.join([str(x) for x in result[i * 6 + 1:i * 6 + 5]]), 2)
tmp = S_table[i][row][col]
# 转为四位2进制
tmp = bin(tmp)[2:]
while len(tmp) < 4:
tmp = '0' + tmp
for j in range(4):
result2.append(tmp[j])
return result2
# P置换,输入32位的S盒代换结果,输出32位的P置换结果,输入输出都是列表
def P(S_result):
# P置换表
P_table = [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]
result = []
for i in range(32):
result.append(S_result[P_table[i] - 1])
return result
# DES加密,输入明文字符串与密钥字符串,输出加密后的结果,明文与密文都是64位二进制字符串
def DES(plaintext, key):
# 初始置换IP
plaintext = IP(plaintext)
# 生成16个子密钥
key = PC_1(key)
keys = []
for i in range(16):
keys.append(PC_2(key, i + 1))
# 初始左右两部分
left, right = LeftAndRight_64(plaintext)
for i in range(16):
# E扩展
right_E = E(right)
# S盒代换
right_S = S(right_E, keys[i])
# P置换
right_P = P(right_S)
# 与左半部分异或
right2 = []
for j in range(32):
right2.append(int(left[j]) ^ int(right_P[j]))
# 交换左右两部分
left = right
right = right2
# 交换左右两部分
left, right = right, left
# 合并
result = left + right
# 逆置换
result = IP_1(result)
return result
# 明文字符串
plaintext = "0011100011010101101110000100001011010101001110011001010111100111"
# 密文字符串
key = "1010101100110100100001101001010011011001011100111010001011010011"
print(DES(plaintext, key))
运行结果:
"E:\Python 3.11.0\python.exe" D:\Python程序\cryptology\DES.py
[0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0]
分模块运行
更改上述DES代码,调用函数PC_2,传入参数设为1即可得到L1与R1,如下:
# 明文字符串
plaintext = "0011100011010101101110000100001011010101001110011001010111100111"
# 密文字符串
key = "1010101100110100100001101001010011011001011100111010001011010011"
# 明文初始IP置换
plaintext = IP(plaintext)
# 分左右
left0, right0 = LeftAndRight_64(plaintext)
# 生成第一个子密钥
key = PC_1(key)
key1 = PC_2(key, 1)
# E扩展
right_E = E(right0)
# S盒代换
right_S = S(right_E, key1)
# P置换
right_P = P(right_S)
# 与左半部分异或,得到R1
right1 = []
for j in range(32):
right1.append(str(int(left0[j]) ^ int(right_P[j])))
# 得到L1
left1 = right0
# 打印
print("L0:", left0)
print("R0:", right0)
print("L1:", left1)
print("R1:", right1)
运行结果:
"E:\Python 3.11.0\python.exe" D:\Python程序\cryptology\DES.py
L0: ['1', '0', '0', '1', '1', '0', '1', '0', '0', '1', '1', '1', '0', '1', '1', '1', '1', '1', '0', '1', '0', '0', '1', '0', '1', '1', '1', '1', '0', '0', '1', '0']
R0: ['1', '1', '0', '1', '0', '1', '1', '0', '1', '0', '1', '0', '0', '1', '0', '1', '0', '0', '1', '0', '0', '1', '0', '1', '1', '0', '0', '0', '1', '0', '0', '0']
L1: ['1', '1', '0', '1', '0', '1', '1', '0', '1', '0', '1', '0', '0', '1', '0', '1', '0', '0', '1', '0', '0', '1', '0', '1', '1', '0', '0', '0', '1', '0', '0', '0']
R1: ['1', '0', '1', '0', '0', '1', '1', '1', '0', '0', '0', '1', '0', '0', '0', '0', '0', '0', '1', '1', '1', '0', '0', '1', '0', '1', '0', '0', '0', '1', '0', '0']
删除DES中部分模块
先准备完整加密过程的六轮加密结果,包含改变前的与改变后的如下:
# 明文字符串
plaintext = "0011100011010101101110000100001011010101001110011001010111100111"
# 密文字符串
key = "1010101100110100100001101001010011011001011100111010001011010011"
# 明文初始IP置换
plaintext = IP(plaintext)
# 密文初始PC-1置换
key = PC_1(key)
# 分左右
left0, right0 = LeftAndRight_64(plaintext)
right0_change = right0.copy()
# 改变right0的最后一位
if right0_change[31] == '0':
right0_change[31] = '1'
else:
right0_change[31] = '0'
# 输出未改变的right0六轮加密的R与L
print("—————————————————————————未改变的right0六轮完整加密的R与L————————————————————————")
for i in range(6):
# E扩展
right_E = E(right0)
# S盒代换
right_S = S(right_E, PC_2(key, i + 1))
# P置换
right_P = P(right_S)
# 与左半部分异或
right2 = []
for j in range(32):
right2.append(str(int(left0[j]) ^ int(right_P[j])))
# 交换左右两部分
left0, right0 = right0, right2
# 打印
print("———————第", i + 1, "轮加密的R与L——————")
print("R:", right0)
print("L:", left0)
# 输出改变最后一位的right0六轮加密的R与L
print("—————————————————————————改变最后一位的right0六轮完整加密的R与L————————————————————————")
for i in range(6):
# E扩展
right_E = E(right0_change)
# S盒代换
right_S = S(right_E, PC_2(key, i + 1))
# P置换
right_P = P(right_S)
# 与左半部分异或
right2 = []
for j in range(32):
right2.append(str(int(left0[j]) ^ int(right_P[j])))
# 交换左右两部分
left0, right0_change = right0_change, right2
# 打印
print("———————第", i + 1, "轮加密的R与L——————")
print("R:", right0_change)
print("L:", left0)
输出结果如下:
—————————————————————————未改变的right0六轮完整加密的R与L————————————————————————
———————第 1 轮加密的R与L——————
R: ['1', '0', '1', '0', '0', '1', '1', '1', '0', '0', '0', '1', '0', '0', '0', '0', '0', '0', '1', '1', '1', '0', '0', '1', '0', '1', '0', '0', '0', '1', '0', '0']
L: ['1', '1', '0', '1', '0', '1', '1', '0', '1', '0', '1', '0', '0', '1', '0', '1', '0', '0', '1', '0', '0', '1', '0', '1', '1', '0', '0', '0', '1', '0', '0', '0']
———————第 2 轮加密的R与L——————
R: ['0', '1', '1', '0', '1', '0', '1', '1', '0', '0', '1', '0', '0', '1', '1', '1', '1', '0', '1', '0', '1', '1', '0', '0', '0', '0', '0', '0', '1', '0', '1', '1']
L: ['1', '0', '1', '0', '0', '1', '1', '1', '0', '0', '0', '1', '0', '0', '0', '0', '0', '0', '1', '1', '1', '0', '0', '1', '0', '1', '0', '0', '0', '1', '0', '0']
———————第 3 轮加密的R与L——————
R: ['1', '1', '0', '1', '1', '1', '1', '0', '1', '0', '1', '1', '0', '1', '1', '0', '1', '1', '0', '0', '0', '0', '1', '0', '1', '0', '0', '0', '0', '1', '1', '0']
L: ['0', '1', '1', '0', '1', '0', '1', '1', '0', '0', '1', '0', '0', '1', '1', '1', '1', '0', '1', '0', '1', '1', '0', '0', '0', '0', '0', '0', '1', '0', '1', '1']
———————第 4 轮加密的R与L——————
R: ['0', '0', '1', '1', '1', '1', '0', '1', '1', '0', '0', '0', '0', '0', '0', '1', '1', '0', '0', '0', '0', '0', '0', '0', '1', '0', '0', '0', '0', '1', '1', '0']
L: ['1', '1', '0', '1', '1', '1', '1', '0', '1', '0', '1', '1', '0', '1', '1', '0', '1', '1', '0', '0', '0', '0', '1', '0', '1', '0', '0', '0', '0', '1', '1', '0']
———————第 5 轮加密的R与L——————
R: ['1', '0', '1', '0', '0', '0', '0', '1', '0', '1', '1', '0', '1', '1', '1', '0', '1', '0', '0', '1', '0', '0', '1', '1', '1', '0', '0', '1', '0', '1', '0', '1']
L: ['0', '0', '1', '1', '1', '1', '0', '1', '1', '0', '0', '0', '0', '0', '0', '1', '1', '0', '0', '0', '0', '0', '0', '0', '1', '0', '0', '0', '0', '1', '1', '0']
———————第 6 轮加密的R与L——————
R: ['0', '1', '0', '0', '1', '1', '0', '1', '1', '1', '0', '1', '1', '1', '1', '1', '0', '1', '1', '0', '1', '0', '0', '1', '0', '0', '0', '0', '0', '1', '1', '0']
L: ['1', '0', '1', '0', '0', '0', '0', '1', '0', '1', '1', '0', '1', '1', '1', '0', '1', '0', '0', '1', '0', '0', '1', '1', '1', '0', '0', '1', '0', '1', '0', '1']
—————————————————————————改变最后一位的right0六轮完整加密的R与L————————————————————————
———————第 1 轮加密的R与L——————
R: ['1', '0', '0', '1', '0', '1', '0', '0', '1', '0', '0', '0', '1', '0', '1', '1', '1', '1', '1', '1', '1', '0', '1', '0', '0', '0', '0', '0', '0', '0', '0', '1']
L: ['1', '1', '0', '1', '0', '1', '1', '0', '1', '0', '1', '0', '0', '1', '0', '1', '0', '0', '1', '0', '0', '1', '0', '1', '1', '0', '0', '0', '1', '0', '0', '1']
———————第 2 轮加密的R与L——————
R: ['0', '0', '1', '0', '1', '0', '1', '1', '1', '0', '1', '0', '1', '1', '0', '1', '0', '0', '1', '1', '1', '0', '0', '1', '1', '1', '0', '0', '0', '1', '1', '0']
L: ['1', '0', '0', '1', '0', '1', '0', '0', '1', '0', '0', '0', '1', '0', '1', '1', '1', '1', '1', '1', '1', '0', '1', '0', '0', '0', '0', '0', '0', '0', '0', '1']
———————第 3 轮加密的R与L——————
R: ['0', '0', '0', '1', '0', '1', '1', '0', '1', '1', '1', '1', '0', '0', '0', '1', '1', '1', '0', '1', '0', '0', '1', '0', '1', '0', '1', '0', '1', '0', '1', '0']
L: ['0', '0', '1', '0', '1', '0', '1', '1', '1', '0', '1', '0', '1', '1', '0', '1', '0', '0', '1', '1', '1', '0', '0', '1', '1', '1', '0', '0', '0', '1', '1', '0']
———————第 4 轮加密的R与L——————
R: ['0', '0', '0', '1', '1', '0', '1', '1', '0', '0', '1', '1', '0', '0', '1', '0', '0', '1', '0', '0', '0', '0', '1', '1', '0', '0', '1', '0', '0', '1', '0', '0']
L: ['0', '0', '0', '1', '0', '1', '1', '0', '1', '1', '1', '1', '0', '0', '0', '1', '1', '1', '0', '1', '0', '0', '1', '0', '1', '0', '1', '0', '1', '0', '1', '0']
———————第 5 轮加密的R与L——————
R: ['1', '0', '0', '0', '1', '0', '1', '1', '1', '0', '0', '0', '1', '0', '0', '1', '1', '1', '0', '0', '1', '0', '0', '1', '0', '0', '0', '0', '0', '1', '0', '1']
L: ['0', '0', '0', '1', '1', '0', '1', '1', '0', '0', '1', '1', '0', '0', '1', '0', '0', '1', '0', '0', '0', '0', '1', '1', '0', '0', '1', '0', '0', '1', '0', '0']
———————第 6 轮加密的R与L——————
R: ['0', '0', '0', '0', '1', '0', '1', '0', '0', '0', '1', '1', '0', '0', '1', '0', '1', '0', '1', '1', '0', '1', '1', '1', '0', '0', '1', '1', '1', '1', '0', '1']
L: ['1', '0', '0', '0', '1', '0', '1', '1', '1', '0', '0', '0', '1', '0', '0', '1', '1', '1', '0', '0', '1', '0', '0', '1', '0', '0', '0', '0', '0', '1', '0', '1']
删除E扩散(32-48填充0)
删除E扩散,更改程序如下:
# 改变最后一位的right0六轮删除E扩散加密的R与L
print("—————————————————————————改变最后一位的right0六轮删除E扩散加密的R与L————————————————————————")
for i in range(6):
# 给right0_change后面补0到48位
right_E = right0_change.copy()
right_E.extend(['0'] * 16)
# S盒代换
right_S = S(right_E, PC_2(key, i + 1))
# P置换
right_P = P(right_S)
# 与左半部分异或
right2 = []
for j in range(32):
right2.append(str(int(left0[j]) ^ int(right_P[j])))
# 交换左右两部分
left0, right0_change = right0_change, right2
# 打印
print("———————第", i + 1, "轮加密的R与L——————")
print("R:", right0_change)
print("L:", left0)
结果如下:
—————————————————————————改变最后一位的right0六轮删除E扩散加密的R与L————————————————————————
———————第 1 轮加密的R与L——————
R: ['1', '1', '1', '1', '0', '0', '1', '1', '1', '0', '0', '0', '1', '1', '0', '1', '1', '0', '0', '0', '0', '1', '1', '0', '0', '1', '0', '1', '0', '1', '1', '1']
L: ['0', '0', '0', '0', '1', '0', '1', '0', '0', '0', '1', '1', '0', '0', '1', '0', '1', '0', '1', '1', '0', '1', '1', '1', '0', '0', '1', '1', '1', '1', '0', '1']
———————第 2 轮加密的R与L——————
R: ['0', '1', '0', '0', '0', '1', '1', '1', '0', '1', '0', '1', '1', '1', '0', '0', '1', '0', '1', '0', '0', '0', '0', '1', '0', '1', '1', '0', '1', '1', '0', '0']
L: ['1', '1', '1', '1', '0', '0', '1', '1', '1', '0', '0', '0', '1', '1', '0', '1', '1', '0', '0', '0', '0', '1', '1', '0', '0', '1', '0', '1', '0', '1', '1', '1']
———————第 3 轮加密的R与L——————
R: ['0', '0', '0', '0', '0', '0', '1', '0', '1', '1', '0', '1', '1', '1', '0', '1', '0', '0', '1', '0', '1', '0', '0', '0', '0', '1', '0', '1', '0', '1', '0', '0']
L: ['0', '1', '0', '0', '0', '1', '1', '1', '0', '1', '0', '1', '1', '1', '0', '0', '1', '0', '1', '0', '0', '0', '0', '1', '0', '1', '1', '0', '1', '1', '0', '0']
———————第 4 轮加密的R与L——————
R: ['1', '1', '1', '0', '1', '0', '0', '0', '1', '0', '1', '0', '0', '1', '1', '1', '0', '1', '1', '1', '0', '0', '0', '1', '1', '0', '1', '0', '1', '1', '0', '0']
L: ['0', '0', '0', '0', '0', '0', '1', '0', '1', '1', '0', '1', '1', '1', '0', '1', '0', '0', '1', '0', '1', '0', '0', '0', '0', '1', '0', '1', '0', '1', '0', '0']
———————第 5 轮加密的R与L——————
R: ['0', '1', '1', '1', '0', '0', '1', '0', '0', '0', '1', '1', '0', '1', '1', '0', '1', '1', '0', '0', '1', '0', '1', '0', '0', '1', '1', '1', '0', '1', '0', '1']
L: ['1', '1', '1', '0', '1', '0', '0', '0', '1', '0', '1', '0', '0', '1', '1', '1', '0', '1', '1', '1', '0', '0', '0', '1', '1', '0', '1', '0', '1', '1', '0', '0']
———————第 6 轮加密的R与L——————
R: ['0', '0', '1', '1', '0', '0', '1', '1', '1', '1', '0', '0', '1', '0', '1', '1', '1', '0', '1', '1', '0', '1', '1', '0', '1', '1', '0', '1', '0', '1', '0', '0']
L: ['0', '1', '1', '1', '0', '0', '1', '0', '0', '0', '1', '1', '0', '1', '1', '0', '1', '1', '0', '0', '1', '0', '1', '0', '0', '1', '1', '1', '0', '1', '0', '1']
删除S-box(取S-box输入的中间4bit为输出)
修改S函数的代码,如下:
# 改变最后一位的right0六轮删除S核加密的R与L
# 重写S函数为S1,取中间的4bit为输出
def S1(right_E, SubK):
# 与轮密钥执行一次异或
result = []
for i in range(48):
result.append(str(int(right_E[i]) ^ int(SubK[i])))
# 取六位中间的四位
result2 = []
for i in range(8):
# 一个个加进result2
result2.append(result[i * 6 + 1])
result2.append(result[i * 6 + 2])
result2.append(result[i * 6 + 3])
result2.append(result[i * 6 + 4])
return result2
print("—————————————————————————改变最后一位的right0六轮删除S盒加密的R与L————————————————————————")
for i in range(6):
# E扩展
right_E = E(right0_change)
# 调用S1函数
right_S = S1(right_E, PC_2(key, i + 1))
# P置换
right_P = P(right_S)
# 与左半部分异或
right2 = []
for j in range(32):
right2.append(str(int(left0[j]) ^ int(right_P[j])))
# 交换左右两部分
left0, right0_change = right0_change, right2
# 打印
print("———————第", i + 1, "轮加密的R与L——————")
print("R:", right0_change)
print("L:", left0)
结果如下:
—————————————————————————改变最后一位的right0六轮删除S盒加密的R与L————————————————————————
———————第 1 轮加密的R与L——————
R: ['1', '0', '1', '0', '1', '1', '0', '0', '1', '1', '0', '0', '1', '1', '1', '1', '0', '0', '1', '1', '0', '1', '1', '1', '1', '1', '0', '1', '0', '0', '0', '0']
L: ['0', '0', '1', '1', '0', '0', '1', '1', '1', '1', '0', '0', '1', '0', '1', '1', '1', '0', '1', '1', '0', '1', '1', '0', '1', '1', '0', '1', '0', '1', '0', '0']
———————第 2 轮加密的R与L——————
R: ['1', '1', '0', '0', '0', '1', '1', '1', '1', '0', '1', '0', '1', '0', '1', '0', '1', '1', '0', '1', '1', '0', '0', '1', '0', '1', '1', '0', '0', '0', '0', '1']
L: ['1', '0', '1', '0', '1', '1', '0', '0', '1', '1', '0', '0', '1', '1', '1', '1', '0', '0', '1', '1', '0', '1', '1', '1', '1', '1', '0', '1', '0', '0', '0', '0']
———————第 3 轮加密的R与L——————
R: ['1', '1', '0', '1', '1', '0', '0', '1', '0', '1', '0', '0', '0', '0', '1', '1', '1', '0', '0', '1', '1', '0', '0', '1', '0', '1', '0', '1', '1', '0', '1', '1']
L: ['1', '1', '0', '0', '0', '1', '1', '1', '1', '0', '1', '0', '1', '0', '1', '0', '1', '1', '0', '1', '1', '0', '0', '1', '0', '1', '1', '0', '0', '0', '0', '1']
———————第 4 轮加密的R与L——————
R: ['1', '0', '0', '1', '0', '0', '0', '1', '1', '1', '1', '1', '1', '0', '1', '0', '0', '1', '1', '0', '0', '1', '1', '0', '1', '1', '1', '0', '1', '0', '1', '0']
L: ['1', '1', '0', '1', '1', '0', '0', '1', '0', '1', '0', '0', '0', '0', '1', '1', '1', '0', '0', '1', '1', '0', '0', '1', '0', '1', '0', '1', '1', '0', '1', '1']
———————第 5 轮加密的R与L——————
R: ['1', '1', '1', '0', '0', '0', '1', '1', '0', '1', '0', '1', '1', '1', '0', '0', '0', '0', '1', '1', '1', '0', '1', '1', '1', '0', '1', '0', '1', '0', '1', '1']
L: ['1', '0', '0', '1', '0', '0', '0', '1', '1', '1', '1', '1', '1', '0', '1', '0', '0', '1', '1', '0', '0', '1', '1', '0', '1', '1', '1', '0', '1', '0', '1', '0']
———————第 6 轮加密的R与L——————
R: ['0', '1', '0', '0', '0', '0', '0', '0', '1', '0', '1', '1', '1', '1', '0', '1', '1', '0', '1', '0', '1', '0', '1', '1', '0', '0', '1', '1', '1', '0', '0', '0']
L: ['1', '1', '1', '0', '0', '0', '1', '1', '0', '1', '0', '1', '1', '1', '0', '0', '0', '0', '1', '1', '1', '0', '1', '1', '1', '0', '1', '0', '1', '0', '1', '1']
删除P置换
删除P置换函数,代码如下:
# 改变最后一位的right0六轮删除P置换加密的R与L
print("—————————————————————————改变最后一位的right0六轮删除P置换加密的R与L————————————————————————")
for i in range(6):
# E扩展
right_E = E(right0_change)
# S盒代换
right_S = S(right_E, PC_2(key, i + 1))
# 与左半部分异或
right2 = []
for j in range(32):
right2.append(str(int(left0[j]) ^ int(right_P[j])))
# 交换左右两部分
left0, right0_change = right0_change, right2
# 打印
print("———————第", i + 1, "轮加密的R与L——————")
print("R:", right0_change)
print("L:", left0)
结果如下:
—————————————————————————改变最后一位的right0六轮删除P置换加密的R与L————————————————————————
———————第 1 轮加密的R与L——————
R: ['0', '0', '1', '1', '0', '0', '1', '0', '0', '0', '0', '1', '1', '0', '1', '1', '1', '1', '1', '1', '0', '1', '1', '0', '0', '1', '1', '1', '1', '0', '0', '1']
L: ['0', '1', '0', '0', '0', '0', '0', '0', '1', '0', '1', '1', '1', '1', '0', '1', '1', '0', '1', '0', '1', '0', '1', '1', '0', '0', '1', '1', '1', '0', '0', '0']
———————第 2 轮加密的R与L——————
R: ['1', '0', '0', '1', '0', '0', '0', '1', '1', '1', '1', '1', '1', '0', '1', '0', '0', '1', '1', '0', '0', '1', '1', '0', '1', '1', '1', '0', '1', '0', '1', '0']
L: ['0', '0', '1', '1', '0', '0', '1', '0', '0', '0', '0', '1', '1', '0', '1', '1', '1', '1', '1', '1', '0', '1', '1', '0', '0', '1', '1', '1', '1', '0', '0', '1']
———————第 3 轮加密的R与L——————
R: ['1', '1', '1', '0', '0', '0', '1', '1', '0', '1', '0', '1', '1', '1', '0', '0', '0', '0', '1', '1', '1', '0', '1', '1', '1', '0', '1', '0', '1', '0', '1', '1']
L: ['1', '0', '0', '1', '0', '0', '0', '1', '1', '1', '1', '1', '1', '0', '1', '0', '0', '1', '1', '0', '0', '1', '1', '0', '1', '1', '1', '0', '1', '0', '1', '0']
———————第 4 轮加密的R与L——————
R: ['0', '1', '0', '0', '0', '0', '0', '0', '1', '0', '1', '1', '1', '1', '0', '1', '1', '0', '1', '0', '1', '0', '1', '1', '0', '0', '1', '1', '1', '0', '0', '0']
L: ['1', '1', '1', '0', '0', '0', '1', '1', '0', '1', '0', '1', '1', '1', '0', '0', '0', '0', '1', '1', '1', '0', '1', '1', '1', '0', '1', '0', '1', '0', '1', '1']
———————第 5 轮加密的R与L——————
R: ['0', '0', '1', '1', '0', '0', '1', '0', '0', '0', '0', '1', '1', '0', '1', '1', '1', '1', '1', '1', '0', '1', '1', '0', '0', '1', '1', '1', '1', '0', '0', '1']
L: ['0', '1', '0', '0', '0', '0', '0', '0', '1', '0', '1', '1', '1', '1', '0', '1', '1', '0', '1', '0', '1', '0', '1', '1', '0', '0', '1', '1', '1', '0', '0', '0']
———————第 6 轮加密的R与L——————
R: ['1', '0', '0', '1', '0', '0', '0', '1', '1', '1', '1', '1', '1', '0', '1', '0', '0', '1', '1', '0', '0', '1', '1', '0', '1', '1', '1', '0', '1', '0', '1', '0']
L: ['0', '0', '1', '1', '0', '0', '1', '0', '0', '0', '0', '1', '1', '0', '1', '1', '1', '1', '1', '1', '0', '1', '1', '0', '0', '1', '1', '1', '1', '0', '0', '1']
从结果分析混乱、扩散效果
通过比较正常DES和修改后DES的轮函数输出,我们可以看出E扩展、S盒和P置换在实现混乱和扩散方面的重要作用。这些组件的缺失显著影响了加密的强度和安全性,减少了由输入的微小变化所引起的广泛输出变化。因此,每一个组件都是DES高安全性的关键部分。
初始变化的影响
首先,考虑改变right0
的最后一位后,第1轮的输出与原始数据的对比:
未改变时的第1轮输出(原始):
R: ['1', '0', '1', '0', '0', '1', '1', '1', '0', '0', '0', '1', '0', '0', '0', '0', '0', '0', '1', '1', '1', '0', '0', '1', '0', '1', '0', '0', '0', '1', '0', '0']
L: ['1', '1', '0', '1', '0', '1', '1', '0', '1', '0', '1', '0', '0', '1', '0', '1', '0', '0', '1', '0', '0', '1', '0', '1', '1', '0', '0', '0', '1', '0', '0', '0']
改变后的第1轮输出:
R: ['1', '0', '0', '1', '0', '1', '0', '0', '1', '0', '0', '0', '1', '0', '1', '1', '1', '1', '1', '1', '1', '0', '1', '0', '0', '0', '0', '0', '0', '0', '0', '1']
L: ['1', '1', '0', '1', '0', '1', '1', '0', '1', '0', '1', '0', '0', '1', '0', '1', '0', '0', '1', '0', '0', '1', '0', '1', '1', '0', '0', '0', '1', '0', '0', '1']
可以看到,单单是改变right0
的最后一位,就已经导致了第1轮输出中R部分有多个位的显著变化。这展示了E扩展和S盒在加密过程中的混乱性,即输入的微小变化通过这些组件的处理被放大。
深入到后续轮次
继续分析到第6轮,我们可以看到初始的单一变化如何影响更多位:
未改变时的第6轮输出(原始):
R: ['0', '1', '0', '0', '1', '1', '0', '1', '1', '1', '0', '1', '1', '1', '1', '1', '0', '1', '1', '0', '1', '0', '0', '1', '0', '0', '0', '0', '0', '1', '1', '0']
L: ['1', '0', '1', '0', '0', '0', '0', '1', '0', '1', '1', '0', '1', '1', '1', '0', '1', '0', '0', '1', '0', '0', '1', '1', '1', '0', '0', '1', '0', '1', '0', '1']
改变后的第6轮输出:
R: ['0', '0', '1', '1', '0', '0', '1', '1', '1', '1', '0', '0', '1', '0', '1', '1', '1', '0', '1', '1', '0', '1', '1', '0', '1', '1', '0', '1', '0', '1', '0', '0']
L: ['0', '1', '1', '1', '0', '0', '1', '0', '0', '0', '1', '1', '0', '1', '1', '0', '1', '1', '0', '0', '1', '0', '1', '0', '0', '1', '1', '1', '0', '1', '0', '1']
从这些数据中可以看出,改变单个输入位对于最终输出的R和L部分产生了广泛的影响,覆盖了多个不同的位置。这种广泛的位变化说明DES算法的轮函数成功实现了扩散的目标,确保了密钥空间的高度安全性和预测难度。
删除E扩展的情况
E扩展操作通过将32位的数据扩展到48位,增加了冗余,使得每个输入位影响多个S盒的输出。删除E扩展意味着S盒将接收到较少的、未扩展的输入,这可能减少了混乱和扩散的效果。
第6轮输出(删除E扩展):
R: ['0', '0', '1', '1', '0', '0', '1', '1', '1', '1', '0', '0', '1', '0', '1', '1', '1', '0', '1', '1', '0', '1', '1', '0', '1', '1', '0', '1', '0', '1', '0', '0']
L: ['0', '1', '1', '1', '0', '0', '1', '0', '0', '0', '1', '1', '0', '1', '1', '0', '1', '1', '0', '0', '1', '0', '1', '0', '0', '1', '1', '1', '0', '1', '0', '1']
与正常加密对比,可以看到删除E扩展后,虽然输出依旧有改变,但混乱和扩散的速率可能较正常情况为低,因为没有额外的位扩展带来的更广的影响。
删除S盒的情况
S盒提供非线性的变换,是DES中实现混乱的核心。删除S盒,理论上将大大减少加密过程中的混乱和扩散。
第6轮输出(删除S盒):
R: ['0', '1', '0', '0', '0', '0', '0', '0', '1', '0', '1', '1', '1', '1', '0', '1', '1', '0', '1', '0', '1', '0', '1', '1', '0', '0', '1', '1', '1', '0', '0', '0']
L: ['1', '1', '1', '0', '0', '0', '1', '1', '0', '1', '0', '1', '1', '1', '0', '0', '0', '0', '1', '1', '1', '0', '1', '1', '1', '0', '1', '0', '1', '0', '1', '1']
从数据看,删除S盒后的输出仍然存在一些变化,但这些变化较为规律,可能不如完整的S盒带来的混乱性高。
删除P置换的情况
P置换的作用是将S盒输出重新排序,以增加扩散效果。删除P置换意味着减少了输出之间的交互,可能减缓了扩散速度。
第6轮输出(删除P置换):
R: ['1', '0', '0', '1', '0', '0', '0', '1', '1', '1', '1', '1', '1', '0', '1', '0', '0', '1', '1', '0', '0', '1', '1', '0', '1', '1', '1', '0', '1', '0', '1', '0']
L: ['0', '0', '1', '1', '0', '0', '1', '0', '0', '0', '0', '1', '1', '0', '1', '1', '1', '1', '1', '1', '0', '1', '1', '0', '0', '1', '1', '1', '1', '0', '0', '1']
删除P置换后,输出依然存在变化,但由于没有了位的重新分配,变化的位可能较为集中,不如完整P置换的扩散性强。
多重DES中间件攻击
两个密钥(EDE)
假设我们已知一个明文P
和一个密文C
,定义两个中间值X1、X2
,则有:
X1 = D(K1,C)=D(K2,E(K1,P))
X2 = E(K2,X1)=E(K1,P)
选取明文P,使用所有可能的K1进行加密,保存加密结果和对应的K1密钥。
选取密文C,使用第一步的K1进行解密,保存解密结果。
选取2. 的解密结果,使用可能的K2进行加密,若结果与1. 的加密结果相同,则找出密钥对K1、K2。
计算复杂度分析:
第一步使用到的K1共有256个,因此计算复杂度为256
第二部与第一步使用的密钥相等,因此计算复杂度为256
第三步结果与第二步相关联,且使用到的K2最坏情况下为256个,因此计算复杂度为O(256*256)+O(256)+O(1)=O(2112)
空间复杂度分析:
在上述三个步骤中,需要存储的其实只有第一步的结果,第二部算出的结果可以立即参与第三步,第三步的计算结果立即与第一步存储的结果进行比较,不相等即丢弃,因此空间复杂度为O(256)
三个密钥(EEE)
假设我们已知一个明文P
和一个密文C
,定义两个中间值X1、X2
,则有:
X1 = D(K1,C)=E(K2,E(K3,P))
X2 = D(K2,X1)=E(K3,P)
选取明文P,使用所有可能的K3进行加密,保存加密结果和对应的K3密钥。
选取密文C,使用所有可能的K1进行解密,保存解密结果和对应的K1密钥。
选取2. 的解密结果,使用可能的K2进行加密,若结果与1. 的加密结果相同,则找出密钥对K1、K2。
计算复杂度分析:
第一步使用到的K3共有256个,因此计算复杂度为256
第一步使用到的K1共有256个,因此计算复杂度为256
第三步结果与第二步相关联,且使用到的K2最坏情况下为256个,因此计算复杂度为O(256*256)+O(256)+O(256)=O(2112)
空间复杂度分析:
在上述三个步骤中,第一步与第二部的结果需要存储起来,各有256个,第三步的计算结果可以直接与第一步的加密结果进行比较,可以不储存,因此空间复杂度为O(256+256)=O(257)
- 感谢你赐予我前进的力量