之前在网上看了好多关于DES加解密的文章,很多都是直接贴代码,然而大多数都不能运行。花了一天写了个能运行的程序,其中有参考网上的一些好的代码。希望入了密码学坑的同学能得到帮助。python刚上手,代码很长,希望大家多多给出建议。

def keychanged(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, 33, 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+=key[pc1[i]-1]
    return changed_key

#将Unicode字符转换为16进制数   
def tohex(string):
    return_string=''
    for i in string:
        return_string+="%02x"%ord(i)
    return return_string

#将16进制数转换为2进制数
def _functionCharToA(code):
    return_code=''
    lens = len(code)
    lens=lens%16
    for key in code:
        code_ord=int(key,16)
        return_code+=_functionTos(code_ord,4)   
    if lens!=0:
        return_code+='0'*(16-lens)*4###如16进制数不为16倍数,则将剩余补为16位
    return return_code

#将16进制数转换为4位2进制数
def _functionTos(o,lens):
    return_code=''
    for i in range(lens):
        return_code=str(o>>i &1)+return_code
    return return_code

###将2进制字符串转换为16进制字符串
def binTohex(string):
    lens = len(string)
    tohex = ''
    for i in range(0,lens,4):
        list = string[i]+string[i+1]+string[i+2]+string[i+3]
        tohex +="%x"%int(list,2)
    return tohex

###将16进制转换为unicode字符
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

#num = tohex(string)
#dnum = _functionCharToA(num)
#changedkey = keychanged(dnum)
#key_l = changedkey[0:28]
#key_r = changedkey[28:56]

###密钥可以转换为2进制数了

def roundKey(initkey):
    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)
    keylist = []
    key_l = initkey[0:28]
    key_r = initkey[28:56]
    for i in range(16):
        key_l = key_l[d[i]:28]+key_l[0:d[i]]
        key_r = key_r[d[i]:28]+key_r[0:d[i]]
        key = key_l+key_r
        return_list = ''
        for i in range(48):#密钥置换选择2
            return_list+=key[pc2[i]-1]
        keylist.append(return_list)
    return keylist
###将轮密钥存在keylist中
#keylist = []
#keylist = roundKey(changedkey)
#print(keylist)

###密钥生成器完毕

###以下是对明文的处理######
def _codefirstchange(code):#明文初始置换
    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

#changetext = tohex(cleartext)
#binarytext = _functionCharToA(changetext)
#print(binarytext)

#textfirstchange = _codefirstchange(binarytext)
#print(len(textfirstchange))
#text_l = textfirstchange[0:32]
#text_r = textfirstchange[32:64]
#print("明文初始置换后:"+text_l+","+text_r)

####明文初始置换完毕

###F函数#####
#扩展置换E
def _functionE(code):
    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+=code[e[i]-1]
    return return_list   
#expandtext_r = _functionE(text_r)
#print("text_r扩展置换后:"+expandtext_r)

####异或
def _codeyihuo(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
#yihuotext_r = _codeyihuo(expandtext_r,keylist[0])
#print("异或后的的text_r:"+yihuotext_r)

####S盒
def _functionS(key):
    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(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+=_functionTos(s[i][row][raw],4)#选择一个数,并转换为4位2进制数
    return return_list

#afterSboxtext_r = _functionS(yihuotext_r)
#print("经过S盒后:"+afterSboxtext_r)
####置换P
def _functionP(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+=code[p[i]-1]
    return return_list
#afterPpermutetext_r = _functionP(afterSboxtext_r)
#print("F函数输出:"+afterPpermutetext_r)

#nowtext_r = _codeyihuo(afterPpermutetext_r,text_l)
#print("一轮迭代后的text_r:"+nowtext_r)

#逆初始置换
def _functionCodeChange(code):
    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

###要不设计成加密64位2进制串的吧
###输入的明文与密钥都是二进制字符串
def Aencryption(binaryText,binaryKey,operate):
    
    turn_len = len(binaryText)
    output = ''
    keylist = []
    firstchangedkey = keychanged(binaryKey)
    keylist = roundKey(firstchangedkey)#keylist存上了每轮的密钥
    
    if(operate == "de"):###解密时将密钥列表逆转
        keylist = keylist[::-1]

for i in range(0,turn_len,64):
    #指导书中将只需对64bit进行加解密即可
        run_code = binaryText[i:i+64]###每次选择64位明文进行加密
        run_code = _codefirstchange(run_code)###对明文进行初始置换
        for j in range(16):
        #取出明文的左右32位
            code_l=run_code[0:32]
            code_r=run_code[32:64]
        #进行左右置换
            run_code = code_r
        
        #将右边32位扩展置换为48位
        #与本轮密钥进行异或
        #进入S盒进行代替选择
        #进入置换P
            code_r = _functionE(code_r)
            code_r = _codeyihuo(code_r,keylist[j])
            code_r = _functionS(code_r)
        #将明文左边32位于F函数中出来值进行异或
            code_r= _codeyihuo(code_l,code_r)
        #将一轮加密后的左右两边密文置换合并,
            run_code += code_r
    #32位互换
        code_l=run_code[0:32]
        code_r=run_code[32:64]
        run_code=code_r+code_l
    ##此时output为2进制数
        output += _functionCodeChange(run_code)
    return(output)

#明文和密钥可能不是64位,key中一个字符4位,所以key长度必须大于16,
#但这里已经在16进制转换为二进制数时处理了

operate = input("加密请输入:en\n解密请输入:de\n")
while(operate!="en" and operate!="de"):
    print("输入格式错误,请重新输入!")
    operate = input("加密请输入:en\n解密请输入:de\n")
    
if(operate =="en"):
    way = input("ECB加密模式请输入:ECB\nCBC加密模式请输入:CBC\n")
    while(way!="ECB" and way!="CBC"):
        print("输入格式错误,请重新输入!")
        way = input("ECB模式请输入:ECB\nCBC模式请输入:CBC\n")
        
elif(operate == "de"):
    print("进入ECB解密模式")
    way = "ECB"

rage = []
IV = "0011000100110011001100110011011000110110001110000011010100110101"#初始向量,CBC加密时使用
rage.append(IV)

if(operate == "en" and way == "CBC"):
    cleartext = input("请输入需要加密的字符串:")
    key = input("请输入密钥:")
    output = ''
    changekey = tohex(key)
    binarykey = _functionCharToA(changekey)
    
    changetext = tohex(cleartext)
    binarytext = _functionCharToA(changetext)
    
    lens = len(binarytext)
    j = 0
    for i in range(0,lens,64):
        mixbinarytext = _codeyihuo(binarytext[i:i+64],rage[j])
        miwen = Aencryption(mixbinarytext,binarykey,operate)###miwen此时为二进制数
        output += miwen
        rage.append(miwen)
        j = j+1
    print("密文:"+output)
    mitohex = binTohex(output)
    realtext = tounicode(mitohex)
    print("密文:"+realtext)

choose = input("是否要进行解密?(y/n):")
    if(choose == 'y'):
        
        operate ="de"
        output = ''
        
        cleartext = input("请输入需要解密的字符串:")
        key = input("请输入密钥:")
        
        changetext = tohex(cleartext)
        binarytext = _functionCharToA(changetext)
        
        print(binarytext)
        changekey = tohex(key)
        binarykey = _functionCharToA(changekey)
        
        lens = len(binarytext)#计算密文长度

j = 0
        for i in range(0,lens,64):
            run_code = binarytext[i:i+64]
            afterDesText = Aencryption(run_code,binarykey,operate)###miwen此时为二进制数
            mingwen = _codeyihuo(afterDesText,rage[j])
            output += mingwen
            j = j+1
            
        print("明文:"+output)
        texttohex = binTohex(output)
        realtext = tounicode(texttohex)
        print("明文:"+realtext)

elif(operate == "en" and way =="ECB"):
    cleartext = input("请输入需要加密的字符串:")
    key = input("请输入密钥:")
    
    changetext = tohex(cleartext)
    binarytext = _functionCharToA(changetext)
    
    changekey = tohex(key)
    binarykey = _functionCharToA(changekey)
    
    mingwen = Aencryption(binarytext,binarykey,operate)###miwen此时为二进制数
    print("密文:"+mingwen)
    mitohex = binTohex(mingwen)
    realtext = tounicode(mitohex)
    print("密文:"+realtext)

choose = input("是否要ECB进行解密?(y/n):")
    if(choose == 'y'):
        operate = "de"
        cleartext = input("请输入需要解密的字符串:")
        key = input("请输入密钥:")
        
        changetext = tohex(cleartext)
        binarytext = _functionCharToA(changetext)
        changekey = tohex(key)
        binarykey = _functionCharToA(changekey)
        
        mingwen = Aencryption(binarytext,binarykey,operate)###miwen此时为二进制数
        print("明文:"+mingwen)
        tohex = binTohex(mingwen)
        realtext = tounicode(tohex)
        print("明文:"+realtext)
        
    
elif(operate == "de" and way =="ECB"):
    cleartext = input("请输入需要解密的字符串:")
    key = input("请输入密钥:")
    
    changetext = tohex(cleartext)
    binarytext = _functionCharToA(changetext)
    
    changekey = tohex(key)
    binarykey = _functionCharToA(changekey)
    
    mingwen = Aencryption(binarytext,binarykey,operate)###miwen此时为二进制数
    print("明文:"+mingwen)
    tohex = binTohex(mingwen)
    realtext = tounicode(tohex)
    print("明文:"+realtext)

用python实现DES加解密,并附带EBC和CBC两种分组加密模式相关推荐

  1. 用Python写DES加解密的常用函数

    文章目录 生成pkcs(填充明文) 去掉填充 DES加密(ECB模式) DES解密(ECB模式) 请求包加密 请求包解密 响应包解密 响应包加密 class Burpy 备注 生成pkcs(填充明文) ...

  2. PHP 基础篇 - PHP 中 DES 加解密详解

    2019独角兽企业重金招聘Python工程师标准>>> 一.简介 DES 是对称性加密里面常见一种,全称为 Data Encryption Standard,即数据加密标准,是一种使 ...

  3. 一个java的DES加解密类转换成C#

    原文:一个java的DES加解密类转换成C# 一个java的des加密解密代码如下: //package com.visionsky.util;import java.security.*; //im ...

  4. 密码学入门1——凯撒密码和三重DES加解密

    实验目的 1.完成第一个入门加解密--凯撒密码 2.完成当下较为流行的三重DES加解密技术 3.熟悉所学的实际运用方向 实验准备 硬件:计算机或笔记本电脑 操作系统:Mac操作系统 IDE环境:Ecl ...

  5. C语言实现DES加解密算法

    C语言实现DES加解密算法 DES加解密 DES加解密 #include <stdio.h> #include <stdlib.h> #include <string.h ...

  6. js des加密 java_Java实现与JS相同的Des加解密算法完整实例

    本文实例讲述了Java实现与JS相同的Des加解密算法.分享给大家供大家参考,具体如下: 这里演示java与js实现相同的des加解密算法,不多说,不废话,直接上代码 一.java实现 package ...

  7. LKT系列加密芯片DES加解密以及OpenSSL DES接口实现加解密

    1.测试目标 使用已经预置DES密钥的LKT4201N系列加密芯片完成运算 2.测试环境 本示例运行环境为windows系统.测试软件LCS KIT.LKT-K100开发板. 3.测试步骤 注意:&q ...

  8. Hutool进行DES加解密

    Hutool进行DES加解密 先简述以下:一个数据接口,接收到的是DES加密后的json字符串,需要先解密再转成bean对象. 我试了网上很多方式实现,发现每次加密后最后几位不同.想着对称加解密还能这 ...

  9. java 和 c# 下的RSA证书+AES+DES加解密实现

    java 和 c# 下的RSA+AES+DES加解密实现 前言 在实际应用中,经常有需要使用加解密的情况,RSA\AES\DES是比较常用的几种加解密方式,使用和实现方式都比较成熟可靠,本文简要介绍一 ...

最新文章

  1. 你熟知的那个杀毒软件公司McAfee,用这种方法骗过护照人脸识别系统
  2. 谷歌X实验室的“无用”发明
  3. JAVA中的反射()
  4. Linux crontab定时任务示例
  5. Java垃圾回收(GC)、找垃圾的方式、GC Root、GC停顿、引用、垃圾收集算法、收集器、GC日志、安全点、安全区域
  6. python3与Beautiful Soup库
  7. P5200 [USACO19JAN]Sleepy Cow Sorting 牛客假日团队赛6 D 迷路的牛 (贪心)
  8. java的scanner的方法_Java Scanner reset()方法
  9. Oracle入门(三B)之11G新特性 SYSASM 角色用来管理ASM
  10. Ubuntu linux 查看串口连接信息
  11. 华为服务器备件系统,华为企业业务中国区经销商备件系列宣传(共8期)
  12. stl的multiset和set和priority_queue区别
  13. POJ - 3190
  14. 设计算法之分治法(补充)
  15. 利用SMS轻松实现资产管理,SMS2003系列之四
  16. layui jquery innerHTML 无效
  17. Java 微服务实践
  18. IDEA之非常复制黏贴
  19. 网页版第三方登录操作——微信登录
  20. Oracle数据库表空间整理回收与释放操作

热门文章

  1. js学习01 :js编写位置+js基础语法
  2. matlab匿名函数
  3. 2015年蓝桥杯省赛C++B组真题与题解
  4. [精易软件开发工程师Leo学习笔记]007流程控制
  5. 迅雷小动作 两招教你禁用偷偷上传
  6. 计算机组成原理时序发生器qd,计算机组成原理微程序控制器组成实验课程实验报告书...
  7. alsa ubuntu声卡驱动重新安装
  8. 魅族手机(魅蓝note)无法作为调试设备连接到mac问题的解决
  9. 陕西省职称网上申报系统评审范围和要求
  10. 18计科专业《数据结构》教学大纲