python实现DES加密解密方法实例详解


Posted in Python onJune 30, 2015

本文实例讲述了python实现DES加密解密方法。分享给大家供大家参考。具体分析如下:

实现功能:加密中文等字符串
密钥与明文可以不等长
这里只贴代码,加密过程可以自己百度,此处python代码没有优化

1. desstruct.py DES加密中要使用的结构体

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)
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)
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]]]
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, 33, 15,
  7, 62, 54, 46, 38, 30, 22,
  14, 6, 61, 53, 45, 37, 29,
  21, 13, 5, 28, 20, 12, 4);
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)
d = ( 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1)

2. des.py 加密文件

#_*_ coding:utf-8 _*_
#!/usr/bin/env python
#Filename:des.py
from desstruct import *
import re
__all__=['desencode']
class DES():
 '''des 加密'''
 def __init__(self):
  pass
 #加密
 def code(self,from_code,key,code_len,key_len):
  output=""
  trun_len=0
  #将密文和密钥转换为二进制
  code_string=self._functionCharToA(from_code,code_len)
  code_key=self._functionCharToA(key,key_len)
  #如果密钥长度不是16的整数倍则以增加0的方式变为16的整数倍
  if code_len%16!=0:
   real_len=(code_len/16)*16+16
  else:
   real_len=code_len
  if key_len%16!=0:
   key_len=(key_len/16)*16+16
  key_len*=4
  #每个16进制占4位
  trun_len=4*real_len
  #对每64位进行一次加密
  for i in range(0,trun_len,64):
   run_code=code_string[i:i+64]
   l=i%key_len
   run_key=code_key[l:l+64]
   #64位明文、密钥初始置换
   run_code= self._codefirstchange(run_code)
   run_key= self._keyfirstchange(run_key)
   #16次迭代
   for j in range(16):
    #取出明文左右32位
    code_r=run_code[32:64]
    code_l=run_code[0:32]
    #64左右交换
    run_code=code_r
    #右边32位扩展置换
    code_r= self._functionE(code_r)
    #获取本轮子密钥
    key_l=run_key[0:28]
    key_r=run_key[28:56]
    key_l=key_l[d[j]:28]+key_l[0:d[j]]
    key_r=key_r[d[j]:28]+key_r[0:d[j]]
    run_key=key_l+key_r
    key_y= self._functionKeySecondChange(run_key)
    #异或
    code_r= self._codeyihuo(code_r,key_y)
    #S盒代替/选择
    code_r= self._functionS(code_r)
    #P转换
    code_r= self._functionP(code_r)
    #异或
    code_r= self._codeyihuo(code_l,code_r)
    run_code+=code_r
   #32互换
   code_r=run_code[32:64]
   code_l=run_code[0:32]
   run_code=code_r+code_l
   #将二进制转换为16进制、逆初始置换
   output+=self._functionCodeChange(run_code)
  return output
 #异或 
 def _codeyihuo(self,code,key):
  code_len=len(key)
  return_list=''
  for i in range(code_len):
   if code[i]==key[i]:
    return_list+='0'
   else:
    return_list+='1'
  return return_list
 #密文或明文初始置换
 def _codefirstchange(self,code):
  changed_code=''
  for i in range(64):
   changed_code+=code[ip[i]-1]
  return changed_code
 #密钥初始置换
 def _keyfirstchange (self,key):
  changed_key=''
  for i in range(56):
   changed_key+=key[pc1[i]-1]
  return changed_key
 #逆初始置换
 def _functionCodeChange(self, code):
  lens=len(code)/4
  return_list=''
  for i in range(lens):
   list=''
   for j in range(4):
    list+=code[ip_1[i*4+j]-1]
   return_list+="%x" %int(list,2)
  return return_list
 #扩展置换 
 def _functionE(self,code):
  return_list=''
  for i in range(48):
   return_list+=code[e[i]-1]
  return return_list  
 #置换P  
 def _functionP(self,code):
  return_list=''
  for i in range(32):
   return_list+=code[p[i]-1]
  return return_list
 #S盒代替选择置换
 def _functionS(self, key):
  return_list=''
  for i in range(8):
   row=int( str(key[i*6])+str(key[i*6+5]),2)
   raw=int(str( key[i*6+1])+str(key[i*6+2])+str(key[i*6+3])+str(key[i*6+4]),2)
   return_list+=self._functionTos(s[i][row][raw],4)
  return return_list
 #密钥置换选择2
 def _functionKeySecondChange(self,key):
  return_list=''
  for i in range(48):
   return_list+=key[pc2[i]-1]
  return return_list
 #将十六进制转换为二进制字符串
 def _functionCharToA(self,code,lens):
  return_code=''
  lens=lens%16
  for key in code:
   code_ord=int(key,16)
   return_code+=self._functionTos(code_ord,4)  
  if lens!=0:
   return_code+='0'*(16-lens)*4
  return return_code
 #二进制转换
 def _functionTos(self,o,lens):
  return_code=''
  for i in range(lens):
   return_code=str(o>>i &1)+return_code
  return return_code
#将unicode字符转换为16进制
def tohex(string):
 return_string=''
 for i in string:
  return_string+="%02x"%ord(i)
 return return_string
def tounicode(string):
 return_string=''
 string_len=len(string)
 for i in range(0,string_len,2):
  return_string+=chr(int(string[i:i+2],16))
 return return_string
#入口函数
def desencode(from_code,key):
 #转换为16进制
 from_code=tohex(from_code)
 key=tohex(key)
 des=DES()
 key_len=len(key)
 string_len=len(from_code)  
 if string_len<1 or key_len<1:
  print 'error input'
  return False
 key_code= des.code(from_code,key,string_len,key_len)
 return key_code
#测试
if __name__ == '__main__':
 print desencode('我是12345678刘就是我abcdwfd','0f1571c947刘')
#返回密文为: 84148584371a6a1fe99e1da0ce1e34649b88ed15098e8aa4b8eb0bf24885c658

3. 解密文件

#_*_coding:utf-8_*_
#!/usr/bin/env python
#Filename:des.py
from desstruct import *
import re
__all__=['desdecode']
class DES():
 '''解密函数,DES加密与解密的方法相差不大
  只是在解密的时候所用的子密钥与加密的子密钥相反
 '''
 def __init__(self):
  pass
 def decode(self,string,key,key_len,string_len):
  output=""
  trun_len=0
  num=0
  #将密文转换为二进制
  code_string=self._functionCharToA(string,string_len)
  #获取字密钥
  code_key=self._getkey(key,key_len)
  #如果密钥长度不是16的整数倍则以增加0的方式变为16的整数倍
  real_len=(key_len/16)+1 if key_len%16!=0 else key_len/16
  trun_len=string_len*4
  #对每64位进行一次加密
  for i in range(0,trun_len,64):
   run_code=code_string[i:i+64]
   run_key=code_key[num%real_len]
   #64位明文初始置换
   run_code= self._codefirstchange(run_code)
   #16次迭代
   for j in range(16):
    code_r=run_code[32:64]
    code_l=run_code[0:32]
    #64左右交换 
    run_code=code_r
    #右边32位扩展置换
    code_r= self._functionE(code_r)
    #获取本轮子密钥
    key_y=run_key[15-j]
    #异或
    code_r= self._codeyihuo(code_r,key_y)
    #S盒代替/选择
    code_r= self._functionS(code_r)
    #P转换
    code_r= self._functionP(code_r)
    #异或
    code_r= self._codeyihuo(code_l,code_r)
    run_code+=code_r
   num+=1
   #32互换
   code_r=run_code[32:64]
   code_l=run_code[0:32]
   run_code=code_r+code_l
   #将二进制转换为16进制、逆初始置换
   output+=self._functionCodeChange(run_code)
  return output
 #获取子密钥
 def _getkey(self,key,key_len):
  #将密钥转换为二进制
  code_key=self._functionCharToA(key,key_len)
  a=['']*16
  real_len=(key_len/16)*16+16 if key_len%16!=0 else key_len
  b=['']*(real_len/16)
  for i in range(real_len/16):
   b[i]=a[:]
  num=0
  trun_len=4*key_len
  for i in range(0,trun_len,64):
   run_key=code_key[i:i+64]
   run_key= self._keyfirstchange(run_key)
   for j in range(16):
    key_l=run_key[0:28]
    key_r=run_key[28:56]
    key_l=key_l[d[j]:28]+key_l[0:d[j]]
    key_r=key_r[d[j]:28]+key_r[0:d[j]]
    run_key=key_l+key_r
    key_y= self._functionKeySecondChange(run_key)
    b[num][j]=key_y[:]
   num+=1
  return b 
 #异或        
 def _codeyihuo(self,code,key):
  code_len=len(key)
  return_list=''
  for i in range(code_len):
   if code[i]==key[i]:
    return_list+='0'
   else:
    return_list+='1'
  return return_list
 #密文或明文初始置换         
 def _codefirstchange(self,code):
  changed_code=''
  for i in range(64):
   changed_code+=code[ip[i]-1]
  return changed_code
 #密钥初始置换
 def _keyfirstchange (self,key):
  changed_key=''
  for i in range(56):
   changed_key+=key[pc1[i]-1]
  return changed_key
 #逆初始置换
 def _functionCodeChange(self, code):
  return_list=''
  for i in range(16):
   list=''
   for j in range(4):
    list+=code[ip_1[i*4+j]-1]
   return_list+="%x" %int(list,2)
  return return_list
 #扩展置换 
 def _functionE(self,code):
  return_list=''
  for i in range(48):
   return_list+=code[e[i]-1]
  return return_list  
 #置换P 
 def _functionP(self,code):
  return_list=''
  for i in range(32):
   return_list+=code[p[i]-1]
  return return_list
 #S盒代替选择置换 
 def _functionS(self, key):
  return_list=''
  for i in range(8):
   row=int( str(key[i*6])+str(key[i*6+5]),2)
   raw=int(str( key[i*6+1])+str(key[i*6+2])+str(key[i*6+3])+str(key[i*6+4]),2)
   return_list+=self._functionTos(s[i][row][raw],4)
  return return_list
 #密钥置换选择2
 def _functionKeySecondChange(self,key):
  return_list=''
  for i in range(48):
   return_list+=key[pc2[i]-1]
  return return_list
 #将十六进制转换为二进制字符串
 def _functionCharToA(self,code,lens):
  return_code=''
  lens=lens%16
  for key in code:
   code_ord=int(key,16)
   return_code+=self._functionTos(code_ord,4)
  if lens!=0:
   return_code+='0'*(16-lens)*4
  return return_code
 #二进制转换
 def _functionTos(self,o,lens):
  return_code=''
  for i in range(lens):
   return_code=str(o>>i &1)+return_code
  return return_code
#将unicode字符转换为16进制
def tohex(string):
 return_string=''
 for i in string:
  return_string+="%02x"%ord(i)
 return return_string
def tounicode(string):
 return_string=''
 string_len=len(string)
 for i in range(0,string_len,2):
  return_string+=chr(int(string[i:i+2],16))
 return return_string
#入口函数
def desdecode(from_code,key):
 key=tohex(key)
 des=DES()
 key_len=len(key)
 string_len=len(from_code)
 if string_len%16!=0:
  return False
 if string_len<1 or key_len<1:
  return False
 key_code= des.decode(from_code,key,key_len,string_len)
 return tounicode(key_code)
#测试
if __name__ == '__main__':
 print desdecode('84148584371a6a1fe99e1da0ce1e34649b88ed15098e8aa4b8eb0bf24885c658','0f1571c947刘'

解密后为: 我是12345678刘就是我abcdwfd

Python DES 加密解密,就是大家所谓想要的那个非常快速的方法
这个要借助Crypto.Cipher这个插件来实现的,引用后只需要写如下代码即可

from Crypto.Cipher import DES

class MyDESCrypt:
  
  key = chr(11)+chr(11)+chr(11)+chr(11)+chr(11)+chr(11)+chr(11)+chr(11)
  iv = chr(22)+chr(22)+chr(22)+chr(22)+chr(22)+chr(22)+chr(22)+chr(22)
  
  def __init__(self,key='',iv=''):
    if len(key)> 0:
      self.key = key
    if len(iv)>0 :
      self.iv = iv
    
  def ecrypt(self,ecryptText):
    try:
      cipherX = DES.new(self.key, DES.MODE_CBC, self.iv)
      pad = 8 - len(ecryptText) % 8
      padStr = ""
      for i in range(pad):
       padStr = padStr + chr(pad)
      ecryptText = ecryptText + padStr
      x = cipherX.encrypt(ecryptText)
      return x.encode('hex_codec').upper()
    except:
      return ""
   
  
  def decrypt(self,decryptText):
    try:
      
      cipherX = DES.new(self.key, DES.MODE_CBC, self.iv)
      str = decryptText.decode('hex_codec')
      y = cipherX.decrypt(str)
      return y[0:ord(y[len(y)-1])*-1]
    except:
      return ""

建议大家可以结合一些插件使用,更方便与快捷

希望本文所述对大家的Python程序设计有所帮助。

Python 相关文章推荐
Python开发实例分享bt种子爬虫程序和种子解析
May 21 Python
Python实现统计文本文件字数的方法
May 05 Python
Python实现求两个csv文件交集的方法
Sep 06 Python
Python3 中文文件读写方法
Jan 23 Python
解决python Markdown模块乱码的问题
Feb 14 Python
python算法与数据结构之单链表的实现代码
Jun 27 Python
Django 接收Post请求数据,并保存到数据库的实现方法
Jul 12 Python
基于Python执行dos命令并获取输出的结果
Dec 30 Python
基于TensorBoard中graph模块图结构分析
Feb 15 Python
解决Jupyter无法导入已安装的 module问题
Apr 17 Python
python 在sql语句中使用%s,%d,%f说明
Jun 06 Python
详解pycharm自动import所需的库的操作方法
Nov 30 Python
python实现的系统实用log类实例
Jun 30 #Python
python实现在windows服务中新建进程的方法
Jun 30 #Python
python实现线程池的方法
Jun 30 #Python
python实现的简单FTP上传下载文件实例
Jun 30 #Python
编写Python CGI脚本的教程
Jun 29 #Python
Python访问纯真IP数据库脚本分享
Jun 29 #Python
Python实现把数字转换成中文
Jun 29 #Python
You might like
深入理解用mysql_fetch_row()以数组的形式返回查询结果
2013/06/05 PHP
PHP中的自动加载操作实现方法详解
2019/08/06 PHP
php文件后缀不强制为.php的实操方法
2019/09/18 PHP
经过绑定元素时会多次触发mouseover和mouseout事件
2014/02/28 Javascript
jQuery的3种请求方式$.post,$.get,$.getJSON
2014/03/28 Javascript
JavaScript Promise启示录
2014/08/12 Javascript
jQuery实现TAB风格的全国省份城市滑动切换效果代码
2015/08/24 Javascript
jQuery动画效果实现图片无缝连续滚动
2016/01/12 Javascript
jquery拖拽效果完整实例(附demo源码下载)
2016/01/14 Javascript
基于JavaScript实现图片点击弹出窗口而不是保存
2016/02/06 Javascript
javascript实现粘贴qq截图功能(clipboardData)
2016/05/29 Javascript
AngularJS 面试题集锦
2016/09/06 Javascript
第一次接触Bootstrap框架
2016/10/24 Javascript
jQuery+HTML5实现WebGL高性能烟花绽放动画效果【附demo源码下载】
2017/08/18 jQuery
详解如何实现Element树形控件Tree在懒加载模式下的动态更新
2019/04/25 Javascript
对TypeScript库进行单元测试的方法
2019/07/18 Javascript
layui 表单标签的校验方法
2019/09/04 Javascript
Vue移动端实现图片上传及超过1M压缩上传
2019/12/23 Javascript
Python中使用dom模块生成XML文件示例
2015/04/05 Python
玩转python selenium鼠标键盘操作(ActionChains)
2020/04/12 Python
如何在sae中设置django,让sae的工作环境跟本地python环境一致
2017/11/21 Python
Python:Numpy 求平均向量的实例
2019/06/29 Python
在pandas中遍历DataFrame行的实现方法
2019/10/23 Python
django多种支付、并发订单处理实例代码
2019/12/13 Python
PyQt5 如何让界面和逻辑分离的方法
2020/03/24 Python
python用tkinter实现一个gui的翻译工具
2020/10/26 Python
HTML5 body设置自适应全屏
2020/05/07 HTML / CSS
化工专业应届生求职信
2013/11/08 职场文书
医生进修自我鉴定
2014/01/19 职场文书
高中历史教学反思
2014/02/08 职场文书
优秀教师先进材料
2014/12/16 职场文书
七年级地理教学计划
2015/01/22 职场文书
初中英语教师个人工作总结
2015/02/09 职场文书
听课评课活动心得体会
2016/01/15 职场文书
Python 解决空列表.append() 输出为None的问题
2021/05/23 Python
Python使用Beautiful Soup(BS4)库解析HTML和XML
2022/06/05 Python