赞
踩
DES(Data Encryption Standard)是迄今为止世界上最为广泛使用和流行的一种分组密码算法,它的分组长度为64比特,密钥长度为56比特,它是由美国IBM公司研制的,是早期的称作Lucifer密码的一种发展和修改。 每隔五年由美国国家保密局(NSA)作出评估,并重新批准它是否继续作为联邦加密标准。最后一次评估是在1994年1月,美国已决定1998年12月以后将不再使用DES。 DES是第一代公开的、完全说明细节的商业级现代算法,并被世界公认。
DES加密基于Feistel结构实现,其轮结构如下图所示:
DES的加密过程:
明文二进制的加密:
将明文数据转为二进制
,再将二进制数据分组
,每组64位,组元素不满64 则在后面补0,满64为止。再将每一组64bit数据进行初始置换
在进行轮函数。
轮函数中将右边32bit
进行F运算
,然后与左边32bit进行异或
,得到的结果作为下一轮右边
将刚开始的右边作为下一轮左边
,依次循环16次
,最后进行逆初始置换
,即可得到密文二进制
。
将明文秘钥转换为二进制 ,取56bit
为一组,不满56bit 补0
,然后进行秘钥生成,将得到的秘钥组
,分别拿去参与每一轮的F运算
,即第一组秘钥对应第一轮F函数
,生成的每组秘钥长度为:48bit
加密和解密一样,不同的点是,最后一组秘钥对应第一轮F函数
,即把秘钥组反过来
而已。
看完大致流程,我们来看看具体的代码实现,有Java版和Python版,为了方便就以Python版来讲解,文章末尾会附上Java和Python的全部代码。
实现的过程我们根据DES加密流程来一步一步的实现。(看着流程图
一步一步来)
1.明文转二进制
这一步我觉得比较重要,首先你的明文可能 是 中文+字母
这样如果转二进制然后加密解密,得出的结果是不一样
的,会出现一些奇怪的字符(乱码
),如果只加密字母和数字
就不会出现。
所以我们需要另一种字符形式来代替它,且只含有字母和数字 的组成,没错,就是转成16进制字符串
,DES中在进制转换这块,看下图。
进制转换这块的流程大概就是这些,我们来实现 第一步,将明文
转成16进制
。
来看Python的代码
# 字符串转16进制字符串
def str2hex(self, string: str):
return bytes.hex(string.encode('utf8'))
# 16进制字符串转字符串
def hex2str(self, hexstr):
return bytes.fromhex(hexstr).decode()
啊这,是不是很简单,就是将明文编码
为utf-8,得到字节
,然后转16进制
,反过来就是解码
,在python中是这样,原来在Java版
代码中可以详细看看怎么实现。
结果如下
:
hello,世界 --> 68656c6c6f2ce4b896e7958c
68656c6c6f2ce4b896e7958c --> hello,世界
接下来转二进制
十六进制转二进制,一个一个取出来然后转换,写了两种
,选择一种即可。注意,每一个字符
对应4位二进制位
如6->0110
# 十六进制转二进制 def hex2bin(self, hex): hex_to_bin_table = ( '0000', '0001', '0010', '0011', '0100', '0101', '0110', '0111', '1000', '1001', '1010', '1011', '1100', '1101', '1110', '1111') bin_string = '' for i in hex: i = int(i, 16) bin_string = bin_string + hex_to_bin_table[i] return bin_string def hex2bin1(self, hex): hex_table = "0123456789ABCDEF" s = "" for i in hex: k = str(bin(hex_table.find(i.upper()))[2:]) if len(k) < 4: k = (4 - len(k)) * "0" + k s += k return s # 二进制转十六进制 def bin2hex(self, bin): changed_str = '' while len(bin) > 0: temp = int(bin[:4], 2) changed_str += '%0x' % temp bin = bin[4:] return changed_str def bin2hex1(self, bin): hextable = "0123456789ABCDEF" binlist = re.findall(r".{4}", bin) s = "" for i in binlist: s += hextable[int(i, 2)].lower() return s
这样就得到了明文的二进制形式,接下来只要进行加密即可
我们把明文转二进制
变成一个函数
,且校验是否满64位
:
def text2Bin(self, txt: str) -> str:
"""
将明文 or 秘钥转换为二进制流 且%64=0
:param txt: 输入的明文或秘钥
:return: 运算的二进制流
"""
txt = self.str2hex(txt) # 字符串转十六进制字符串
bintxt = self.hex2bin(txt) # 十六进制字符串 转 二进制字符串
k = len(bintxt) % 64
if k != 0:
bintxt += "0" * (64 - k)
return bintxt
生成16轮的秘钥组原理图
代码中的所有置换表
都在文末
的最终代码里面
生成秘钥
:接受一个二进制秘钥流
64bit,进行PC1置换
,取前56位,然后一分为二,每个28bit,然后进行循环移位
,就是根据移位表
,数字2:表示把二进制串左边2个接到右边后面,移位完将
C0和D0拼接在一起,进行PC2置换
,得到子秘钥
,然后再将上次循环移位的结果继续循环移位,依次生成完16组
def generateKeyTo16(self, binKey: str): """ 生成16组秘钥 :param binKey: 初始秘钥 :return: 16组秘钥列表 """ keyList = [] # 置换选择PC-1 z1 = "" for i in self.PC_1: z1 += binKey[i - 1] # 28 bit key leftKey = z1[:28] rightKey = z1[28:] def leftShift(m, s): # 移位函数 s:移多少 return m[s:] + m[:s] for shift in self.SHIFT: leftKey = leftShift(leftKey, shift) rightKey = leftShift(rightKey, shift) # 置换选择PC-2 zh = leftKey + rightKey ans = "" for i in self.PC_2: ans += zh[i - 1] keyList.append(ans) # 添加秘钥 return keyList
函数的输入分析: 1.一个32bit的 二进制流
2. 48bit的二进制秘钥
E表置换
:将32bit扩展成48bit(将某些位重复)
异或
:将E表结果和秘钥进行异或
S盒代换
:将异或结果(48bit)进行S盒代换
将48bit分成8份
,每份6bit ,然后再让6bit变4bit 怎么变?
首先,将6bit首尾 的一个字符合并成2个 作为行号
,剩下的不变,作为列号
如:010011
->行:01
列:1001
,然后 行号列号 转十进制
数字,去S盒
中查询行列对应的值,再把这个值转为二进制
。(注意,第一组6bit 对应的是第一组S盒)
如将 010011
根据上图S盒表
进行代换,那么 行
:01 列
1001 十进制分别是 1
和9
第一行 第九列 结果为6
二进制为 0110
。
再将S盒所有结果拼凑起来
,进行P表置换
,得到F函数的输出
# XOR 异或操作 def msgXorKey(self, left, right) -> str: xor = "" for i in range(len(left)): xor += str(int(left[i]) ^ int(right[i])) return xor # f函数 def FFunction(self, binText: str, binKey: str) -> str: # 定义几个函数 # E表扩展 def e_Extend(bintxt) -> str: e = "" for i in self.E: e += bintxt[i - 1] return e # S盒处理 def S_Box(bintxt: str) -> str: ans = "" bit6list = re.findall(r".{6}", bintxt) flag = 0 for b in bit6list: k = int(b[0] + b[len(b) - 1], 2) # 获取 行 v = int(b[1:5], 2) # 获取列 sValue = bin(self.S[flag][k * 16 + v])[2:] # S盒查询的结果转2进制 if len(sValue) < 4: sValue = "0" * (4 - len(sValue)) + sValue flag += 1 ans += sValue return ans # P置换 def P_Swap(bintxt: str) -> str: ans = "" for i in self.P: ans += bintxt[i - 1] return ans # 开始处理 E表->异或->S盒->P置换 return P_Swap(S_Box(self.msgXorKey(e_Extend(binText), binKey)))
参数
: 1. 64bit的待加密二进制
2.秘钥组
(秘钥组中的秘钥给F函数用的)
开始,首先先将64bit
进行初始置换
,然后分为32bit 32bit,将右边的32bit
进行 F函数
,然后在和左边32bit 异或
得到的结果作为下一轮右边
,刚开始的右边32bit 作为下一轮的左边
。依次进行了16
次
以后,再将结果左右交换
,然后进行逆初始置换
,即可得到密文
。
# ip置换和逆置换 def ip_Swap(self, bit, reTable=False): n = "" if reTable is True: for i in self.IP_re_table: n += bit[i - 1] else: for i in self.IP_table: n += bit[i - 1] return n # 轮函数 def WheelFunction(self, bitTo64: str, keyList: list): # 初始置换(IP置换) n = self.ip_Swap(bitTo64) leftBit = n[:32] rightBit = n[32:] # 获取16轮秘钥 for rot in keyList: # 16轮加密 temp = rightBit k32 = self.FFunction(rightBit, rot) rightBit = self.msgXorKey(leftBit, k32) # 异或 leftBit = temp # 左右交换 swapValue = rightBit + leftBit # 逆 初始置换 Ciphertext = self.ip_Swap(swapValue, True) return Ciphertext
整合上面实现加密
参数
: 1. 明文 2. 秘钥
def encryption(self, msg: str, key: str):
"""
DES加密
:param msg: 明文消息
:param key: 明文秘钥
:return: 密文
"""
binMsgList = re.findall(r".{64}", self.text2Bin(msg)) # 64bit文明二进制列表
k64 = re.findall(r".{64}", self.text2Bin(key))[0] # 秘钥二进制流
binKeyList = self.generateKeyTo16(k64) #生成秘钥组
binaryCipher = ""
for bitTo64 in binMsgList: # 依次把二进制流和秘钥 进行加密
binaryCipher += self.WheelFunction(bitTo64, binKeyList)
return self.bin2hex(binaryCipher) # 二进制结果转16进制
接收参数
: 1.16进制密文
2.秘钥
注意:解密的秘钥组要反过来
def decryption(self, msg: str, key: str):
"""
DES解密
:param msg: 密文
:param key: 秘钥
:return: 明文
"""
binMsgList = re.findall(r".{64}", self.hex2bin(msg)) # 64bit二进制列表
k64 = re.findall(r".{64}", self.text2Bin(key))[0] # 秘钥二进制流m
binKeyList = self.generateKeyTo16(k64)
binaryCipher = ""
for bitTo64 in binMsgList:
binaryCipher += self.WheelFunction(bitTo64, binKeyList[::-1]) # [::-1]将列表反转,即秘钥组反过来
return self.hex2str(self.bin2hex(binaryCipher))
des = DesUtil()
s = des.encryption("你好啊,world", "lightr.cn")
print(f"加密结果:{s}")
print(f"{s}的解密结果:{des.decryption(s, 'lightr.cn')}")
加密结果
:
bea987772587d33d80f57b15ec011c57
bea987772587d33d80f57b15ec011c57的解密结果:你好啊,world
Java版
import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public class DesUtil { /** * DES加密 * @param msg 明文消息 * @param key 明文秘钥 * @return 16进制密文字符串 */ public String encryption(String msg, String key){ String msgbin = Check64(hex2Bin(str2Hex(msg))); String keybin = Check64(hex2Bin(str2Hex(key))); String[] msgs = regex(msgbin, ".{64}"); String k = regex(keybin, ".{64}")[0]; String[] keys = generateKey(k); StringBuilder mm = new StringBuilder(); for (String binmsg : msgs) { mm.append(Wheel(binmsg, keys)); } return bin2Hex(mm.toString().trim()).toLowerCase(); } /** * DES解密 * @param cipher 16进制密文 * @param key 解密/加密 秘钥 * @return 明文字符串 */ public String decryption(String cipher, String key){ String msgbin = hex2Bin(cipher); key = Check64(hex2Bin(str2Hex(key))); String[] cpbin = regex(msgbin, ".{64}"); String k = regex(key, ".{64}")[0]; String[] keys = generateKey(k); Collections.reverse(Arrays.asList(keys)); //反转数组 StringBuilder mm = new StringBuilder(); for (String binmsg : cpbin) { mm.append(Wheel(binmsg, keys)); } return hex2Str(bin2Hex(mm.toString().trim())).trim(); } // =========进制转换=============== /** * 字符串转十六进制字符串 * * @param str String * @return HexString */ public String str2Hex(String str) { char[] chars = "0123456789ABCDEF".toCharArray(); StringBuilder stringBuilder = new StringBuilder(); byte[] bytes = str.getBytes(); int bt; for (byte b : bytes) { bt = (b & 0x0f0) >> 4; stringBuilder.append(chars[bt]); stringBuilder.append(chars[(b & 0x00f)]); } return stringBuilder.toString().trim().toLowerCase(); } /** * 十六进制字符串转字符串 * * @param hexStr * @return */ public String hex2Str(String hexStr) { String str16 = "0123456789ABCDEF"; char[] chars = str16.toCharArray(); byte[] bytes = new byte[hexStr.length() / 2]; char[] hex = hexStr.toUpperCase().toCharArray(); int i; for (int j = 0; j < bytes.length; j++) { i = str16.indexOf(hex[j * 2]) << 4; i += str16.indexOf(hex[j * 2 + 1]); bytes[j] = (byte) i; } return new String(bytes); } public String hex2Bin(String hexStr) { char[] hexchr = hexStr.toLowerCase().toCharArray(); String binStr = ""; for (char i : hexchr) { String bin = Integer.toBinaryString(Integer.parseInt(String.valueOf(i),16)); if (bin.length() < 4) { bin = String.join("", Collections.nCopies(4 - bin.length(), "0")) + bin; } binStr += bin; } return binStr; } public String bin2Hex(String bin){ char[] chars = "0123456789ABCDEF".toCharArray(); String[] h4 = regex(bin, ".{4}"); StringBuilder hexstr = new StringBuilder(); for (String s : h4) { hexstr.append(chars[Integer.parseInt(s,2)]); } return hexstr.toString().trim(); } /** * 检查二进制字符串是否是64位 * @param binStr str * @return str64 */ public String Check64(String binStr) { int num = binStr.length() % 64; if (num != 0) { binStr += String.join("", Collections.nCopies(64 - num, "0")); } return binStr; } /** * 正则获取匹配的值 * @param str 字符串 * @param regex 正则表达式 * @return String[] */ public String[] regex(String str,String regex){ Matcher matcher = Pattern.compile(regex).matcher(str); List<String> list = new ArrayList<>(); while (matcher.find()){ list.add(matcher.group(0)); } String[] strings = new String[list.size()]; list.toArray(strings); return strings; } /** * 0 1 的异或 * @param left 二进制字符串 * @param right 二进制字符串 * @return xor */ public String xor(String left,String right){ StringBuilder str = new StringBuilder(); char[] leftchr = left.toCharArray(); char[] rightchr = right.toCharArray(); for (int i = 0; i < leftchr.length; i++) { str.append(leftchr[i] ^rightchr[i]); } return str.toString().trim(); } /** * F函数的实现 * @param bin32 64位明文的右边32位 * @param key 当前轮的加密秘钥 * @return */ public String f_function(String bin32,String key){ //E表置换 bin32 = Swap(bin32,E); // 异或 String xor = xor(bin32, key); //S盒代换 String[] slist = regex(xor, ".{6}"); StringBuilder builder = new StringBuilder(); for (int i = 0; i < slist.length; i++) { String s = slist[i]; int h = Integer.parseInt(s.substring(0,1) + s.substring(5),2); int l = Integer.parseInt(s.substring(1,5) ,2); String i1 = Integer.toBinaryString(S[i][h * 16 + l]); if (i1.length()<4){ i1 = String.join("",Collections.nCopies(4-i1.length(),"0"))+i1; } builder.append(i1); } //P置换 String trim = builder.toString().trim(); return Swap(trim,P); } /** * 轮函数 * @param bin64 64位明文二进制 * @param keys 16组秘钥 * @return */ public String Wheel(String bin64,String[] keys){ bin64 = Swap(bin64,IP_table); // 初始置换 String leftbin = bin64.substring(0,32); String rightbin = bin64.substring(32); for (String key : keys) { String temp = rightbin; String f_function = f_function(rightbin, key); rightbin = xor(leftbin, f_function); leftbin = temp; } return Swap(rightbin+leftbin,IP_re_table); } /** * 生成16组秘钥 * @param binKey 初始秘钥的二进制 * @return keys[] */ public String[] generateKey(String binKey) { List<String> list = new ArrayList<>(); String leftbin, rightbin; binKey = Swap(binKey,PC_1); leftbin = binKey.substring(0,28); rightbin = binKey.substring(28,56); for (int i : SHIFT) { leftbin = leftbin.substring(i) + leftbin.substring(0,i); rightbin = rightbin.substring(i) + rightbin.substring(0,i); list.add(Swap(leftbin+rightbin,PC_2)); } return list.toArray(new String[list.size()]); } /** * 置换运算 * @param swap 待置换的字符串 * @param table 置换表 * @return 置换后的字符串 */ public static String Swap(String swap, int[] table) { char[] array = swap.toCharArray(); StringBuilder string = new StringBuilder(); for (int i = 0; i < table.length; i++) { string.append(array[table[i]-1]); } return string.toString().trim(); } public static final int[] 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}; public static final int[] 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}; public static final int[] SHIFT = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}; public static final int[][] S = { {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}, {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}, {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}, {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}, {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}, {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}, {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}, {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} }; public static final int[] 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}; public static final int[] 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}; public static final int[] 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}; public static final int[] IP_re_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}; }
Python 版
import re class DesUtil: """ 使用: des = DesUtil() print(des.encryption("加密的明文", "秘钥")) print(des.decryption("密文", "秘钥")) """ # ============== 进制转换==================== def bin2hex(self, bin): hextable = "0123456789ABCDEF" binlist = re.findall(r".{4}", bin) s = "" for i in binlist: s += hextable[int(i, 2)].lower() return s def hex2bin(self, hex): hex_table = "0123456789ABCDEF" s = "" for i in hex: k = str(bin(hex_table.find(i.upper()))[2:]) if len(k) < 4: k = (4 - len(k)) * "0" + k s += k return s def str2hex(self, string: str): return bytes.hex(string.encode('utf8')) def hex2str(self, hexstr): return bytes.fromhex(hexstr).decode().replace(b"\x00".decode(), "") # 去除空格 def encryption(self, msg: str, key: str): """ DES加密 :param msg: 明文消息 :param key: 明文秘钥 :return: 密文 """ binMsgList = re.findall(r".{64}", self.text2Bin(msg)) # 64bit文明二进制列表 k64 = re.findall(r".{64}", self.text2Bin(key))[0] # 秘钥二进制流 binKeyList = self.generateKeyTo16(k64) binaryCipher = "" for bitTo64 in binMsgList: binaryCipher += self.WheelFunction(bitTo64, binKeyList) return self.bin2hex(binaryCipher) def decryption(self, msg: str, key: str): """ DES解密 :param msg: 密文 :param key: 秘钥 :return: 明文 """ binMsgList = re.findall(r".{64}", self.hex2bin(msg)) # 64bit文明二进制列表 k64 = re.findall(r".{64}", self.text2Bin(key))[0] # 秘钥二进制流m binKeyList = self.generateKeyTo16(k64) binaryCipher = "" for bitTo64 in binMsgList: binaryCipher += self.WheelFunction(bitTo64, binKeyList[::-1]) return self.hex2str(self.bin2hex(binaryCipher)) def text2Bin(self, txt: str) -> str: """ 将明文 or 秘钥转换为二进制流 且%64=0 :param txt: 输入的明文或秘钥 :return: 运算的二进制流 """ txt = self.str2hex(txt) # 字符串转十六进制字符串 bintxt = self.hex2bin(txt) # 十六进制字符串 转 二进制字符串 k = len(bintxt) % 64 if k != 0: bintxt += "0" * (64 - k) return bintxt def generateKeyTo16(self, binKey: str): """ 生成16组秘钥 :param binKey: 初始秘钥 :return: 16组秘钥列表 """ keyList = [] # 置换选择PC-1 z1 = "" for i in self.PC_1: z1 += binKey[i - 1] # 28 bit key leftKey = z1[:28] rightKey = z1[28:] def leftShift(m, s): # 移位函数 s:移多少 return m[s:] + m[:s] for shift in self.SHIFT: leftKey = leftShift(leftKey, shift) rightKey = leftShift(rightKey, shift) # 置换选择PC-2 zh = leftKey + rightKey ans = "" for i in self.PC_2: ans += zh[i - 1] keyList.append(ans) # 添加秘钥 return keyList # XOR 异或操作 def msgXorKey(self, left, right) -> str: xor = "" for i in range(len(left)): xor += str(int(left[i]) ^ int(right[i])) return xor # f函数 def FFunction(self, binText: str, binKey: str) -> str: # 定义几个函数 # E表扩展 def e_Extend(bintxt) -> str: e = "" for i in self.E: e += bintxt[i - 1] return e # S盒处理 def S_Box(bintxt: str) -> str: ans = "" bit6list = re.findall(r".{6}", bintxt) flag = 0 for b in bit6list: k = int(b[0] + b[len(b) - 1], 2) # 获取 行 v = int(b[1:5], 2) # 获取列 sValue = bin(self.S[flag][k * 16 + v])[2:] # S盒查询的结果转2进制 if len(sValue) < 4: sValue = "0" * (4 - len(sValue)) + sValue flag += 1 ans += sValue return ans # P置换 def P_Swap(bintxt: str) -> str: ans = "" for i in self.P: ans += bintxt[i - 1] return ans # 开始处理 E表->异或->S盒->P置换 return P_Swap(S_Box(self.msgXorKey(e_Extend(binText), binKey))) # ip置换和逆置换 def ip_Swap(self, bit, reTable=False): n = "" if reTable is True: for i in self.IP_re_table: n += bit[i - 1] else: for i in self.IP_table: n += bit[i - 1] return n # 轮函数 def WheelFunction(self, bitTo64: str, keyList: list): # 初始置换(IP置换) n = self.ip_Swap(bitTo64) leftBit = n[:32] rightBit = n[32:] # 获取16轮秘钥 for rot in keyList: # 16轮加密 temp = rightBit k32 = self.FFunction(rightBit, rot) rightBit = self.msgXorKey(leftBit, k32) # 异或 leftBit = temp # 左右交换 swapValue = rightBit + leftBit # 逆 初始置换 Ciphertext = self.ip_Swap(swapValue, True) return Ciphertext 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] IP_re_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] 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] S = [ [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], [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], [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], [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], [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], [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], [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], [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], ] # key 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] 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] SHIFT = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1]
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。