基于Python实现的DES加密算法

基于Python实现的DES加密算法 一,算法描述 DES算法是利用56 + 8奇偶校验位 = 64位的密钥对以64位为单位的数据块进行加密和解密

本文包含相关资料包-----> 点击直达获取<-------

基于Python实现的DES加密算法

一、算法描述

DES算法是利用56 + 8奇偶校验位 = 64位的密钥对以64位为单位的数据块进行加密和解密。它的加密与解密实现首先是要生成一套加密密钥,用户输入一个64位长的密码,然后通过等分、移位、选取和迭代形成一套16个加密密钥,分别用于之后的每一轮运算。

1.1 加密

DES对以64位(bit)为单位的明文分组M进行操作,M经过初始置换IP,成为M0 。将M0明文分为左半部分和右半部分,M0 = (L0 ,R0 ),各32位长。然后进行16轮完全相同的迭代运算,即 Feistel 轮函数;在每一轮运算过程中数据与相应的密钥结合进行操作。

每一轮轮函数运算中,密钥位移位,然后再从密钥的56位中选出48位。通过一个扩展置换将数据的右半部分扩展成48位,并通过一个异或操作替代成新的48位数据,再将其压缩置换成32位。做完这些操作后,通过另一个异或运算,轮函数的输出与左半部分结合,其结果成为新的右半部分,原来的右半部分成为新的左半部分。此操作重复16次,最后输出R16L16。

根据L0R0按照下述规则进行16次迭代,即

至此,16轮迭代结束后,左右部分结合在一起后,再经过一次IP逆置换,加密过程结束。

1.2 解密

DES解密并不是加密过成的逆运算,而是与加密算法相同算法。唯一的不同是密钥的次序相反,加密时是K1K2...K16的顺序,解密时为K16K15...K1的顺序

二、总体结构

输入64位明文M时,子密钥调度次序按照K1K2...K16的顺序调度,为加密过程;

输入64位密文时,子密钥按K16K15...K1次序调度,为解密过程。

三、代码实现

在此算法的实现中,我使用python是因为其中的List这种数据类型,用这种类型的数据结构存放在算法中要用到的IP置换表,IP-1置换表,8个S盒,P盒以及⽐特-选择表(E-扩展规则)等,python中对这些List的转换、移位操作⾮常⽅便,而不用像c,c++中那样构造⼆维数组。

代码由两个todo.py和go.py两部分构成。其中todo.py主要实现算法中各种表的置换、数据类型的转换以及子密钥的生成和其他一些功能函数;go.py中主要实现算法的具体运算,包括加密与解密,以及输入等操作。

3.1 初始化部分

两个IP置换表的实现

```python

初始IP置换表

def IpTable(text): 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] return [text[IP[i] - 1] for i in range(64)]

逆初始IP置换表

def InvereIpTable(text): INVERSE_IP = [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]

return [text[INVERSE_IP[i] - 1] for i in range(64)]

```

⼆进制的明文块,通过置换后重排明文块的⼆进制串

子密钥的生成

```python

PC_1变换和PC_2变换

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]

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]

子密钥的生成

def createSubKey(preKey): result = [] key56 = [preKey[PC_1[i]-1] for i in range(56)] # 对56个非校验位进行PC_1置换

step = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1]  # 移动的步长

for i in range(16):
    key_left = move(key56[:28], step[i])
    key_right = move(key56[28:], step[i])
    key56 = key_left + key_right
    key48 = [key56[PC_2[i]-1] for i in range(48)]
    result.append(key48)
return result

def move(text, times): return text[times:] + text[:times] ```

3.2 轮函数部分

E-扩展

```python

E扩展置换

def E_extend(text): 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 [text[E[i] - 1] for i in range(48)] ```

S-盒置换

```python

s盒置换,将48位输入均分成长度为6的8个小组,每个小组按顺序进入相应的S盒各得到4位输出,返回合并后的32位结果。

def s_box_change(text): result = [] for i in range(0, 8): temp = text[i 6:(i+1) 6] row = int(str(temp[0])+str(temp[-1]), 2) col = int(str(temp[1])+str(temp[2])+str(temp[3])+str(temp[4]), 2) message = S_box[i][row][col] result.append(dec2bin4(message))

return [int(x) for x in ''.join(result)]

```

P-盒置换

```python

P-盒置换:将32位输入按 P 规则置换后返回32位结果。

def p_box_change(text): 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 [text[P[i] - 1] for i in range(32)]

```

异或

```python

异或操作, 对序列进行各位异或操作,并返回所有结果

def xor(m, n): return [a ^ b for a, b in zip(m, n)] ```

F函数

python for i in range(16): l, r = text[:32], text[32:] r_extend = E_extend(r) # 对右半部分进行E扩展运算,转换成48位对串 xor1 = xor(r_extend, subkeys[i]) # 对得到对48位串与48位对子密钥进行异或运算 s_box_result = s_box_change(xor1) # 异或得到对结果进行S盒转换 p_box_result = p_box_change(s_box_result) # p置换,得到轮函数的输出 xor2 = xor(l, p_box_result) # 将左半部分与轮函数输出做异或,得到新串对右半部分 text = r + xor2 # 左右部分结合,形成新串

3.3 算法实现部分

```python

算法实现

def cipher(message, key, mode='encrypt'): # 初始化明文和密钥,将其转化为二进制串 message = string2bin(message) key = string2bin(key) # 子密钥的生成,当mode为'decrypt'时,反转子密钥序列 subkeys = createSubKey(key) if mode == 'encrypt' else createSubKey(key)[::-1] text = IpTable(message)

for i in range(16):
    l, r = text[:32], text[32:]
    r_extend = E_extend(r)  # 对右半部分进行E扩展运算,转换成48位对串
    xor1 = xor(r_extend, subkeys[i])  # 对得到对48位串与48位对子密钥进行异或运算
    s_box_result = s_box_change(xor1)  # 异或得到对结果进行S盒转换
    p_box_result = p_box_change(s_box_result)  # p置换,得到轮函数的输出
    xor2 = xor(l, p_box_result)  # 将左半部分与轮函数输出做异或,得到新串对右半部分
    text = r + xor2  # 左右部分结合,形成新串

text = text[32:] + text[:32]
# print(InvereIpTable(text))
# 将二进制密文串转换为字符串返回
return bin2string(InvereIpTable(text))

```

考虑到用户输入的明文不一定都满足规定的位数,所以需要对输入的明文进行一定的操作,对于不满足要求的进行补位操作。

python def fill(string): # 如果二进制串的位数不是8的倍数,则用补满空缺位数 mod = len(string) % 8 space = 8 - mod return string + bytes(space).decode('utf-8')

DES类的封装

```python class DES: def init (self, message, key): self.message = message self.key = key

@property
def ciphertext(self):  # 密文
    return self.__encrypt()

@property
def plaintext(self):  # 明文
    return self.__decrypt()

def __encrypt(self):  # 加密
    output = []
    length = len(self.message)
    # 按64bit为一组(8bytes)进行切分
    times, mod = length // 8, length % 8
    if mod:  # 补位
        self.message = fill(self.message)
        times += 1
    # 对明文对每一组进行操作
    for i in range(times):
        result = cipher(self.message[i * 8:i * 8 + 8], self.key, 'encrypt')
        output.append(result)

    return ''.join(output)

def __decrypt(self):  # 解密
    output = []
    length = len(self.message)
    times, mod = length // 8, length % 8

    if not times:
        return None

    if mod:
        self.message = fill(self.message)
        length += 1

    for i in range(times):
        result = cipher(self.message[i * 8:i * 8 + 8], self.key, 'decrypt')
        output.append(result)

    return ''.join(output).rstrip(b'\x00'.decode('utf-8'))

```

main函数

```python if name == ' main ':

mess = input("请输入需要加密的内容:")
key = input("请输入密钥:")
while len(key) != 8:
    print("请输入八字节字符的密钥,请重新输入:")
    key = input()
cipher1 = DES(mess, key)
print("秘文:"+cipher1.ciphertext)

cipher2 = DES(cipher1.ciphertext, key)

print("解密后的明文:"+cipher2.plaintext)

```

四、运行结果

  • 测试明文 :I love DES so much.

  • 密钥 :1234abcd

当密钥长度不为8时,会有错误提示,如果加密解密不使用同一密钥,则解密得到的明文与原明文不同。

参考文献

  • 基于同态加密智能合约的电力数据安全共享方案研究与实现(哈尔滨工业大学·林英杰)
  • 银行信息安全系统的设计与实现(北京邮电大学·贺兴华)
  • 基于区块链的去中心化匿名电子检举系统(华南农业大学·陈益康)
  • 基于数据挖掘的二维码防伪防窜货系统分析与设计(北京邮电大学·陈贵川)
  • 基于B/S架构的企业内部管理系统的设计与实现(昆明理工大学·高张宝)
  • 基于B/S架构的企业内部管理系统的设计与实现(昆明理工大学·高张宝)
  • 基于J2EE的数据库加密技术的研究(合肥工业大学·许磊)
  • 面向云际计算场景的数据解密权限让渡技术研究(国防科技大学·相亮亮)
  • 基于DES和RSA算法的数据加密传输系统的设计和实现(苏州大学·朱作付)
  • 基于切片优化的星际文件系统加解密方法(南京邮电大学·周长松)
  • 基于数据挖掘的二维码防伪防窜货系统分析与设计(北京邮电大学·陈贵川)
  • 基于加密算法的软硬件协同设计与实现及云安全存储研究(广东工业大学·刘祥)
  • 支持内容关联密钥技术的密钥管理系统优化研究(华中科技大学·郑杨杰)
  • 基于B/S架构的企业内部管理系统的设计与实现(昆明理工大学·高张宝)
  • 基于B/S架构的企业内部管理系统的设计与实现(昆明理工大学·高张宝)

本文内容包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主题。发布者:代码项目助手 ,原文地址:https://bishedaima.com/yuanma/35506.html

相关推荐

发表回复

登录后才能评论