DES加密
DES加密简介
DES加密算法是对称密钥加密算法、分组加密算法。
DES(Data Encryption Standard,数据加密标准)的出现是现代密码发展史上的一个非常重要的事件,它是密码学历史上第一个广泛应用于商用数据保密的密码算法,开创了公开密码算法、公开竞选密码算法的先例,极大地促进了密码学的发展。尽管AES取代它成为新的数据加密标准,但使用诸如3重DES等方法加强DES密钥强度仍然不失为一个安全的密码系统。因此,DES算法的基本理论和设计思想仍有重要的参考价值。
在国内,DES在POS、ATM、磁卡以及智能卡、高速公路收费站等领域有广泛的应用,如信用卡持卡人的PIN加密传输,IC卡与POS之间的双向认证、金融交易数据包的MAC校验等等。
DES的加密和解密使用的是同一算法,安全性依赖于所用的密钥。DES算法仅使用最大为64比特的标准算术和逻辑运算,运算速度快,密钥产生容易,适合于在计算机上软件实现或专用芯片实现。
曾经在其时间内提供了相对较高的安全性,但由于密钥长度受限以及密码分析技术的进步,它已经不再被认为足够安全,在现代通信和数据安全领域不再广泛使用。
主要特点如下:
-
分组加密
DES采用固定的64位数据块进行加密,需要将数据划分成特定大小的块进行处理。 -
对称密钥加密
DES采用相同的密钥进行加密和解密操作,密钥长度为56位,实际用于加密的位数为48位。 -
多种混淆
采用多种替代和置换操作,包括初始置换、轮函数、扩展置换、S-盒替代和P-盒置换,以混淆和替换数据块中的位。 -
轮函数
DES包括16轮轮函数,每一轮都使用不同的子密钥对数据块进行变换,增加算法的复杂性和安全性。 -
密钥长度较小
DES的密钥长度相对较小(56bit),导致容易受到暴力破解攻击。DES的密钥长度为56位。密钥实际长度为64位,但第8、16、24、40、48、56和64位为奇偶校验位,故使用时的实际有效长度为56位。虽然密钥空间包含2^56种不同的密钥组合,但随着计算能力的增强,暴力破解攻击变得更加可行。现代计算机可以以很高的速度尝试不同的密钥组合,因此56位密钥的保护已经不足以抵御强大的计算资源。
DES加密基本原理
基本流程
DES的基本流程图如下图所示:
其中IP置换后直接将数据从中间一分为二得到\(L_0\)和\(R_0\)(64bit变为32bit),在最后将\(R_{16}\)和\(L_{16}\)首尾相接得到数据再进行IP逆置换(32bit变为64bit)。
初始置换IP表如下图
逆初始置换表如下图
轮函数
轮函数是对称密钥加密算法中的一个关键组成部分,用于将输入数据转化为输出数据。这里我将详细介绍轮函数的原理以及每一步的操作方法:
- 扩展置换:
-
原理:扩大数据块的大小,增加数据的复杂性,从而提高密码的安全性。将输入数据的某些位复制,将输入数据块(32bit)扩展为48位。使密文的每一位更加依赖明文和密钥的每一位,实现了扩散原则。
-
操作方法:输入数据块中的每一位根据一个预定义的置换表(EXPANSION)被复制和重新排列,生成一个更大的数据块(48位)。这个置换表定义了每个输入位应该被复制到扩展数据块的哪个位置,以及是否需要重复。
-
EXPANSION表如下图:
-
扩展示意图:
-
-
子密钥异或:
-
原理:初始密钥经过一系列操作生成一组轮密钥,每轮使用一个不同的轮密钥,一共有16个轮密钥,分别用于16轮加密。在每轮中,扩展置换后的数据与对应轮的轮密钥进行按位异或操作。将密钥的影响混合到数据中,增加密码的变化性和安全性。
-
操作方法:对每个位,将扩展置换后的数据位与对应位的轮密钥位执行异或运算。
-
轮密钥生成详细过程见“密钥k生成”部分。
-
-
S-盒替换:
-
原理:S-盒是一种非线性替代函数,它将一组输入位映射到一组输出位。S-盒替换是DES中的核心部分,它引入非线性性,将6位的输入映射到4位的输出,每个S盒由一个4行16列的表组成,可以增加数据的混乱度,增强密码的非线性特性。
-
操作方法:将异或后的48位数据分成8组,每组6位,分别放入8个S-盒进行代换。每个S-盒通过查找表将6位输入映射为4位输出,替换每个6位块,得到32位输出。
-
8个S-盒数据见代码S_BOXES部分。
-
详细置换过程:
-
使用S1作为示例S-盒:
-
假设输入数据为
110110101011
,它被分成8个6位的块,每个块分别是:110110
、101011
。首先分别对这两个块进行S1的替换: -
STEP1:对第一个块
110110
的S-盒替换:- 行号(row)计算:第1位和第6位为
11
,这对应行号3
。 - 列号(col)计算:第2位到第5位为
1011
,这对应列号11
。 - 在S1的S-盒中,第3行和第11列的交叉点的值是
5
。 5
转化为4位二进制为0101
。
- 行号(row)计算:第1位和第6位为
-
STEP2:对第二个块
101011
的S-盒替换:- 行号(row)计算:第1位和第6位为
11
,这对应行号3
。 - 列号(col)计算:第2位到第5位为
0101
,这对应列号5
。 - 在S1的S-盒中,第3行和第5列的交叉点的值是
0
。 0
转化为4位二进制为0000
。
- 行号(row)计算:第1位和第6位为
-
现在有了两个S-盒替换后的结果:
- 第一个块替换后为
0101
- 第二个块替换后为
0000
- 第一个块替换后为
-
将这两个结果拼接在一起,得到最终的32位输出数据块为
01010000
。
-
-
-
P-盒置换:
-
原理:重新排列32位数据块的位,增加数据的扩散性,为下一轮的轮函数准备数据。将数据再次混淆,以增加密码的安全性。
-
操作方法:对32位数据块中的每一位根据一个预定义的置换表(P_BOX)进行重新排列。
-
P-盒数据如下图所示:
-
P盒的设计的特点:
①每个S盒的4位输出影响下一轮6个不同的S盒,但是没有2位影响同一S盒;
②在第i轮S盒的4位输出中,2位将影响i+1轮中间位,其余2位将影响两端位;
③如果一个S盒的4位输出影响另一个S盒的中间的1位,则后一个的输出位不会影响前面一个S盒的中间位。
-
轮函数具体流程如下图所示:
密钥k生成
在DES加密算法中,密钥生成是关键的步骤之一,它通过对主密钥进行置换、左移操作和再次置换,生成16轮加密所需的子密钥。下面是生成子密钥的简要描述:
-
初始密钥置换:
-
原理:使用置换表PC1对主密钥进行置换,将64位的主密钥压缩为56位。去除主密钥中的奇偶校验位,以及排列密钥位的顺序。
-
操作方法:主密钥的每一位根据置换表PC1被复制和重新排列,生成一个56位的中间密钥。
-
-
分成左右两部分:
-
原理:将初始的56位密钥分成两个28位的部分,通常称为左半部分和右半部分。
-
操作方法:将中间密钥的前28位作为左半部分,后28位作为右半部分。
-
-
子密钥生成:
- 原理:首先,使用包含16个不同的左移位数的SHIFT_SCHEDULE数组,每轮使用一个不同的左移数来生成子密钥。其次,左移操作将左半部分和右半部分的位数进行循环左移,根据SHIFT_SCHEDULE中的指定位数。通过循环移位和置换,DES的密钥调度方法确保了原密钥中各位的使用次数基本上相同。然后,将左半部分和右半部分重新组合成56位的中间密钥,再次使用一个置换表(PC2)对中间密钥进行置换,得到48位的子密钥。**最后,重复这个操作16次,每次生成一个不同轮次的子密钥。
- 操作方法:
- 对左半部分和右半部分分别执行左移操作,左移位数由SHIFT_SCHEDULE数组决定。
- 合并左半部分和右半部分,得到56位的中间密钥。
- 使用置换表PC2对中间密钥进行置换,生成48位的子密钥。
- 重复这个过程16次,每次生成一个不同的子密钥。
轮密钥生成的过程图:
DES加密主函数(以及解密主函数)
加密主函数包含以下步骤:
-
初始置换:将明文进行IP初始置换,将数据重新排列成64位的形式。
-
生成子密钥:根据输入的初始密钥,生成16个轮次所需的子密钥。
-
数据分割:将初始置换后的数据分成左右两部分,每部分32位。
-
16轮加密:循环执行16轮加密过程,每轮中:
a. 右半部分和子密钥一起放入轮函数生成轮输出。
b. 将轮输出与左半部分进行异或操作,生成新的右半部分。
c. 更新左半部分和右半部分,将左半部分设为之前的右半部分,右半部分设为新的右半部分。
-
数据合并:将左半部分和右半部分合并成一个64位的数据块。
-
逆初始置换:对合并的数据块进行IP_INV逆初始置换,得到最终密文。
密钥加密流程如下图所示:
DES在解密时,根据对称加密的基本原则,通过将加密相同密钥应用于密文,但以相反的顺序应用相同的变换和操作,可以确保解密的逆操作,从而还原明文。
解密函数与加密函数唯一不同的地方是,在进行轮函数中的异或时,加密函数正向遍历轮密钥进行异或,解密函数相反(从第16个轮密钥开始异或)。
DES加密的破解
DES可以通过以下方式进行破解:
-
暴力破解
通过尝试所有可能的密钥组合来解密DES加密消息。由于DES密钥长度为56位,暴力破解需要尝试2^56个不同的密钥。需要大量计算资源和时间,因此在实践中通常不使用。 -
差分密码分析
基于已知明文和对应密文之间的差异进行攻击。攻击者通过比较不同密钥下的差异,试图获得有关密钥的信息。虽然这种方法比暴力破解更有效,但它仍然需要大量的计算和数据。 -
线性密码分析
基于线性逼近进行攻击,通过构建密钥与明文和密文之间的线性关系来尝试破解密钥。它通常需要更多的已知明文-密文对。 -
针对弱密钥的攻击
DES有一些弱密钥和半弱密钥,这些密钥在加密中表现出特定的性质,可能容易受到攻击。攻击者可以尝试利用这些性质来减少破解的难度。 -
针对多轮DES的攻击
在多轮DES中,可以尝试针对每一轮的子密钥,逐步获取主密钥的信息。需要大量的计算分析。 -
生日攻击
攻击者可以使用生日攻击来找到两个不同的密钥,这两个密钥都可以加密相同的明文,从而推断原始明文。
其他还有工作密钥攻击等方法。
多重DES
多重DES(Triple Data Encryption Standard)是DES(Data Encryption Standard)的一种变种,旨在提高加密的安全性,通过多次应用DES算法来增加密钥长度和加密强度。它使用三个独立的DES算法来连续加密数据。
多重DES主要模式有以下两种:
-
2-DES:
- 2-DES使用两次独立的DES加密过程来加密数据。
- 首先,明文数据被用一个DES密钥进行加密。
- 然后,密文再次被用另一个DES密钥进行加密,这个过程涉及两个不同的密钥。
- 2-DES的密钥长度为112位(两个56位的密钥),相对于原始DES的56位密钥,它提供了更高的安全性。
- 加密过程可以表示为:
C = E(K2, D(E(K1, P)))
,其中C是密文,E代表加密,K1和K2是两个DES密钥,D代表解密,P是明文。
-
3-DES:
- 3-DES使用三次独立的DES加密过程来加密数据。
- 明文首先被用一个DES密钥进行加密,然后再用另一个DES密钥进行解密,最后再用第三个DES密钥进行加密。
- 3-DES的密钥长度为168位(三个56位的密钥),相对于原始DES,它提供了更高的加密强度。
- 加密过程可以表示为:
C = E(K3, D(E(K2, E(K1, P)))
,其中C是密文,E代表加密,K1、K2和K3是三个DES密钥,D代表解密,P是明文。 - 3-DES提供更高的安全性,因为它涉及更多的加密和解密轮次,而且密钥空间更大。
多重DES的主要优点是保留了DES算法的结构和算法,同时增加了密钥长度,从而提高了安全性。缺点是需要多次执行DES加密和解密操作,速度较慢。
DES加密解密实现
python代码
'''
20231022
skdtxdy
# 初始置换IP
# 逆初始置换IP_INV
# 初始密钥置换PC1
# 循环左移位数表SHIFT_SCHEDULE
# 子密钥置换PC2
# S-盒S_BOXES
# 扩展置换EXPANSION
# P盒P_BOX
'''
# 初始置换IP
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
IP_INV = [
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
]
# 循环左移位数表
SHIFT_SCHEDULE = [
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
]
# 初始密钥置换PC-1
'''
PC-1是用于从初始密钥中生成56位的中间密钥(C0和D0)的置换表。
它从64位的初始密钥中筛选出56位,并丢弃了8位奇偶校验位。
这个置换是DES算法中的第一步,用于准备子密钥生成。
'''
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
'''
PC-2是用于从56位中间密钥生成每一轮的48位子密钥的置换表。
在DES中,子密钥是通过对中间密钥进行轮次迭代和置换生成的。
PC-2负责选择并排列中间密钥的位,以生成48位的子密钥。
'''
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
]
# S-盒
S_BOXES = [
# 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]
]
]
# 扩展置换 E置换
EXPANSION = [
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-盒
P_BOX = [
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
]
def text_to_binary(text):
binary_data = [int(bit) for char in text for bit in format(ord(char), '08b')]
return binary_data
# 生成密钥校验位
def add_parity_bits(key_without_parity):
key_with_parity = []
for i in range(0, 56, 7):
# 从每7位中计算奇偶校验位
key_chunk = key_without_parity[i:i + 7]
parity_bit = key_chunk.count(1) % 2 # 计算1的数量
key_chunk.append(1 - parity_bit) # 添加奇偶校验位
key_with_parity.extend(key_chunk)
return key_with_parity
# 左移位操作
def left_shift(bits, shift):
return bits[shift:] + bits[:shift]
# 通用置换函数
def permutation(data, table):
return [data[i - 1] for i in table]
# 生成16个子密钥的函数
'''
首先进行初始密钥置换(PC-1表),然后将密钥分为左右两部分,并根据循环左移位数表(SHIFT_SCHEDULE)进行左移操作。
接着,将左右两部分合并,再进行子密钥置换(PC-2表),最终得到一个子密钥。这个过程重复16次,生成所有的子密钥。
'''
def generate_subkeys(key):
# 初始密钥置换
key = permutation(key, PC1)
# 分成左右两部分
left_half = key[:28]
right_half = key[28:]
subkeys = []
for i in range(16):
# 左移操作
left_half = left_shift(left_half, SHIFT_SCHEDULE[i])
right_half = left_shift(right_half, SHIFT_SCHEDULE[i])
# 合并左右两部分
combined_key = left_half + right_half
# 子密钥置换PC-2
subkey = permutation(combined_key, PC2)
subkeys.append(subkey)
return subkeys
# S-盒替换函数
def s_box_substitution(data):
s_box_output = []
for i in range(8):
# 分割为6位块
chunk = data[i * 6:(i + 1) * 6]
row = chunk[0] * 2 + chunk[5] # 行号
col = chunk[1] * 8 + chunk[2] * 4 + chunk[3] * 2 + chunk[4] # 列号
s_box_value = S_BOXES[i][row][col]
# 转为4位二进制
s_box_output.extend([(s_box_value >> j) & 1 for j in range(3, -1, -1)])
return s_box_output
# 轮函数
def round_function(data, subkey):
# 扩展置换
expanded_data = permutation(data, EXPANSION)
# 与子密钥异或
data_xor_subkey = [expanded_data[i] ^ subkey[i] for i in range(48)]
# S-盒替换
s_box_output = s_box_substitution(data_xor_subkey)
# P-盒置换
round_output = permutation(s_box_output, P_BOX)
return round_output
# 主DES加密函数
def des_encrypt(plain_text, key):
# 初始置换
plain_text = permutation(plain_text, IP)
# 生成16个子密钥,接受一个初始密钥作为输入,并返回一个包含16个子密钥的列表
subkeys = generate_subkeys(key)
# 分成左右两部分
left_half = plain_text[:32]
right_half = plain_text[32:]
for i in range(16):
# 执行轮函数
round_output = round_function(right_half, subkeys[i])
# 异或
new_right_half = [left_half[j] ^ round_output[j] for j in range(32)]
# 更新左右两部分
left_half = right_half
right_half = new_right_half
# 合并左右两部分
combined_data = right_half + left_half
# 逆初始置换
cipher_text = permutation(combined_data, IP_INV)
return cipher_text
# des解密函数
def des_decrypt(cipher_text, key):
# 逆初始置换
cipher_text = permutation(cipher_text, IP)
# 生成16个子密钥,接受一个初始密钥作为输入,并返回一个包含16个子密钥的列表
subkeys = generate_subkeys(key)
# 分成左右两部分
left_half = cipher_text[:32]
right_half = cipher_text[32:]
for i in range(16):
# 执行轮函数的逆操作
round_output = round_function(right_half, subkeys[15 - i])
# 异或
new_right_half = [left_half[j] ^ round_output[j] for j in range(32)] # 加解密唯一区别
# 更新左右两部分
left_half = right_half
right_half = new_right_half
# 合并左右两部分
combined_data = right_half + left_half
# 初始置换
plain_text = permutation(combined_data, IP_INV)
return plain_text
if __name__ == "__main__":
# 明文字符串
plain_text = "HelloWorld"
# 转换为二进制对应的整型数组
binary_plain_text = text_to_binary(plain_text)
# 计算需要填充零位的数量
remainder = 64 - len(binary_plain_text) % 64
# 将整数数组拆分成64位一组的二维整数数组,并在末尾添加零位
n = 64 # 定义每个子数组的长度
binary_plain_text_2d = [binary_plain_text[i:i + n] + [0] * remainder for i in range(0, len(binary_plain_text), n)]
# 密钥字符串(需要确保长度为56位)8位字符 64
key = "SecretKey"
# 转换为二进制对应的整型数组
binary_key = text_to_binary(key)
# 从整型数组中去掉每8个整型数据中的第8个
binary_key_partitioned = [int(bit) for binary_value in binary_key for i, bit in
enumerate(str(binary_value)) if i % 8 != 7]
# 添加奇偶校验位
key_with_parity = add_parity_bits(binary_key_partitioned)
cipher_texts = []
text = ""
# 加密
for i in range(len(binary_plain_text_2d)):
cipher_text_int = des_encrypt(binary_plain_text_2d[i], key_with_parity)
cipher_texts.append(cipher_text_int)
for i in range(len(cipher_texts)):
# 将整型数组转化为8位一组的二进制
binary_str = ''.join(map(str, cipher_texts[i]))
# 将二进制转化为字符串
text += ''.join(chr(int(binary_str[i:i + 8], 2)) for i in range(0, len(binary_str), 8))
# 加密后的字符串
print("字符串密钥(8位):")
print(key)
print("加密:")
print(text)
# //////////////////////////////////////////////// 解密
# 密文字符串
cipher_text = text
# 转换为二进制对应的整型数组
binary_cipher_text = text_to_binary(cipher_text)
# 计算需要填充零位的数量
remainder_2 = 64 - len(binary_cipher_text) % 64
# 将整数数组拆分成64位一组的二维整数数组,并在末尾添加零位
n_2 = 64 # 定义每个子数组的长度
binary_cipher_text_2d = [binary_cipher_text[i:i + n] + [0] * remainder_2 for i in range(0, len(binary_cipher_text), n_2)]
decrypted_binary_text = []
decrypted_text = ""
# 解密
for i in range(len(binary_cipher_text_2d)):
decrypted_binary_text.append(des_decrypt(binary_cipher_text_2d[i], key_with_parity))
for i in range(len(decrypted_binary_text)):
# 将整型数组转化为8位一组的二进制
binary_str = ''.join(map(str, decrypted_binary_text[i]))
# 将二进制转化为字符串
decrypted_text += ''.join(chr(int(binary_str[i:i + 8], 2)) for i in range(0, len(binary_str), 8))
# 解密后的明文
print("解密:")
print(decrypted_text)
运行结果测试
图片(流程图)来源于网络