手把手DES加密解密详解-Java,Python
DES介绍
DES(Data Encryption Standard)是迄今为止世界上最为广泛使用和流行的一种分组密码算法,它的分组长度为64比特,密钥长度为56比特,它是由美国IBM公司研制的,是早期的称作Lucifer密码的一种发展和修改。 每隔五年由美国国家保密局(NSA)作出评估,并重新批准它是否继续作为联邦加密标准。最后一次评估是在1994年1月,美国已决定1998年12月以后将不再使用DES。 DES是第一代公开的、完全说明细节的商业级现代算法,并被世界公认。
DES加密基于Feistel结构实现,其轮结构如下图所示:
DES的加密和解密详解
DES的加密过程:
明文二进制的加密:
将明文数据转为二进制
,再将二进制数据分组
,每组64位,组元素不满64 则在后面补0,满64为止。再将每一组64bit数据进行初始置换
在进行轮函数。
轮函数中将右边32bit
进行F运算
,然后与左边32bit进行异或
,得到的结果作为下一轮右边
将刚开始的右边作为下一轮左边
,依次循环16次
,最后进行逆初始置换
,即可得到密文二进制
。
秘钥的产生:
将明文秘钥转换为二进制 ,取56bit
为一组,不满56bit 补0
,然后进行秘钥生成,将得到的秘钥组
,分别拿去参与每一轮的F运算
,即第一组秘钥对应第一轮F函数
,生成的每组秘钥长度为:48bit
解密过程:
加密和解密一样,不同的点是,最后一组秘钥对应第一轮F函数
,即把秘钥组反过来
而已。
看完大致流程,我们来看看具体的代码实现,有Java版和Python版,为了方便就以Python版来讲解,文章末尾会附上Java和Python的全部代码。
DES加密
实现的过程我们根据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_stringdef 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" + ks += kreturn s# 二进制转十六进制def bin2hex(self, bin):changed_str = ''while len(bin) > 0:temp = int(bin[:4], 2)changed_str += '%0x' % tempbin = bin[4:]return changed_strdef 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) % 64if k != 0:bintxt += "0" * (64 - k)return bintxt
2.秘钥组生成
生成16轮的秘钥组原理图
代码中的所有置换表
都在文末
的最终代码里面
生成秘钥
:接受一个二进制秘钥流
64bit,进行PC1置换
,取前56位,然后一分为二,每个28bit,然后进行循环移位
,就是根据移位表
,数字2:表示把二进制串左边2个接到右边后面,移位完将
C0和D0拼接在一起,进行PC2置换
,得到子秘钥
,然后再将上次循环移位的结果继续循环移位,依次生成完16组
def generateKeyTo16(self, binKey: str):"""生成16组秘钥:param binKey: 初始秘钥:return: 16组秘钥列表"""keyList = []# 置换选择PC-1z1 = ""for i in self.PC_1:z1 += binKey[i - 1]# 28 bit keyleftKey = 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-2zh = leftKey + rightKeyans = ""for i in self.PC_2:ans += zh[i - 1]keyList.append(ans) # 添加秘钥return keyList
3.F函数的实现
函数的输入分析: 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 = 0for 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)) + sValueflag += 1ans += sValuereturn 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)))
4 轮函数实现
参数
: 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 = rightBitk32 = self.FFunction(rightBit, rot)rightBit = self.msgXorKey(leftBit, k32) # 异或leftBit = temp# 左右交换swapValue = rightBit + leftBit# 逆 初始置换Ciphertext = self.ip_Swap(swapValue, True)return Ciphertext
5.加密函数
整合上面实现加密
参数
: 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进制
6.解密函数
接收参数
: 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] # 秘钥二进制流mbinKeyList = self.generateKeyTo16(k64)binaryCipher = ""for bitTo64 in binMsgList:binaryCipher += self.WheelFunction(bitTo64, binKeyList[::-1]) # [::-1]将列表反转,即秘钥组反过来return self.hex2str(self.bin2hex(binaryCipher))
7.测试
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 reclass 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 sdef 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" + ks += kreturn sdef 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] # 秘钥二进制流mbinKeyList = 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) % 64if k != 0:bintxt += "0" * (64 - k)return bintxtdef generateKeyTo16(self, binKey: str):"""生成16组秘钥:param binKey: 初始秘钥:return: 16组秘钥列表"""keyList = []# 置换选择PC-1z1 = ""for i in self.PC_1:z1 += binKey[i - 1]# 28 bit keyleftKey = 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-2zh = leftKey + rightKeyans = ""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 = 0for 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)) + sValueflag += 1ans += sValuereturn 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 = rightBitk32 = self.FFunction(rightBit, rot)rightBit = self.msgXorKey(leftBit, k32) # 异或leftBit = temp# 左右交换swapValue = rightBit + leftBit# 逆 初始置换Ciphertext = self.ip_Swap(swapValue, True)return CiphertextIP_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],]# keyPC_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]
手把手DES加密解密详解-Java,Python相关推荐
- C#高级--加密解密详解
C#高级–加密解密详解 零.文章目录 一.名词介绍 1.加密 是以某种特殊的算法改变原有的信息数据,以另外一种形式呈现,这里有几个名词:加密之前的信息数据可以理解为原数据,原文:加密之后的数据信息可以 ...
- PHP 基础篇 - PHP 中 DES 加解密详解
2019独角兽企业重金招聘Python工程师标准>>> 一.简介 DES 是对称性加密里面常见一种,全称为 Data Encryption Standard,即数据加密标准,是一种使 ...
- java ios des加密解密_IOS、java支持DES加密
转载请注明博客地址:http://blog.csdn.net/mengxiangyue/article/details/40015727 近期在考虑数据加密方面的需求,所以对数据加密简单的看了一下,当 ...
- Go-ecc加密解密详解与代码
目录 Ecc概述 历史 密钥对生成 加密算法 解密算法 小结 Ecc的Go实现 crypto/ecdsa 包 crypto/elliptic 包 crypto/rand 包 crypto/x509包 ...
- php中文加密解密,php加密解密详解
不知道大家对于php加密解密有多少了解,本文主要和大家分享php加密解密相关知识,希望能帮助到大家. 一 对称加密 1.mycyrpt的对称加密:/** * @param $key //数据加密密钥 ...
- php 易语言md5加密解密,详解易语言调用js实现md5加密方法
易语言调用js需要用到拓展组件的脚本组件, 在窗口创建完毕的事件里给脚本组件初始化设置下脚本组件的语言属性,在这里以JScript为例: 脚本组件执行脚本的简单方法是: 脚本组件1.执行 () 然 ...
- crypto-js 前端DES加密/解密、生成秘钥 详解
DES概述 DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并授权在非 ...
- python des解密_python实现DES加密解密方法实例详解
本文实例讲述了python实现DES加密解密方法.分享给大家供大家参考.具体分析如下: 实现功能:加密中文等字符串 密钥与明文可以不等长 这里只贴代码,加密过程可以自己百度,此处python代码没有优 ...
- python des加密文件_Python DES加密解密方法 pyDes库 兼容中文
单纯记录一下Python中DES加密解密的使用方式直接看代码: 依赖pyDes库安装> pip install pyDes 约定秘钥 python和java 加密和解密联调,兼容中文字符串 Py ...
- Python爬虫JS解密详解,学会直接破解80%的网站(一)!!!
文章目录 1.网页查看 2.有道翻译简单实现源码 3.JS解密(详解) 4.python实现JS解密后的完整代码 4.1.实现效果 5.JS解密后完整代码升级版 5.1.实现效果 CSDN独家福利降临 ...
最新文章
- 数据分析必备:掌握这个R语言基础包1%的功能让你事半功倍!(附代码)
- Python 程序员最常犯的十个错误
- Stanford UFLDL教程 主成分分析(PCA)
- 跑步碰撞大数据,走进悦跑圈的数据“大观园”
- ATT汇编leave指令
- HDFS常用的Api
- python之csv模块(part1)--写入csv文件
- java学习(1):学生管理系统1
- android 横向stepview,一款由Recyclerview打造的步骤控件,支持横向和纵向
- C++自学08:类型推断(auto/typeid)
- DB2 常用的SQL
- 网页上的内容无法复制和下载?一行代码教你解决
- Apache Tomcat 文件包含漏洞(CNVD-2020-10487,对应 CVE-2020-1938)
- 在电脑上收听广播——龙卷风网络收音机试用
- 京东 PC 首页 2019 改版前端总结
- 物理服务器怎么装linux,新手如何在物理机上部署红帽linux系统
- 当沙拉与火锅狭路相逢,长沙人的“肥胖焦虑“有何新解法?
- 对于Linux内核tty设备的一点理解
- py sel采集部署linux报错
- 匀速运动小车卡尔曼_卡尔曼滤波(Kalman Filter)
热门文章
- 从 iTunes 和 Finder 断开 iPhone 连接的三种方法
- 从零开始SpringCloud Alibaba实战(47)——阿里开发手册泰山版学习笔记一 命名风格
- android动态相机权限
- ThinkPHP一键检测ThinkPHP漏洞,漏洞检测工具
- Html和css算是编程语言吗,不被承认的编程语言
- 还在用百度找资源?试试这3个顶级资源搜索网站,没有找不到的!
- Vue入门项目:学生管理系统之班级管理 【含源码】
- C++入门基础之计算使用某快递公司运输货物的运费
- mac怎么设置锁屏壁纸,锁屏壁纸和屏幕壁纸不同
- 分数化简通分:最大公约数与最小公倍数