C++ DES

2025年3月17日 | 阅读 14 分钟

引言

信息时代的到来产生了海量的数据。由于需要保护人们的隐私,保护敏感信息变得越来越重要。因此,信息在网络传输和系统内存存储过程中的保护方式受到了越来越多的重视。

DES (数据加密标准)算法由 IBM 开发。它是一种对称密钥技术,基于 Horst Feistel20 世纪 70 年代科学技术发展初期提供的一种较旧的算法。对称密钥算法使用相同的密钥来加密和解密消息和密文。该算法被提交给 美国国家标准局

在与 美国国家安全局(NSA)进行了讨论后,DES 算法在 1976 年进行了一些修改。该算法随后被选定,并于 1977 年在美国正式公布为 联邦信息处理标准(FIPS)

描述 DES 算法。

数据加密标准算法是一种 分组密码方法,它使用 48 位密钥对每个输入进行处理,一次将 64 位的明文块转换为 64 位的密文块。需要加密的文本被分成称为 “块”的单元,并且在分组密码技术中,每个块都使用密钥单独加密。

在解密步骤中,加密过程被完全逆转。使用与加密过程中相同的 48 位密钥,它接收一个 64 位的密文块并输出一个 64 位的明文块。为了能够相互通信,加密者解密者必须使用相同的密钥。

DES 算法在互联网早期取得了成功,但由于其 56 位的密钥长度不足,如今的应用已无法使用。随着技术的发展和处理能力的提高,有决心的攻击者可以使用正确的工具快速破解密钥。然而,它对密码学的发展产生了重大影响。

如何生成密钥

字母数字不被计算机使用。在加密之前,所有明文字符都被转换为二进制。在加密过程中,数据被分成块进行处理。DES 算法将二进制明文分成每块 64 位,从而产生 64 位的块大小。

在进行任何其他操作之前,如果最后一个块的长度不足 64 位,则会对其进行填充。填充可确保块中包含额外数据以增加其长度至 64 位。填充可以确保加密数据更难解密。

为了防止攻击者仅凭算法预测明文,密钥被用来改变加密操作的结果。

在 DES 中,使用单个密钥来创建在每个 “轮次”中使用的后续密钥。DES 算法应用 16 次来创建最终的 密文;每次应用都被称为一个轮次,其结果作为下一个轮次的输入。这使得明文混淆程度最大化。

现在,我们首先选择一个随机的 64 位值作为我们的密钥 K。请记住,为了通信,发送者和接收者都必须拥有相同的 64 位密钥

每个轮次都必须有一个 子密钥。这个子密钥对于该轮次是唯一的,并且是我们在开始时建立的主密钥 K 的一个置换。为每个轮次生成一个子密钥,总共生成 16 个子密钥。它们用 K1K16来标识。

密钥首先使用 置换选择-1(PC-1)表进行置换,以创建我们的轮密钥。下面的 PC1 表将用于重新排序我们数据块的组件。

数据块的 “左”“右”半部分分别用字母 “C”“D”表示。表中的数字决定了输入密钥的哪些位进入密钥调度状态的左侧或右侧部分。

C

57494133251709
01585042342618
10025951433527
19110360524436

D

63554739312315
07625446383022
14066153453729
21131328201204

表格:- PC1

原始密钥的每一位都根据表格进行移动和重新分配。原始密钥的第 57 位将进入表 “C”的第一个单元格,因为它包含值 57。我们新密钥的第二位将是前一个块的第 49 位,因为第二个单元格显示数字 49。按照表 “C”的顺序放置旧块的其余整数,以创建我们的新密钥。在按照表 “C”的顺序放置完块后,我们继续处理表 “D”以完成我们新密钥的第二半部分。

您可能已经注意到,表和密钥的长度只有 56 位,而不是 64 位。这是因为每第八位(8、16、24、32、40、48 和 56)被指定用作奇偶校验位,以确认密钥已成功接收。这些奇偶校验位使 DES 算法具有 56 位密钥的实际安全性。

现在,我们将 56 位密钥分成 两半,每半长 28 位。这将在接下来的步骤中作为我们的指导。

之后,根据轮次号,密钥向左移动一位或两位。下表提供了确切的移动位数。

在这些轮次中,数字会按照表中列出的距离向左移动,每个移位都应用于前一轮的结果。

例如,如果我们处于第 次加密轮次,并且我们的密钥是 1101101101101101,表格显示我们必须将其左移两位。因此,我们在此轮次后的密钥将是: 0110110110110111

因此,生成了十六个不同的 子密钥,每个 DES轮次一个。之后,密钥使用提供的 置换选择-2 表进行置换。现在,我们根据下表再次重新排列密钥中的位。

密钥的排列方式与之前的置换类似,以便新密钥的位置由表格所示确定。

表:PC2

141711240105
032815062110
231912042608
160727201302
415231374755
304051453348
444939563453
464250362932

因此,密钥的第 14 位被放置在新置换密钥的第一个位置,第 17 位被放置在第二个位置,依此类推。进一步检查会发现,新生成的密钥只有 48 位,而之前的密钥是 56 位

DES 算法中的加密过程

初始置换函数

就像我们对密钥所做的那样,明文被分成 64 位的块。需要加密并从发送者发送到接收者的信息称为 明文。如果最后一个块的长度小于所需的 64 位,也会对其进行填充。

在进行任何处理之前,文本会通过初始置换函数进行混淆。初始置换,或 IP,在密码学方面没有重要意义。

二进制编码消息的位按照 初始置换表进行排序,并且置换过程与我们对密钥进行的操作类似。此步骤的输出将作为下一个步骤的输入。

块拆分

当 IP 过程完成后,块被分成两部分:一个由 32 位组成的 左块 L0和一个也由 32 位组成的 右块 R0

在块拆分后,我们继续进行下一个函数。在 第一轮中,取右半部分块并进行以下处理:

  1. 扩展置换 (E)
  2. 密钥混合
  3. 替换 (S1, S2,...,S8)
  4. 置换 (P)

A) 扩展置换 (E)

扩展置换实现了三个目标,其中之一是雪崩效应,即两个不同位的输出直接受到一个输入数据位的影响。为了与下一步的子密钥长度相同,此步骤还确保右半部分具有 48 位

雪崩效应的案例研究

扩展置换的另一个重要结果是,通过增加输出相对于输入的长度,在替换操作期间压缩数据。

之后,使用下面的扩展函数表重新排列块。

通过深入研究,我们可以看到表包含几个重复的块。结果,块将从 32 位增加到 48 位

表:E

320102030405
040506070809
080910111213
121314151617
161718192021
202122232425
242526272829
282930313201

B) 密钥混合 ()

在将 块扩展48 位之后,我们应用了我们从先前的密钥调度中获得的第一个轮次的 子密钥。之后,使用 XOR 表子密钥来修改块。

例如,如果扩展密钥的最后八位是 01001011,则密钥混合步骤后的密钥将是: 10110100

结果块将进入下一阶段。

C) 替换 (S)

替换用于增加数据的复杂性,使其更难理解。每个 6 位输入通过 8 个预构建的表(称为 替换框S-Box)转换为 4 位输出。

6 位输入中提取 MSBLSB,并将其转换为十进制数 X。此数字提供 S-Box的行号,即 X。之后,将输入的中间 四位转换为十进制数 Y。我们通过 Y数字为查找提供列号。之后,将相应的 S-Box数字转换为 4 位二进制数。因此,我们成功地将 6 位输入转换为 4 位输出。

D) 置换 (P)

F 函数再次使用下面的置换 P 表进行置换。

现在,我们完成了 F 函数的所有阶段。我们获得的加密数据具有一个称为 f(R0, K1)的数学值。它表示结果取决于第一轮的 子密钥块 R0的初始右侧。

现在,我们将此值进行处理,并执行后续操作。

i) 与左块进行 XOR 运算

接下来,使用我们之前留下的块的左半部分和上一轮置换获得的 f(R0,K1)块,我们进行 XOR 运算。现在我们有了 R1,这是初步处理的结果。

ii) 再进行 15 次

将上述 3 个过程重复 15 次,以完成 16 轮处理。块的处理过程如下图所示。

Des in C++

iii) 最终置换

使用提供的 f(R0, K1) 表,对最后一轮的结果进行最后一次置换。在这种情况下,表 f(R0,K1)是初始表 P的逆。由 DES 算法生成的 密文是此逆置换表的最终产物。

DES 算法中的解密过程

现在,我们将介绍 DES 解密过程。

该算法具有 Feistel 结构,这有助于简单的解密。加密和解密过程之间的唯一区别是,在解密过程中 子密钥的使用顺序是相反的。

数据经过第一个置换 P 后被分成两部分。F 函数继续处理右半部分。但是,这次使用了第 16 个子密钥,其余过程照常进行。一旦获得 F 函数的结果,就将结果块的左侧与 XOR。通过反向取用子密钥,重复该过程。经过第 16 轮后,最终获得明文。

Des in C++

DES 的操作模式

虽然 DES 算法可以加密明文,但其有效的密钥长度较短,使其容易受到各种暴力破解攻击。尤其是在现代世界,云计算和超级计算机提供的处理能力远远超过 20 世纪 70 年代设计 DES 时可用的计算机。

因此,DES 算法在实际应用中与各种操作模式结合使用,具体取决于应用和用途。

以下是一些基本的操作模式:

电子密码本 (ECB)。

输入明文的每个块直接用 DES 算法加密,以生成一个密文块。

Des in C++

密文块链 (CBC)

它在安全性方面是 ECB的改进。在这种情况下,在与明文进行 XOR 运算后,前一个密文块被作为输入提供给下一个加密周期。


Des in C++

CFB(密文反馈模式)

在此模式下,初始化向量 (IV)是一个唯一的变量。它用于启动加密过程。IV用于初始加密,而早期加密的输出是所有后续加密的输入。

每轮的输出在左右两边分别均等地分成 s 位b 位。然后,下一轮加密使用 s 位与明文进行 XOR 运算。

OFB(输出反馈模式)

DES 与密码块链的区别仅在于,输出被提供给下一轮作为反馈,而不是 s 位

DES 算法实现和测试

DES 算法使用以下 C++ 代码实现:

1) 生成密钥

该技术在其 16 轮加密过程中使用了 16 个不同的子密钥。

输出

Key 1: 000110010100110011010000011100101101111010001100
Key 2: 010001010110100001011000000110101011110011001110
Key 3: 000001101110110110100100101011001111010110110101
Key 4: 110110100010110100000011001010110110111011100011
Key 5: 011010011010011000101001111111101100100100010011
Key 6: 110000011001010010001110100001110100011101011110
Key 7: 011100001000101011010010110111011011001111000000
Key 8: 001101001111100000100010111100001100011001101101
Key 9: 100001001011101101000100011100111101110011001100
Key 10: 000000100111011001010111000010001011010110111111
Key 11: 011011010101010101100000101011110111110010100101
Key 12: 110000101100000111101001011010100100101111110011
Key 13: 100110011100001100010011100101111100100100011111
Key 14: 001001010001101110001011110001110001011111010000
Key 15: 001100110011000011000101110110011010001101101101
Key 16: 000110000001110001011101011101011100011001101101

2) 明文加密生成密文

需要加密的明文被分成两个相等的 半部分,并经过 16 轮加密。之后,通过组合它们来生成密文。

输出

Plaintext: 1010101111001101111001101010101111001101000100110010010100110110
Ciphertext: 1001111000100110100111110101101011111010010011011011101101110000