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实现文件快照加密保护的方法
Jun 30 Python
qpython3 读取安卓lastpass Cookies
Jun 19 Python
深入理解NumPy简明教程---数组3(组合)
Dec 17 Python
基于python OpenCV实现动态人脸检测
May 25 Python
Python从数据库读取大量数据批量写入文件的方法
Dec 10 Python
利用python脚本如何简化jar操作命令
Feb 24 Python
初探利用Python进行图文识别(OCR)
Feb 26 Python
Python 脚本的三种执行方式小结
Dec 21 Python
python读取ini配置文件过程示范
Dec 23 Python
python3实现网页版raspberry pi(树莓派)小车控制
Feb 12 Python
解决pycharm中opencv-python导入cv2后无法自动补全的问题(不用作任何文件上的修改)
Mar 05 Python
python 装饰器的实际作用有哪些
Sep 07 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
php 保留小数点
2009/04/21 PHP
PHP PDOStatement::errorCode讲解
2019/01/31 PHP
PHP 自动加载类原理与用法实例分析
2020/04/14 PHP
CI框架简单分页类用法示例
2020/06/06 PHP
jQuery中setTimeout的几种使用方法小结
2013/04/07 Javascript
js简单实现用户注册信息的校验代码
2013/11/15 Javascript
jQuery添加/改变/移除CSS类及判断是否已经存在CSS
2014/08/20 Javascript
jQuery使用之处理页面元素用法实例
2015/01/19 Javascript
sso跨域写cookie的一段js脚本(推荐)
2016/05/25 Javascript
jQuery使用siblings获取某元素所有同辈(兄弟姐妹)元素用法示例
2017/01/30 Javascript
JS正则验证多个邮箱完整实例【邮箱用分号隔开】
2017/04/19 Javascript
一篇看懂vuejs的状态管理神器 vuex状态管理模式
2017/04/20 Javascript
JS查找数组中重复元素的方法详解
2017/06/14 Javascript
JS判断非空至少输入两个字符的简单实现方法
2017/06/23 Javascript
浅谈Vuex的this.$store.commit和在Vue项目中引用公共方法
2020/07/24 Javascript
原生js实现自定义消息提示框
2020/11/19 Javascript
Python 条件判断的缩写方法
2008/09/06 Python
python ElementTree 基本读操作示例
2009/04/09 Python
python 正则表达式 概述及常用字符
2009/05/04 Python
Python functools模块学习总结
2015/05/09 Python
linux环境下的python安装过程图解(含setuptools)
2017/11/22 Python
python 识别图片中的文字信息方法
2018/05/10 Python
Python使用pandas处理CSV文件的实例讲解
2018/06/22 Python
Python爬取视频(其实是一篇福利)过程解析
2019/08/01 Python
Pytorch maxpool的ceil_mode用法
2020/02/18 Python
python一些性能分析的技巧
2020/08/30 Python
设置器与访问器的定义以及各自特点
2016/01/08 面试题
20年同学聚会邀请函
2014/02/04 职场文书
大学军训感言1500字
2014/03/09 职场文书
我的理想演讲稿
2014/04/30 职场文书
2015年女生节活动总结
2015/02/27 职场文书
表扬信范文
2015/05/04 职场文书
CocosCreator ScrollView优化系列之分帧加载
2021/04/14 Python
go xorm框架的使用
2021/05/22 Golang
HTML中的表单元素介绍
2022/02/28 HTML / CSS
js作用域及作用域链工作引擎
2022/07/07 Javascript