参考资料:
DES结构实现
各阶段函数结果验证


具体详细说明可以先参看参考资料,后面再补充详细的说明。
代码实现:

# 采用ECB方式加密,填充方式采用zeropadding
# 明文输入需要是ASCII在 0-255之间的字符,中文输入暂时不支持
# 密钥需要是8字节字符串
# IP置换表
IP_table=[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
]# 扩展置换表
extend_table=[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
]# S盒中的S1盒
S1 = [[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盒中的S2盒
S2 = [[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盒中的S3盒
S3 = [[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盒中的S4盒
S4 = [[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盒中的S5盒
S5 = [[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盒中的S6盒
S6 = [[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盒中的S7盒
S7 = [[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盒中的S8盒
S8 = [[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 = [S1, S2, S3, S4, S5, S6, S7, S8]# P盒
P_table = [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
]# 压缩置换表1,不考虑每字节的第8位,将64位密钥减至56位。然后进行一次密钥置换。
PC_1=[ 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
]# 压缩置换表2,用于将循环左移和右移后的56bit密钥压缩为48bit。
PC_2=[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
]
# 逆置换IP表
_IP_table=[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
]# 循环移位位数表
moveNum=[1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1]# IP置换函数
def IP(message):result = ''# 用IP表进行置换即可for i in IP_table:result += message[i-1]return result# 扩展置换函数
def extend(R0):result=''# 用扩展置换表进行置换即可for i in extend_table:result += R0[i-1]return result# S盒子压缩函数
def sbox(afterRoundKey):result = ''for m in range(0,48,6):# 通过第1位和第6位算出列号i = int(afterRoundKey[m])*2+int(afterRoundKey[m+5])# 通过第2、3、4、5位算出行号j = int(afterRoundKey[m+1])*8+int(afterRoundKey[m+2])*4+int(afterRoundKey[m+3])*2+int(afterRoundKey[m+4])result += str('{:04b}'.format(S[m//6][i][j]))return result# 轮密钥加函数
def addRoundKey(afterExtend,roundKey):result = ''for i in range(48):# 进行按位异或运算result += str(int(afterExtend[i])^int(roundKey[i]))return result# 线性置换P盒
def pbox(afterSbox):result = ''# 用P盒表进行置换即可for i in range(32):result += str(afterSbox[P_table[i]-1])return result# F函数
def F(R0,key):# 扩展将32位扩展为48位R0 = extend(R0)# 与轮密钥进行按位异或afterRoundKey = addRoundKey(R0,key)# 放入S盒压缩afterSbox = sbox(afterRoundKey)# 放入P盒进行线性替换result = pbox(afterSbox)return result#轮密钥生成
def generateKey(key):result = ''roundKey=[]# 进行第一次压缩置换,将64位密钥减至56位,即去除8个校验位for i in PC_1:result += key[i-1]# 分位左右两部分,每部分28位C0=result[:28]D0=result[28:]for i in range(16):# 按循环移位位数表进行移位操作C0=C0[moveNum[i]:]+C0[:moveNum[i]]D0=D0[moveNum[i]:]+D0[:moveNum[i]]tmp=C0+D0ret = ''# 进行第二次压缩将56位压缩减至48位for i in PC_2:ret+=tmp[i-1]# 生成轮密钥存储到列表中roundKey.append(ret)return roundKey# IP逆置换
def inverseIP(afterF):ciphertext=''# 用逆IP表进行置换即可for i in _IP_table:ciphertext+=afterF[i-1]return ciphertext# 加密函数
def encrypt(plaintext,roundKey):# 进行IP置换result = IP(plaintext)# 分左右32bitL0=result[:32]R0=result[32:]# 进行16轮加密for i in range(16):tmp=R0results = F(R0, roundKey[i])# print(results)# print(roundKey[0])R0=''for j in range(32):R0+=str(int(L0[j])^int(results[j]))L0=tmp# print(R0)# 最后一轮结束后结果要左右交换afterF = R0+L0# 进行逆IP置换得到密钥ciphertext=inverseIP(afterF)return ciphertext# 解密函数
def decrypt(ciphertext, roundKey):result = IP(ciphertext)Li = result[:32]Ri = result[32:]# 解密函数对轮密钥使用要倒序使用for i in range(15,-1,-1):tmp=Riresults = F(Ri,roundKey[i])Ri = ''for j in range(32):Ri += str(int(Li[j])^int(results[j]))Li = tmpafterF = Ri+Liplaintext = inverseIP(afterF)return plaintext# 0填充函数
def zeroPadding(message):# UTF-8解码message = list(bytes(message,'utf8'))# 先填充一个0,这使得如果明文本来就是64位仍然要填充64个0到末尾message.append(0)# 填充0到8字节的整数倍while len(message)%8!=0:message.append(0)ret = []strs=''# 分组,化为二进制串,然后没8字节分组放入ret列表中for i in range(len(message)):strs+=str('{:08b}'.format(message[i]))if (i+1)%8==0:ret.append(strs)strs=''return ret# 处理密文函数
def progress(cipher):lens=len(cipher)# 因为密文输入是16进制,所以直接按没16个字符分一组即可,最后会被解释成16*4=64bitm=lens//16ret=[]for i in range(m):ret.append(cipher[i*16:(i+1)*16])return ret# 将16进制位串变为字符
def to_chr(text):lens = len(text)# 每两个个16进制数被解释成一个ASCII码字符,2**8=256m = lens // 2lists = []for i in range(m):lists.append(text[i * 2:(i + 1) * 2])strs = ''for s in lists:tmp=int(s, 16)# 因为ascii码0不会被输入,因此认为是补位值,当存在补位值,后继必为补位值,直接舍弃即可# 对中文进行加解密时这里需要优化if tmp==0:breakstrs += chr(tmp)return strsif __name__ == "__main__":print("请选择1、加密,2、解密:")choose = input()if choose == '1':message = input("请输入要加密的文本:")key = input("请输入密钥:")keylist = list(bytes(key, 'utf8')) # 将密钥变为ascii码if len(keylist)!=8:# 密钥应该为8字节的整数倍print("错误!请输入8字节密钥!")else:key=''for i in keylist:key += str('{:08b}'.format(i)) # 将密钥的ascii码转为2进制roundKey = generateKey(key)# 生成轮密钥,用列表存储lists=zeroPadding(message) # 进行明文0填充,并分组,每64位一组cipher=''for p in lists:cipher+=encrypt(p, roundKey) # 每组分别加密,因为采用ECB方式,直接将各段加密结果链接即可cipher=str(hex(int(cipher,2)))[2:] # 将结果2进制串转化为16进制串输出print(cipher)elif choose == '2':text = input("请输入密文文本:")key = input("请输入密钥:")keylist = list(bytes(key, 'utf8'))if len(keylist)!=8:print("错误!请输入8字节密钥!")else:key = ''for i in keylist:key += str('{:08b}'.format(i))roundKey = generateKey(key)cipherlist=progress(text)plaintext=''for c in cipherlist:message = str('{:064b}'.format(int(c, 16)))tmp=decrypt(message, roundKey)if c==cipherlist[-1] and  int(tmp,2)==0: # 如果当前段位最后一段且当前段值为0,认为是补位段,直接舍弃breakplaintext+=tmpplaintext=str(hex(int(plaintext,2)))[2:]plaintext = to_chr(plaintext) # 将解密结果化为字符输出print(plaintext)else:print("错误输入!")

加解密结果经过在线加密验证正确:
加密:

验证结果:

解密:

python实现DES加密解密相关推荐

  1. python des解密_python实现DES加密解密方法实例详解

    本文实例讲述了python实现DES加密解密方法.分享给大家供大家参考.具体分析如下: 实现功能:加密中文等字符串 密钥与明文可以不等长 这里只贴代码,加密过程可以自己百度,此处python代码没有优 ...

  2. python des加密文件_Python DES加密解密方法 pyDes库 兼容中文

    单纯记录一下Python中DES加密解密的使用方式直接看代码: 依赖pyDes库安装> pip install pyDes 约定秘钥 python和java 加密和解密联调,兼容中文字符串 Py ...

  3. getcoo php_PHP简单实现DES加密解密的方法

    本文实例讲述了PHP简单实现DES加密解密的方法.分享给大家供大家参考,具体如下: des加密: function des_encrypt($str, $key) { $block = mcrypt_ ...

  4. .net实现md5加密 sha1加密 sha256加密 sha384加密 sha512加密 des加密解密

    写项目时,后台一直用md5加密,一天群里人问,除了MD5还有其它的加密方法吗?当时只知道还有个SHA,但怎么实现什么的都不清楚,于是当网上找了下,把几种常见的加密方法都整理了下,用winform写了个 ...

  5. java 实现 DES加密 解密算法

    DES算法的入口参数有三个:Key.Data.Mode.其中Key为8个字节共64位,是DES算法的工作密钥:Data也为8个字节64位,是要被加密或被解密的数据:Mode为DES的工作方式,有两种: ...

  6. DES加密解密算法Java实现

    DES 使用一个 56 位的密钥以及附加的 8 位奇偶校验位,产生最大 64 位的分组大小.这是一个迭代的分组密码,使用称为 Feistel 的技术,其中将加密的文本块分成两半.使用子密钥对其中一半应 ...

  7. python下RSA加密解密以及跨平台问题

    项目合作需要,和其他网站通信,消息内容采用RSA加密方式传递.之前没有接触过RSA,于是两个问题出现了: 声明: 环境WIN 7 + python 2.6.6 RSA格式:PEM 一.Python下R ...

  8. DES加密解密与AES加密解密

    × 目录 [1]AES加密算法和DES加密算法的效率比较 [2]AES和DES加密解密代码 随着开发时间的变长,当初认为比较难的东西,现在渐渐也就变的不那么难了!特别对于一些经常很少使用的类,时间长了 ...

  9. 转载并学习实现三重DES加密解密代码(一)

    作者:finallyliuyu 出处:博客园 声明:此篇博文代码来自于邹德强先生.由于目前找到的版本是残缺版,所以我又进行了补全.读一份好代码,可以领略到作者的编程风格和语言驾驭能力,同时又能从其中汲 ...

  10. java des加密类_java的DES加密解密辅助类

    java的DES加密解密辅助类 package temptest; import java.io.IOException; import java.io.UnsupportedEncodingExce ...

最新文章

  1. Mac下Selenium无法最大化Chrome解决方案
  2. SAP-PM 的工具管理篇
  3. fly a kite
  4. java解析xml文档_Java解析xml文件
  5. PHP中的const
  6. Java黑皮书课后题第7章:**7.17(对学生排序)编写一个程序,提示用户输入学生个数、学生姓名和他们的成绩,然后按照学生成绩的降序打印学生的姓名。假定姓名是不包含空格的字符,使用next()读取
  7. 1+X web中级 Laravel学习笔记——使用DB facade对数据库进行增删改查
  8. 力扣452 用最少的箭引爆气球(个人感悟向,非完整代码)
  9. 让你人见人爱的27个原则
  10. SQLite入门与分析(四)---Page Cache之事务处理(1)
  11. proxmox 控制台无法连接_Proxmox VE 5的SPICE控制台和虚拟机声音设置
  12. [解题报告]102 - 生态装箱 时间限制:3.000秒
  13. Kibana 自定义索引模式 Index patterns
  14. c语言累加和校验_累加和校验算法(CheckSum算法)
  15. java中AWT如何关闭窗口_java 窗口关闭的六种方法
  16. Win XP 精简版安装SQL Server
  17. Android校准指南针,电子罗盘的工作原理及校准 电子罗盘,电子指南针,android.docx...
  18. 计算机打开查看方式默认是什么样,win10图片打开方式里没有默认照片查看器的解决方法...
  19. 计算机组成原理保姆级复习资料
  20. 推荐书籍 《半小时漫画经济学1--生活常识篇》

热门文章

  1. 芯片技术---芯片到底是什么?
  2. 文献解读-物理信息深度学习(PINN)
  3. Ps 2022 版新增功能及改进
  4. 从二维码图片到镂空二维码stl模型(1)
  5. 没能躲开的云服务容器网络问题
  6. 计算机无法正常更新,电脑时间不能自动更新怎么回事?电脑时间校准同步方法介绍...
  7. excel选中指定行数
  8. c语言jt808协议库,部标JTT808协议快速开发包
  9. marlin固件烧录教程_marlin固件中文(marlin固件下载)
  10. Win10访问Linux分区