一次网络安全的练手作业…
class S_DES:
"""
简化DES, S-DES, 一种对称加密算法
可使用两个8位密钥,或由一个10位密钥生成两个8位密钥
明文和密文限制为8位
@author ZJH
2021/10/6
"""
def IP(self, text: str) -> str:
orderIP = '15203746'
return ''.join([text[int(i)] for i in orderIP])
def IP_RE(self, text: str) -> str:
orderIP_RE = '30246175'
return ''.join([text[int(i)] for i in orderIP_RE])
def SW(self, text: str) -> str:
return text[4:] + text[:4]
def generateKey(self, P10: str) -> tuple:
"""
用10位密钥产生两位8位密钥
:param P10: 10位密钥, str
:return: 2个8位密钥, tuple, (K1,K2)
"""
# 置换P10
order10 = '2416390875'
P10 = ''.join([P10[int(i)] for i in order10])
# 左移
P10 = P10[1:5] + P10[0] + P10[6:] + P10[5]
# 产生8位K1
order8 = '52637498'
self.K1 = ''.join([P10[int(i)] for i in order8])
# 左移2次
P10 = P10[1:5] + P10[0] + P10[6:] + P10[5]
P10 = P10[1:5] + P10[0] + P10[6:] + P10[5]
# 产生8位K2
self.K2 = ''.join([P10[int(i)] for i in order8])
print('KEY1:\t{}\nKEY2:\t{}'.format(self.K1, self.K2))
return (self.K1, self.K2)
def funK(self, text: str, key: str) -> str:
# 分半
L, R = text[:4], text[4:]
# 拓展/置换
ep1 = R[3] + R[:3]
ep2 = R[1:] + R[0]
# 异或
ep1 = [str(int(a) ^ int(b)) for a, b in zip(ep1, key[:4])]
ep2 = [str(int(a) ^ int(b)) for a, b in zip(ep2, key[4:])]
# 映射
S1 = ('1032', '3210', '0213', '3132')
S2 = ('0123', '2013', '3010', '2103')
ep1 = S1[int(ep1[0] + ep1[3], 2)][int(ep1[1] + ep1[2], 2)]
ep1 = '{0:02b}'.format(int(ep1))
ep2 = S2[int(ep2[0] + ep2[3], 2)][int(ep2[1] + ep2[2], 2)]
ep2 = '{0:02b}'.format(int(ep2))
mappingF = ep1[1] + ep2[::-1] + ep1[0]
# 映射结果异或
L = int(mappingF, 2) ^ int(L, 2)
L = '{0:04b}'.format(int(L))
# 组合得到结果
res = L + R
# print('RES:\t'+res)
return res
def initKey(self, key1, key2=''):
"""
自动初始化密钥
eg:
initKey(self,10位密钥)
or
initKey(self,8位密钥1)
or
initKey(self,8位密钥1, 8位密钥1)
or
initKey(self,8位密钥1, 8位密钥2)
:param key1: 密钥1 8或10位,str
:param key2: 密钥2 8位 密钥1为10位时不需要传入, str, ''
:return:
"""
assert len(key1) in (8, 10), '密钥1长度不合法, 应该为8或10位str:' + key1
if len(key1) == 10:
print('你输入的是10位密钥,将自动生产两个8位密钥')
self.generateKey(key1)
else:
if not key2:
print('你输入了一个8位密钥')
self.K1 = self.K2 = key1
else:
assert len(key2) == 8, '密钥2长度不合法, 应该为8位str:' + key2
print('你输入了两个8位密钥')
self.K1, self.K2 = key1, key2
def encode(self, text: str) -> str:
assert len(text) == 8, '明文长度不合法, 应该为8位str:' + text
text = self.IP(text)
text = self.funK(text, self.K1)
text = self.SW(text)
text = self.funK(text, self.K2)
text = self.IP_RE(text)
print('加密完成, 密文: ' + text)
return text
def decode(self, text: str) -> str:
assert len(text) == 8, '密文长度不合法, 应该为8位str:' + text
text = self.IP(text)
text = self.funK(text, self.K2)
text = self.SW(text)
text = self.funK(text, self.K1)
text = self.IP_RE(text)
print('解密完成, 明文: ' + text)
return text
def __init__(self, *args, **kwargs):
if args or kwargs:
print('自动设置密钥')
self.initKey(*args, **kwargs)
else:
print('未设置密钥')
if __name__ == '__main__':
# s=S_DES()
# s.initKey('1010000010')
# s.initKey('10100100')
# s.initKey('10100100','01000011')
s = S_DES('1010000010')
res = s.encode('1' * 8)
s.decode(res)