python如何实现DES加密


Posted in Python onSeptember 21, 2020

加密流程

首先说一下置换的意思,比如说有5678这个字符串,置换表为2143,置换表中的数表示的是位置,所以字符串变成6587。所有的置换表在程序中。(S盒置换不一样,会另外说明)

密钥部分

python如何实现DES加密

  • 把8位字符串密钥变成2进制(好像密钥只可以是8位,这一块我也没有搞太清楚)
  • 64位密钥进行PC1置换,变成56位,因为以前DES是用硬件实现的,所以8,16,24,32,40,48,56,64位为校验位,不记入密钥部分。但是我们现在是用软件实现,所以这8位需要去掉,再打乱顺序。
  • 将56位密钥对半分L0和R0、分别对L0和R0进行左循环移位,(当轮数为第1、2、9、16轮时,移动1位,其余时候移动两位)L0,R0移动1位后得到L1,R1。L1和R0继续进行下一轮,进行16轮。
  • 上面移位得到的所以Li+Ri进行PC2置换得到16个子密钥(PC2置换把56位数据变成了48位)。

明文部分

  • 先进行明文填充,采用PKCS #5规则,如果刚好满足每组有8个字节,则再添加一组,每个字节为000010000,如果最后一组没有8个字节,则把这一组填充成8个字节,填充的字节为少掉的字节的数目,比如有7个字节,则填充00000001。
  • 再进行初始置换,把64位明文打乱。
  • 进行16轮feistel函数后在进行逆初始运算

feistel函数

python如何实现DES加密

​以一组为例子来说明,一组明文8个字节,64位。有16轮迭代,要运行16次feistel函数。注意在16轮迭代前要把明文进行初始置换,迭代后把左右两边数据合并成64位再进行逆初始运算。

  • 把64位明文左右对半分成两份。
  • 右边的先进行部分进行扩展置换,32位变成48位。
  • 再和对应轮数的子密钥进行异或运算。
  • 再进行S盒运算,48位变成32位。S盒运算具体操作方法是,把48位数据分成8份,每份就有6位数据,比如010110,把头和尾结合位00,变成十进制就是0,中间四位的十进制为11,所以(x,y)为(0,11)

[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]

在上面这个表中表示的就是12,在把12变成2进制就是1100,所以6位就变成了4位。总共有8份数据,也有8个表。每份对应的运算的表都不一样。

  • 再进行P盒运算。
  • 最后和左边的32位进行异或运算。

解密

解密部分除了在feistel函数中调用子密钥的顺序相反外,其他都一样。加密调用的顺序是1-16,解密是16-1。

代码

#################################辅助函数######################################

# 十进制转成二进制
def INT_BIN(NUM):
  i = bin(NUM)[2:]
  if len(i) != 8:
    i = ((8 - len(i)) * '0') + i

  return i

# 置换函数
def Replace(ARR,change):
  ARR1 = []
  for i in ARR:
    a = ''
    for j in change:
      a += i[j-1]
    ARR1.append(a)
  return ARR1

# 异或运算
def XOR(a,b):
  c=""
  for i,j in zip(a,b):
    if i==j:
      c+='0'
    else:
      c+='1'
  return [c]

# 二进制转字符
def ASCII(A):
  text = ''
  for i in A:
    for j in range(8):
      b = i[j*8:(j+1)*8]
      text += chr(int(b,2))
  return text

##############################################################################

#################################密钥生成######################################
# 先PC1置换、将56位密钥对半分L0和R0、分别对L0和R0进行左循环移位,
# (当轮数为第1、2、9、16轮时,移动1位,其余时候移动两位)L0,R0移动1位
# 后得到L1,R1,L1+R0进行PC2置换得到密钥K1,L1和R0继续进行下一轮,直到生成16个子密钥

# PC-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]

# PC-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]

# 生成子密钥函数
def GenerateSubkey(Key):
  # 字符串转二进制
  K = ""
  i_byte = bytes(Key, encoding='utf-8')
  for i_bin in i_byte:
    K += INT_BIN(i_bin)

  # PC1置换
  ReplacePc1 = Replace([K],PC1)

  # 生成16组子密钥
  Lmi = []
  Rmi = []
  Lmi.append(ReplacePc1[0][:28])
  Rmi.append(ReplacePc1[0][28:])
  for i in range(1,17):
    if i in (1, 2, 9, 16):
      Lmi.append(Lmi[i-1][1:]+Lmi[i-1][:1])
      Rmi.append(Rmi[i-1][1:]+Rmi[i-1][:1])
    else:
      Lmi.append(Lmi[i-1][2:]+Lmi[i-1][:2])
      Rmi.append(Rmi[i-1][2:]+Rmi[i-1][:2])
  del Lmi[0]
  del Rmi[0]
  del ReplacePc1[0]
  for i in range(16):
    ReplacePc1.append(Lmi[i]+Rmi[i])

  # PC2置换
  return Replace(ReplacePc1,PC2)

###########################################################################

#################################明文处理###################################
# 明文填充,采用PKCS #5规则,如果刚好满足每组有8个字节,则再添加一组,每个字节为
# 000010000,如果最后一组没有8个字节,则把这一组填充成8个字节,填充的字节为少掉的
# 字节的数目,比如有7个字节,则填充00000001

# 对明文进行填充,分组
def InitPlaintext(Plaintext):
  DecimalList = []
  BytesList = []
  BinList = []
  
  # 字符串转成10机制
  i_byte = bytes(Plaintext, encoding='utf-8')
  for i_bin in i_byte:
    DecimalList.append(i_bin)

  # 刚好满足分组
  if len(DecimalList) % 8 == 0:
    for i in range(8):
      DecimalList.append(8)
    for i in range(int(len(DecimalList)/8)):
      BytesList.append(DecimalList[i*8:(i+1)*8])
  # 不满足分组
  else:
    INT = 8 - len(DecimalList) % 8
    for i in range(INT):
      DecimalList.append(INT)
    for i in range(int(len(DecimalList)/8)):
      BytesList.append(DecimalList[i*8:(i+1)*8])
  
  # 10进制转2进制
  for i in BytesList:
    TMP = ''
    for j in i:
      TMP += INT_BIN(j)
    BinList.append(TMP)
  
  return BinList

###########################################################################

################################feistel函数################################
#ip初始置换表
IPINIT = [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]

#扩展E置换表
EExten = [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盒置换表
PBOX = [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]

#逆初始置换表
P1 = [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]

#8个s盒
S_1 = [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]
 
S_2 = [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]
 
S_3 = [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]
 
S_4 = [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]
 
S_5 = [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]
 
S_6 = [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]
 
S_7 = [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]
 
S_8 = [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]

S_9 = []
S_9.append(S_1)
S_9.append(S_2)
S_9.append(S_3)
S_9.append(S_4)
S_9.append(S_5)
S_9.append(S_6)
S_9.append(S_7)
S_9.append(S_8)

# S盒置换
def S(R):
  s = ''
  for i in range(8):
    a = R[i*6:(i+1)*6]
    x = int(a[0]+a[-1],2)
    y = int(a[1:5],2)
    s += INT_BIN(S_9[i][x*15+y])[4:]
  return[s]


# feistel函数
def feistel(L, R, K):
  # 扩展置换
  Expand = Replace(R,EExten)
  # 异或运算
  Expand = XOR(Expand[0],K)
  # S盒运算
  Expand = S(Expand[0])
  # P盒
  Expand = Replace(Expand,PBOX)
  # 异或运算
  Expand = XOR(L[0],Expand[0])

  return Expand[0]

###########################################################################

################################加、解密函数################################
# 加密
def Encrypt(PlanText,Key):
  # 初始置换
  IP1 = Replace(InitPlaintext(PlanText),IPINIT)
  # 生成子密钥
  SubkeyList = GenerateSubkey(Key)

  # 16轮迭代
  Ciphertext = []
  for i in IP1:
    L = i[:32]
    R = i[32:]
    for k in SubkeyList:
      TMP = feistel([L],[R],k)
      L = R
      R = TMP
    # 逆初始置换
    Ciphertext.append(Replace([R+L],P1)[0])
  return Ciphertext,SubkeyList

# 解密
def Decrypt(Ciphertext,Key):
  # 初始置换
  IP1 = Replace(Ciphertext,IPINIT) 

  # 16轮迭代
  PlanText = []
  for i in IP1:
    L = i[:32]
    R = i[32:]
    for k in Key[::-1]:
      TMP = feistel([L],[R],k)
      L = R
      R = TMP
    # 逆初始置换
    PlanText.append(Replace([R+L],P1)[0])
  return PlanText

###########################################################################

if __name__ == "__main__":
  miwen,miyao = Encrypt('computer','networks')
  print(miwen)
  print(ASCII(Decrypt(miwen,miyao)))

以上就是python如何实现DES加密的详细内容,更多关于python实现DES加密的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Django中对通过测试的用户进行限制访问的方法
Jul 23 Python
利用ctypes提高Python的执行速度
Sep 09 Python
Python数据处理numpy.median的实例讲解
Apr 02 Python
在python中使用requests 模拟浏览器发送请求数据的方法
Dec 26 Python
Python实现删除排序数组中重复项的两种方法示例
Jan 31 Python
TensorFlow tf.nn.conv2d实现卷积的方式
Jan 03 Python
Pytorch使用MNIST数据集实现基础GAN和DCGAN详解
Jan 10 Python
Python3读写Excel文件(使用xlrd,xlsxwriter,openpyxl3种方式读写实例与优劣)
Feb 13 Python
浅谈keras通过model.fit_generator训练模型(节省内存)
Jun 17 Python
Python之Matplotlib文字与注释的使用方法
Jun 18 Python
Python实现七个基本算法的实例代码
Oct 08 Python
python 邮件检测工具mmpi的使用
Jan 04 Python
如何从csv文件构建Tensorflow的数据集
Sep 21 #Python
python打包多类型文件的操作方法
Sep 21 #Python
python 星号(*)的多种用途
Sep 21 #Python
Python+Selenium随机生成手机验证码并检查页面上是否弹出重复手机号码提示框
Sep 21 #Python
解决PyCharm不在run输出运行结果而不是再Console里输出的问题
Sep 21 #Python
python map比for循环快在哪
Sep 21 #Python
通过实例解析Python文件操作实现步骤
Sep 21 #Python
You might like
php 之 没有mysql支持时的替代方案
2006/10/09 PHP
火车采集器 免费版使出收费版本功能实现原理
2009/09/17 PHP
ThinkPHP访问不存在的模块跳转到404页面的方法
2014/06/19 PHP
EarthLiveSharp中cloudinary的CDN图片缓存自动清理python脚本
2017/04/04 PHP
JS request函数 用来获取url参数
2010/05/17 Javascript
JavaScript Date对象 日期获取函数
2010/12/19 Javascript
在JavaScript中typeof的用途介绍
2013/04/11 Javascript
JavaScript截取字符串的Slice、Substring、Substr函数详解和比较
2014/03/20 Javascript
js实现鼠标感应向下滑动隐藏菜单的方法
2015/02/20 Javascript
浅谈JavaScript超时调用和间歇调用
2015/08/30 Javascript
Node.js的npm包管理器基础使用教程
2016/05/26 Javascript
浅谈js中的延迟执行和定时执行
2016/05/31 Javascript
微信小程序 获取相册照片实例详解
2016/11/16 Javascript
vue日期组件 支持vue1.0和2.0
2017/01/09 Javascript
node.js中对Event Loop事件循环的理解与应用实例分析
2020/02/14 Javascript
Typescript3.9 常用新特性一览(推荐)
2020/05/14 Javascript
详解JavaScript 作用域
2020/07/14 Javascript
[02:02:38]VG vs Mineski Supermajor 败者组 BO3 第一场 6.6
2018/06/07 DOTA
Python升级提示Tkinter模块找不到的解决方法
2014/08/22 Python
Python自动生产表情包
2017/03/17 Python
Python基于生成器迭代实现的八皇后问题示例
2018/05/23 Python
python实现对csv文件的列的内容读取
2018/07/04 Python
numpy数组之存取文件的实现示例
2019/05/24 Python
python multiprocessing多进程变量共享与加锁的实现
2019/10/02 Python
python实现交并比IOU教程
2020/04/16 Python
Django中的AutoField字段使用
2020/05/18 Python
Python3如何在服务器打印资产信息
2020/08/27 Python
Python 多进程、多线程效率对比
2020/11/19 Python
python实现经纬度采样的示例代码
2020/12/10 Python
CSS+jQuery实现的在线答题功能
2015/04/25 HTML / CSS
越南母婴用品购物网站:Kids Plaza
2020/04/09 全球购物
请说出这段代码执行后a和b的值分别是多少
2015/03/28 面试题
出纳的岗位职责
2013/11/09 职场文书
初中体育教学反思
2014/01/14 职场文书
MySQL学习总结-基础架构概述
2021/04/05 MySQL
部分武汉产收音机展览
2022/04/07 无线电