5.1 DES加密解密 -python 实现

引例:DES 加密

5.1 此题给出了一轮DES加密的例子,假设明文和密文都是:
00000001 00100011 01000101 01100111 10001001 10101011 11001101 11101111

5.1 DES加密解密 -python 实现

解题思路

5.1 DES加密解密 -python 实现
5.1 DES加密解密 -python 实现

答案见如下代码结果

python 实现

#DES的Python实现--若初·知乎
import binascii
K=[0,0,0,0,
	0,0,0,0,
	0,0,0,0,
	0,0,0,0]

def str_to_hex(string):	#Unicode字符串转16进制字符串
	hex_string=''
	for i in string:
		hex_string=hex_string + '%02x'%ord(i)
	return hex_string

def hex_to_bin(string):	#16进制字符串转2进制字符串
	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 string:
		i=int(i,16)
		bin_string=bin_string + hex_to_bin_table[i]
	return bin_string
	
def bin_to_hex(string):	#2进制字符串转16进制字符串
	changed_str=''
	while(len(string)>0):
		temp=string[:4]
		temp=int(temp, 2)
		changed_str=changed_str + '%0x'%temp
		string=string[4:]
	return changed_str
	
def permutation1(key):	#置换选择1
	pc1=(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)
	changed_key=''
	for i in range(56):
		changed_key = changed_key + key[pc1[i]-1]
	return changed_key
	
def permutation2(C, D):	#置换选择2
	pc2= (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)
	key = C + D
	changed_key=''
	for i in range(48):
		changed_key = changed_key + key[pc2[i]-1]
	return changed_key
	
def ROL(string, i):		#循环左移
	changed_string=''
	if(i==1):
		changed_string=string[1:] + string[:1]
	if(i==2):
		changed_string=string[2:] + string[:2]
	return changed_string
	
def permutation_IP(code):	#置换选择IP
	ip= (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)
	changed_code=''
	for i in range(64):
		changed_code+=code[ip[i]-1]
	return changed_code
	
def permutation_IP_1(code):	#置换选择IP逆
    ip_1=(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)
    changed_code=''
    for i in range(64):
        changed_code+=code[ip_1[i]-1]
    return changed_code
	
def E(code):	#选择运算E
    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)
    return_list=''
    for i in range(48):
	    return_list=return_list + code[e[i]-1]
    return return_list
	
def S(code):	#选择运算S
    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]]]
		
    return_list=''
    for i in range(8):
        row=int(str(code[i*6])+str(code[i*6+5]),2)#选择行
        raw=int(str(code[i*6+1])+str(code[i*6+2])+str(code[i*6+3])+str(code[i*6+4]),2)#选择列
        return_list=return_list + '%0x'%s[i][row][raw]
		#选择一个数,并转换为16进制数
    return_list=hex_to_bin(return_list)
	#整个转换为2进制字符串
    return return_list
	
def permutation_P(code):#置换选择P
	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)
	return_list=''
	for i in range(32):
		return_list=return_list + code[p[i]-1]
	return return_list
	
def f(A,i):		#加密函数f
	global K
	result=E(A)
	if i==0:
		print('E(R0)',result)
	result=int(result,2)
	result=result ^ int(K[i],2)
	result='%0x'%result
	result=hex_to_bin(result)
	result=(48-len(result))*'0' + result#增长到48位
	if i==0:
	    print("A: ",result)
	result=S(result)
	if i==0:
	    print("B: ",result)
	result=permutation_P(result)
	if i==0:
	    print("P(B): ",result)
	return result

def gen_K(key):
	global K
	ROL_table=(1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1)
	key=permutation1(key)
	C=[]
	D=[]
	C.append(key[:28])
	D.append(key[28:])
	for i in range(16):
		C.append(ROL(C[i],ROL_table[i]))
		D.append(ROL(D[i],ROL_table[i]))
		K[i]=permutation2(C[i+1],D[i+1])
		
def DES_encrypt(plaintext):#总体加密结构
	result=''
	result=permutation_IP(plaintext)
	L=[]
	R=[]
	L.append(result[0:32])
	R.append(result[32:64])
	for i in range(16):
		L.append(R[i])
		temp=hex_to_bin('%0x'%(int(f(R[i],i),2) ^ int(L[i],2)))
		temp=(32-len(temp))*'0' + temp#增加到32位,前面全用0填满
		R.append(temp)
		if i==0:
			print('L: ',L)
			print('R: ',R)
			#print('E(R0): ',f(R[i],i))
	result=R[16]+L[16]
	result=permutation_IP_1(result)
	result=bin_to_hex(result)#16进制ASCII码
	#result=str.encode(result)
	#print(binascii.a2b_hex(result))
	print('result in hex:' + result)



choose=input('choose 1 for encode, 2 for decode: ')
if choose=='1':				#encode
							#debug用
	key_64bits='0000000'+'0010001'+'0100010'+'0110011'+'1000100'+'1010101'+'1100110'+'1110111'
	plaintext ='00000001'+'00100011'+'01000101'+'01100111'+'10001001'+'10101011'+'11001101'+'11101111'
	
	'''
	#key=input('input the key(56bits, 7words): ')#密钥
	while(len(key)!=7):
		key=input('input the key(56bits, 7words): ')
	plaintext=input('input the plaintext: ')#明文
	#print(len(hex_to_bin(str_to_hex(plaintext))))
	key_64bits=''
	for i in key:#密钥转成2进制字符串
		key_64bits=key_64bits + hex_to_bin('%02x'%ord(i))
	'''
	key_64bits=key_64bits[0:7] + '0' + key_64bits[7:14] + '0' + key_64bits[14:21] + '0' + key_64bits[21:28] + '0' + key_64bits[28:35] + '0' + key_64bits[35:42] + '0' + key_64bits[42:49] + '0' + key_64bits[49:56] + '0'	
	#56位密钥扩展成64位
	#print('length of the key:' + str(len(key_64bits)))
	#plaintext=str_to_hex(plaintext)
	#plaintext=hex_to_bin(plaintext)
	#明文转2进制字符串
	
	gen_K(key_64bits)
	print('K:  ' + str(K))
	while(len(plaintext)>=64):
		plaintext_64bits=plaintext[:64]
		DES_encrypt(plaintext_64bits)
		plaintext=plaintext[64:]
	if(len(plaintext)!=0):
		i=64-len(plaintext)
		plaintext_64bits=plaintext + i*'0'
		DES_encrypt(plaintext_64bits)
		
		

if choose=='2':				#decode
	key='1234567'
	#key=input('input the key(56bits, 7words): ')#密钥
	while(len(key)!=7):
		key=input('input the key(56bits, 7words): ')
	ciphertext=input('input the ciphertext: ')#密文

	key_64bits=''
	for i in key:#密钥转成2进制字符串
		key_64bits=key_64bits + hex_to_bin('%02x'%ord(i))
	key_64bits=key_64bits[0:7] + '0' + key_64bits[7:14] + '0' + key_64bits[14:21] + '0' + key_64bits[21:28] + '0' + key_64bits[28:35] + '0' + key_64bits[35:42] + '0' + key_64bits[42:49] + '0' + key_64bits[49:56] + '0'	
	#56位密钥扩展成64位
	#print('length of the key:' + str(len(key_64bits)))
	ciphertext = str_to_hex(ciphertext)
	ciphertext = hex_to_bin(ciphertext)
	gen_K(key_64bits)
	K.reverse()
	while(len(ciphertext)>=64):
		ciphertext_64bits=ciphertext[:64]
		DES_encrypt(ciphertext_64bits)
		ciphertext=ciphertext[64:]
	if(len(ciphertext)!=0):
		i=64-len(ciphertext)
		ciphertext_64bits=ciphertext + i*'0'
		DES_encrypt(ciphertext_64bits)



# choose 1 for encode, 2 for decode: 1 
# K:  ['000010110000001001100111100110110100100110100101', '011010011010011001011001001001010110101000100110', '010001011101010010001010101101000010100011010010', '011100101000100111010010101001011000001001010111', '001111001110100000000011000101111010011011000010', '001000110010010100011110001111001000010101000101', '011011000000010010010101000010101110010011000110', '010101111000100000111000011011001110010110000001', '110000001100100111101001001001101011100000111001', '100100011110001100000111011000110001110101110010', '001000010001111110000011000011011000100100111010', '011100010011000011100101010001010101110001010100', '100100011100010011010000010010011000000011111100', '010101000100001110110110100000011101110010001101', '101101101001000100000101000010100001011010110101', '110010100011110100000011101110000111000000110010']
# E(R0) 011110100001010101010101011110100001010101010101
# A:  011100010001011100110010111000010101110011110000
# B:  00001100001000010110110101010000
# P(B):  10010010000111000010000010011100
# L:  ['11001100000000001100110011111111', '11110000101010101111000010101010']
# R:  ['11110000101010101111000010101010', '01011110000111001110110001100011']
# result in hex:56cc09e7cfdc4cef

上一篇:容器化RDS|计算存储分离 or 本地存储?


下一篇:python批量移动文件并进行MD5去重