import ctypes from functools import reduce from hashlib import md5 """ 标准des,由于不知道部分key的utf-8, 通过捕获的key还原标准des调用 """ def MD5(strs): m = md5() m.update(strs.encode("utf-8")) return m.hexdigest() def hex_2_str(v: int): v = v & 0xffffffff # 将结果转换为32位有符号整数 tmp = str(hex(v))[2:] return "0" + tmp if len(tmp) % 2 > 0 else tmp def logical_left_shift(n, bits): """ 有符号左移 :param n: :param bits: :return: """ return ctypes.c_int(n << bits).value def logical_right_shift(n, bits): """ 无符号右移 :param n: :param bits: :return: """ return (n % 0x100000000) >> bits def get_s_box(i, j): """ sbox :param i: :param j: :return: """ s_box1 = [-2146402272, -2147450880, 32768, 1081376, 1048576, 32, -2146435040, -2147450848, -2147483616, -2146402272, -2146402304, -2147483648, -2147450880, 1048576, 32, -2146435040, 1081344, 1048608, -2147450848, 0, -2147483648, 32768, 1081376, -2146435072, 1048608, -2147483616, 0, 1081344, 32800, -2146402304, -2146435072, 32800, 0, 1081376, -2146435040, 1048576, -2147450848, -2146435072, -2146402304, 32768, -2146435072, -2147450880, 32, -2146402272, 1081376, 32, 32768, -2147483648, 32800, -2146402304, 1048576, -2147483616, 1048608, -2147450848, -2147483616, 1048608, 1081344, 0, -2147450880, 32800, -2147483648, -2146435040, -2146402272, 1081344] s_box2 = [8396801, 8321, 8321, 128, 8396928, 8388737, 8388609, 8193, 0, 8396800, 8396800, 8396929, 129, 0, 8388736, 8388609, 1, 8192, 8388608, 8396801, 128, 8388608, 8193, 8320, 8388737, 1, 8320, 8388736, 8192, 8396928, 8396929, 129, 8388736, 8388609, 8396800, 8396929, 129, 0, 0, 8396800, 8320, 8388736, 8388737, 1, 8396801, 8321, 8321, 128, 8396929, 129, 1, 8192, 8388609, 8193, 8396928, 8388737, 8193, 8320, 8388608, 8396801, 128, 8388608, 8192, 8396928] s_box3 = [536870928, 541065216, 16384, 541081616, 541065216, 16, 541081616, 4194304, 536887296, 4210704, 4194304, 536870928, 4194320, 536887296, 536870912, 16400, 0, 4194320, 536887312, 16384, 4210688, 536887312, 16, 541065232, 541065232, 0, 4210704, 541081600, 16400, 4210688, 541081600, 536870912, 536887296, 16, 541065232, 4210688, 541081616, 4194304, 16400, 536870928, 4194304, 536887296, 536870912, 16400, 536870928, 541081616, 4210688, 541065216, 4210704, 541081600, 0, 541065232, 16, 16384, 541065216, 4210704, 16384, 4194320, 536887312, 0, 541081600, 536870912, 4194320, 536887312] s_box4 = [268439616, 4096, 262144, 268701760, 268435456, 268439616, 64, 268435456, 262208, 268697600, 268701760, 266240, 268701696, 266304, 4096, 64, 268697600, 268435520, 268439552, 4160, 266240, 262208, 268697664, 268701696, 4160, 0, 0, 268697664, 268435520, 268439552, 266304, 262144, 266304, 262144, 268701696, 4096, 64, 268697664, 4096, 266304, 268439552, 64, 268435520, 268697600, 268697664, 268435456, 262144, 268439616, 0, 268701760, 262208, 268435520, 268697600, 268439552, 268439616, 0, 268701760, 266240, 266240, 4160, 4160, 262208, 268435456, 268701696] s_box5 = [16843776, 0, 65536, 16843780, 16842756, 66564, 4, 65536, 1024, 16843776, 16843780, 1024, 16778244, 16842756, 16777216, 4, 1028, 16778240, 16778240, 66560, 66560, 16842752, 16842752, 16778244, 65540, 16777220, 16777220, 65540, 0, 1028, 66564, 16777216, 65536, 16843780, 4, 16842752, 16843776, 16777216, 16777216, 1024, 16842756, 65536, 66560, 16777220, 1024, 4, 16778244, 66564, 16843780, 65540, 16842752, 16778244, 16777220, 1028, 66564, 16843776, 1028, 16778240, 16778240, 0, 65540, 66560, 0, 16842756] s_box6 = [520, 134349312, 0, 134348808, 134218240, 0, 131592, 134218240, 131080, 134217736, 134217736, 131072, 134349320, 131080, 134348800, 520, 134217728, 8, 134349312, 512, 131584, 134348800, 134348808, 131592, 134218248, 131584, 131072, 134218248, 8, 134349320, 512, 134217728, 134349312, 134217728, 131080, 520, 131072, 134349312, 134218240, 0, 512, 131080, 134349320, 134218240, 134217736, 512, 0, 134348808, 134218248, 131072, 134217728, 134349320, 8, 131592, 131584, 134217736, 134348800, 134218248, 520, 134348800, 131592, 8, 134348808, 131584] s_box7 = [256, 34078976, 34078720, 1107296512, 524288, 256, 1073741824, 34078720, 1074266368, 524288, 33554688, 1074266368, 1107296512, 1107820544, 524544, 1073741824, 33554432, 1074266112, 1074266112, 0, 1073742080, 1107820800, 1107820800, 33554688, 1107820544, 1073742080, 0, 1107296256, 34078976, 33554432, 1107296256, 524544, 524288, 1107296512, 256, 33554432, 1073741824, 34078720, 1107296512, 1074266368, 33554688, 1073741824, 1107820544, 34078976, 1074266368, 256, 33554432, 1107820544, 1107820800, 524544, 1107296256, 1107820800, 34078720, 0, 1074266112, 1107296256, 524544, 33554688, 1073742080, 524288, 0, 1074266112, 34078976, 1073742080] s_box8 = [2097152, 69206018, 67110914, 0, 2048, 67110914, 2099202, 69208064, 69208066, 2097152, 0, 67108866, 2, 67108864, 69206018, 2050, 67110912, 2099202, 2097154, 67110912, 67108866, 69206016, 69208064, 2097154, 69206016, 2048, 2050, 69208066, 2099200, 2, 67108864, 2099200, 67108864, 2099200, 2097152, 67110914, 67110914, 69206018, 69206018, 2, 2097154, 67108864, 67110912, 2097152, 69208064, 2050, 2099202, 69208064, 2050, 67108866, 69208066, 69206016, 2099200, 0, 2, 69208066, 0, 2099202, 69206016, 2048, 67108866, 67110912, 2048, 2097154] s_box = [s_box1, s_box2, s_box3, s_box4, s_box5, s_box6, s_box7, s_box8] return s_box[i][j] def alg_main(key, _plaintext_left, _plaintext_right): """ 3.轮密钥和明文块计算 + 计算后的明文还原 :param key: :param _plaintext_left: :param _plaintext_right: :return: 处理后的16进制字符串、处理后的字符串 """ for i in range(0, len(key), 2): _key = key[i] # 轮密钥 _key2 = key[i+1] tmp = _plaintext_right ^ _key tmp1 = (logical_right_shift(_plaintext_right, 4) | logical_left_shift(_plaintext_right, 28)) ^ _key2 mid = get_s_box(0, logical_right_shift(tmp, 24) & 63) | get_s_box(1, logical_right_shift(tmp, 16) & 63) | \ get_s_box(2, logical_right_shift(tmp, 8) & 63) | get_s_box(3, tmp & 63) | \ get_s_box(4, logical_right_shift(tmp1, 24) & 63) | get_s_box(5, logical_right_shift(tmp1, 16) & 63) | \ get_s_box(6, logical_right_shift(tmp1, 8) & 63) | get_s_box(7, tmp1 & 63) tmp2 = _plaintext_left ^ mid _plaintext_left = _plaintext_right # 左边继承右边 _plaintext_right = tmp2 # print(f"第{i}轮 ; ", _plaintext_left, _plaintext_right, mid, _key, _key2, tmp, tmp1) # break t1 = logical_right_shift(_plaintext_right, 1) | logical_left_shift(_plaintext_right, 31) t2 = logical_right_shift(_plaintext_left, 1) | logical_left_shift(_plaintext_left, 31) t3 = (logical_right_shift(t1, 1) ^ t2) & 1431655765 t4 = t2 ^ t3 t5 = t1 ^ logical_left_shift(t3, 1) t6 = (logical_right_shift(t4, 8) ^ t5) & 16711935 t7 = t5 ^ t6 t8 = t4 ^ logical_left_shift(t6, 8) t9 = (logical_right_shift(t8, 2) ^ t7) & 858993459 t10 = t7 ^ t9 t11 = logical_left_shift(t9, 2) ^ t8 t12 = (logical_right_shift(t10, 16) ^ t11) & 65535 t13 = t11 ^ t12 t14 = t10 ^ logical_left_shift(t12, 16) t15 = (logical_right_shift(t14, 4) ^ t13) & 252645135 t16 = t15 ^ t13 t17 = t14 ^ logical_left_shift(t15, 4) b1 = logical_right_shift(t17, 24) b2 = logical_right_shift(t17, 16) & 255 b3 = logical_right_shift(t17, 8) & 255 b4 = t17 & 255 b5 = logical_right_shift(t16, 24) b6 = logical_right_shift(t16, 16) & 255 b7 = logical_right_shift(t16, 8) & 255 b8 = t16 & 255 segment_list = [b1, b2, b3, b4, b5, b6, b7, b8] segment = "".join([chr(s) for s in segment_list]) segment_hex = "".join([hex_2_str(s) for s in segment_list]) # print(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17) # print(segment) # print(segment_hex) return segment_hex, segment def deal_array2(array1_res, array2_res): """ 2. 明文块预处理(和alg_main中的后半部分是可逆的) :param array1_res: :param array2_res: :return: """ tmp = (logical_right_shift(array1_res, 4) ^ array2_res) & 252645135 tmp1 = array2_res ^ tmp tmp1_ = array1_res ^ logical_left_shift(tmp, 4) tmp2 = (logical_right_shift(tmp1_, 16) ^ tmp1) & 65535 tmp2_ = tmp1 ^ tmp2 tmp3 = logical_right_shift(tmp2_, 2) tmp4 = tmp1_ ^ logical_left_shift(tmp2, 16) tmp5 = (tmp3 ^ tmp4) & 858993459 tmp5_ = logical_left_shift(tmp5, 2) tmp6 = tmp5 ^ tmp4 tmp7 = (logical_right_shift(tmp2_ ^ tmp5_, 8) ^ tmp6) & 16711935 tmp7_ = tmp6 ^ tmp7 tmp8 = logical_right_shift(tmp7_, 1) tmp9 = tmp2_ ^ tmp5_ ^ logical_left_shift(tmp7, 8) tmp10 = (tmp8 ^ tmp9) & 1431655765 tmp10_ = tmp9 ^ tmp10 tmp11 = tmp7_ ^ logical_left_shift(tmp10, 1) tmp12 = logical_left_shift(tmp11, 1) | logical_right_shift(tmp11, 31) tmp13 = logical_left_shift(tmp10_, 1) | logical_right_shift(tmp10_, 31) return tmp12, tmp13 def deal_array(array): """ 1.简单处理块 :param array: :return: """ for i in range(len(array)): array[i] = array[i] << (24 - 8 * i) res = reduce(lambda x, y: x | y, array) return res def des_encrypt(key, plain_text): """ des加密入口 :param key: list :param plain_text: list :return: """ array1_hex = [] array1_string = [] for m in range(0, len(plain_text), 8): left_list, right_list = plain_text[m:m + 4], plain_text[m + 4:m + 8] left, right = deal_array2(deal_array(left_list), deal_array(right_list)) segment_hex, segment = alg_main(key, left, right) array1_hex.append(segment_hex) array1_string.append(segment) _hex = "".join(array1_hex) _string = "".join(array1_string) return _hex, _string