分组密码基础(二):Feistel 结构与 DES 的设计思想

分组密码基础(二):Feistel 结构与 DES 的设计思想

    • 前言
    • [一、Feistel 结构:分组密码的经典范式](#一、Feistel 结构:分组密码的经典范式)
      • [1.1 从"单一大置换"到多轮迭代](#1.1 从"单一大置换"到多轮迭代)
      • [1.2 Feistel 网络的基本结构](#1.2 Feistel 网络的基本结构)
        • [1.2.1 单轮变换规则](#1.2.1 单轮变换规则)
        • [1.2.2 轮函数 F](#1.2.2 轮函数 F)
        • [1.2.3 多轮迭代与最终输出](#1.2.3 多轮迭代与最终输出)
      • [1.3 为什么 Feistel 是置换?](#1.3 为什么 Feistel 是置换?)
        • [1.3.1 证明单射(不会碰撞)](#1.3.1 证明单射(不会碰撞))
        • [1.3.2 证明满射(都能解密)](#1.3.2 证明满射(都能解密))
      • [1.4 核心性质:加解密对称性证明](#1.4 核心性质:加解密对称性证明)
        • [1.4.1 单轮的逆变换](#1.4.1 单轮的逆变换)
        • [1.4.2 多轮的逆变换](#1.4.2 多轮的逆变换)
        • [1.4.3 一个极其重要的推论](#1.4.3 一个极其重要的推论)
      • [1.5 Feistel 结构的优势与局限](#1.5 Feistel 结构的优势与局限)
    • [二、DES 算法概览](#二、DES 算法概览)
      • [2.1 诞生与标准化历程](#2.1 诞生与标准化历程)
      • [2.2 整体加密流程](#2.2 整体加密流程)
      • [2.2 整体加密流程](#2.2 整体加密流程)
    • [三、初始置换 IP 与逆初始置换](#三、初始置换 IP 与逆初始置换)
      • [3.1 IP 置换表与查表规则](#3.1 IP 置换表与查表规则)
      • [3.2 逆初始置换 IP⁻¹](#3.2 逆初始置换 IP⁻¹)
      • [3.3 设计意图与争议](#3.3 设计意图与争议)
    • [四、DES 轮函数深度拆解](#四、DES 轮函数深度拆解)
      • [4.1 轮函数整体结构与 E 扩展](#4.1 轮函数整体结构与 E 扩展)
      • [4.2 S 盒代换:DES 的非线性核心](#4.2 S 盒代换:DES 的非线性核心)
        • [4.2.1 查表规则(标准固定拆分方式)](#4.2.1 查表规则(标准固定拆分方式))
        • [4.2.2 S 1 S_1 S1 查表实操](#4.2.2 S 1 S_1 S1 查表实操)
        • [4.2.3 S盒硬性设计约束](#4.2.3 S盒硬性设计约束)
        • [4.2.4 S盒与差分抗性(攻击视角)](#4.2.4 S盒与差分抗性(攻击视角))
      • [4.3 P 置换与一轮完整流程](#4.3 P 置换与一轮完整流程)
        • [4.3.1 P 置换表](#4.3.1 P 置换表)
        • [4.3.2 一轮完整流程走查](#4.3.2 一轮完整流程走查)
    • 五、子密钥生成算法
      • [5.1 PC-1 置换:64 位到 56 位的密钥压缩](#5.1 PC-1 置换:64 位到 56 位的密钥压缩)
      • [5.2 循环左移:为什么每轮移位数不同?](#5.2 循环左移:为什么每轮移位数不同?)
      • [5.3 PC-2 置换:56 位到 48 位的子密钥选择](#5.3 PC-2 置换:56 位到 48 位的子密钥选择)
      • [5.4 16 轮子密钥完整生成流程](#5.4 16 轮子密钥完整生成流程)
    • [六、多重DES:DES 的兼容改进方案](#六、多重DES:DES 的兼容改进方案)
      • [6.1 双重 DES(2DES)](#6.1 双重 DES(2DES))
      • [6.2 三重 DES(3DES / TDEA)](#6.2 三重 DES(3DES / TDEA))
      • [6.3 3DES 的优劣与现状](#6.3 3DES 的优劣与现状)
    • [七、总结:Feistel 结构与 DES 的历史遗产](#七、总结:Feistel 结构与 DES 的历史遗产)
    • 免责声明

前言

在上一篇「分组密码基础(一)」中,我们建立了分组密码的基础框架:理解了为什么要分组、轮函数的核心地位,以及 ECB / CBC / CTR 等工作模式如何让定长置换处理任意长度的消息。

但有一个核心问题还没有回答:轮函数内部该怎么设计?一个安全的分组密码遵循什么样的设计原则?

现代分组密码的轮函数设计,最终收敛到了两条经典路线:

  • Feistel 结构 :以 DES 为代表,将明文拆为左右两半,轮函数只作用于一半,实现了加解密几乎完全对称的优美性质。
  • SPN 结构:以 AES 为代表,通过 S 盒(混淆)+ P 盒(扩散)的交替迭代,在整个分组上直接施加非线性变换。

这两种结构是现代分组密码的两大基石。理解了它们,再看 Blowfish、Twofish、SM4 等任何算法,都能迅速抓住核心逻辑。

本篇我们聚焦 Feistel 结构,并以 DES 为完整案例深度拆解。我们不会停留在"DES 有哪些步骤"的表面,而是追问每一个设计选择背后的原因------知其然,更要知其所以然

Crypto专栏:https://blog.csdn.net/r_feynman_/category_13190241.html
Crypto 密码解析实战靶场:https://blog.csdn.net/r_feynman_/category_13194584.html


一、Feistel 结构:分组密码的经典范式

1.1 从"单一大置换"到多轮迭代

分组密码的数学本质很简单:它是一个 n n n 比特空间上的置换------每个明文唯一对应一个密文,反之亦然。

但问题来了:为什么不直接设计一个"足够乱"的大置换,查表加密就行了?

原因有两个。第一,存不下 。64 位分组的置换表要有 2 64 2^{64} 264 条记录,这是个天文数字,根本不可能实现。第二,没法分析安全性。一个黑盒般的大置换,你根本不知道它有没有隐藏的弱点、有没有数学规律可以被利用。

所以密码学家换了个思路:不搞一个大置换,而是搞很多轮"小操作"。每一轮只做一点点变换,看起来很简单,但多轮叠加之后,整体就变成了一个极其复杂的置换。

这就是迭代分组密码 的核心思想。每一轮的内部运算逻辑,就叫轮函数

迭代结构的好处很明显:每一轮操作都很简单,便于分析安全性;实现起来也高效,不需要巨大的存储空间。而 Feistel 结构,就是迭代分组密码中最经典、影响最深远的一种设计框架。


1.2 Feistel 网络的基本结构

Feistel 结构(也叫 Feistel 网络 / Feistel 密码)由 IBM 密码学家 Horst Feistel 在 1970 年代提出,是分组密码史上最经典的设计框架之一,后来成为美国数据加密标准 DES 的核心架构。

它的核心设计思路非常巧妙:不直接对整个分组做变换,而是把明文分组平均切成左右两半,每一轮只"搅乱"其中一半,另一半直接平移过去。

这种"半分组处理"的设计,正是 Feistel 结构所有优美性质的根源。


1.2.1 单轮变换规则

具体来说,设分组总长度为 2 n 2n 2n 位,左右两半各 n n n 位。初始明文被拆分为左半部分 L 0 L_0 L0 和右半部分 R 0 R_0 R0。

随后进行 r r r 轮迭代,每一轮的操作规则完全相同:

L i = R i − 1 R i = L i − 1 ⊕ F ( R i − 1 , K i ) \begin{align*} L_i &= R_{i-1} \\ R_i &= L_{i-1} \oplus F(R_{i-1}, K_i) \end{align*} LiRi=Ri−1=Li−1⊕F(Ri−1,Ki)

逐行解释:

  • 第一行 L i = R i − 1 L_i = R_{i-1} Li=Ri−1:上一轮的右半部分,直接变成这一轮的左半部分。简单说就是"右边的直接移到左边",不做任何变换。
  • 第二行 R i = L i − 1 ⊕ F ( R i − 1 , K i ) R_i = L_{i-1} \oplus F(R_{i-1}, K_i) Ri=Li−1⊕F(Ri−1,Ki):上一轮的左半部分,与轮函数的输出做异或运算,结果作为这一轮的右半部分。

1.2.2 轮函数 F

公式中的 F F F 就是轮函数(Round Function),它是 Feistel 结构的核心组件,也是密码安全性的主要来源。

轮函数接受两个输入:

  1. 上一轮的右半部分 R i − 1 R_{i-1} Ri−1
  2. 第 i i i 轮的轮子密钥 K i K_i Ki(由主密钥通过密钥调度算法生成)

轮函数的输出长度与左半部分相同,都是 n n n 位,这样才能与左半部分做异或运算。

特别注意 :轮函数 F F F 不需要是可逆的。这是 Feistel 结构极其重要的一个性质------整个密码的可逆性由异或操作和左右分片机制保证,轮函数本身可以设计得任意复杂、任意非线性。我们会在 1.4 节详细证明这一点


1.2.3 多轮迭代与最终输出

r r r 轮迭代全部完成之后,将最后一轮的左右两半拼接起来,就得到了密文:

密文 = L r ∥ R r \text{密文} = L_r \ \|\ R_r 密文=Lr ∥ Rr

其中 ∥ \| ∥ 表示比特串拼接。

💡 一个容易忽略的细节:通用理论Feistel模型迭代完成后输出 L r ∥ R r L_r\|R_r Lr∥Rr;DES执行完16轮迭代得到 L 16 ∥ R 16 L_{16}\|R_{16} L16∥R16,迭代内部不再执行交换,我们需要手动交换左右两半得到 R 16 ∥ L 16 R_{16}\|L_{16} R16∥L16 ,再送入 I P − 1 IP^{-1} IP−1。

这个设计保证解密仅需倒序使用子密钥,其余运算逻辑完全复用。若忽视这次手动交换,算法实现将直接出错。


1.3 为什么 Feistel 是置换?

在讲解密之前,我们先确认一个最基本的问题:Feistel 结构加密出来的结果,能不能唯一解密回去?

换句话说,加密操作是不是一个置换(Permutation)?如果不是,两个不同的明文可能加密成同一个密文,那就乱套了------解密的时候你根本不知道该还原成哪个。

答案是:是的,每一轮 Feistel 变换都是置换,因此整个加密过程也是置换。

我们来简单证明一下。


1.3.1 证明单射(不会碰撞)

设单轮 Feistel 变换为函数 F K i \mathcal{F}{K_i} FKi,输入为第 i − 1 i-1 i−1 轮状态 ( L i − 1 , R i − 1 ) (L{i-1}, R_{i-1}) (Li−1,Ri−1),输出为第 i i i 轮状态 ( L i , R i ) (L_i,R_i) (Li,Ri):

F K i ( L i − 1 , R i − 1 ) = ( L i ,    R i ) = ( R i − 1 , L i − 1 ⊕ F ( R i − 1 , K i ) ) \mathcal{F}{K_i}(L{i-1}, R_{i-1}) = \big(L_i,\; R_i\big) = \bigl(R_{i-1},\ L_{i-1} \oplus F(R_{i-1}, K_i)\bigr) FKi(Li−1,Ri−1)=(Li,Ri)=(Ri−1, Li−1⊕F(Ri−1,Ki))

现在证明:如果两个输入经过变换后输出相同,那么输入一定相同。

假设:

F K i ( L 1 , R 1 ) = F K i ( L 2 , R 2 ) \mathcal{F}{K_i}(L_1, R_1) = \mathcal{F}{K_i}(L_2, R_2) FKi(L1,R1)=FKi(L2,R2)

根据函数定义,输出左分量等于输入右分量,因此:

R 1 = R 2 (1) R_1 = R_2 \tag{1} R1=R2(1)

输出右分量等于输入左分量异或轮函数输出:

L 1 ⊕ F ( R 1 , K i ) = L 2 ⊕ F ( R 2 , K i ) (2) L_1 \oplus F(R_1, K_i) = L_2 \oplus F(R_2, K_i) \tag{2} L1⊕F(R1,Ki)=L2⊕F(R2,Ki)(2)

由式 (1) 可知 R 1 = R 2 R_1 = R_2 R1=R2,推得 F ( R 1 , K i ) = F ( R 2 , K i ) F(R_1, K_i) = F(R_2, K_i) F(R1,Ki)=F(R2,Ki)。

式 (2) 两边同时异或 F ( R 1 , K i ) F(R_1, K_i) F(R1,Ki),得到:

L 1 = L 2 L_1 = L_2 L1=L2

结合式 (1),有 ( L 1 , R 1 ) = ( L 2 , R 2 ) (L_1, R_1) = (L_2, R_2) (L1,R1)=(L2,R2)。

单射得证------不会出现"两个不同明文加密成同一个密文"的碰撞情况。


1.3.2 证明满射(都能解密)

反过来,证明:对于任意一个输出,都一定能找到对应的输入。

任取输出 ( L ′ , R ′ ) (L', R') (L′,R′),我们构造输入如下:

{ R i − 1 = L ′ L i − 1 = R ′ ⊕ F ( L ′ , K i ) \begin{cases} R_{i-1} = L' \\ L_{i-1} = R' \oplus F(L', K_i) \end{cases} {Ri−1=L′Li−1=R′⊕F(L′,Ki)

现在验证这个输入经过 F K i \mathcal{F}_{K_i} FKi 变换后,确实能得到 ( L ′ , R ′ ) (L', R') (L′,R′)。

输出左半部分

L i = R i − 1 = L ′ ✓ L_i = R_{i-1} = L' \quad \text{✓} Li=Ri−1=L′✓

输出右半部分

R i = L i − 1 ⊕ F ( R i − 1 , K i ) = ( R ′ ⊕ F ( L ′ , K i ) ) ⊕ F ( L ′ , K i ) = R ′ ⊕ ( F ( L ′ , K i ) ⊕ F ( L ′ , K i ) ) = R ′ ⊕ 0 = R ′ ✓ \begin{align*} R_i &= L_{i-1} \oplus F(R_{i-1}, K_i) \\ &= \bigl(R' \oplus F(L', K_i)\bigr) \oplus F(L', K_i) \\ &= R' \oplus \bigl(F(L', K_i) \oplus F(L', K_i)\bigr) \\ &= R' \oplus 0 \\ &= R' \quad \text{✓} \end{align*} Ri=Li−1⊕F(Ri−1,Ki)=(R′⊕F(L′,Ki))⊕F(L′,Ki)=R′⊕(F(L′,Ki)⊕F(L′,Ki))=R′⊕0=R′✓

(异或的性质: x ⊕ x = 0 x \oplus x = 0 x⊕x=0, x ⊕ 0 = x x \oplus 0 = x x⊕0=x)

所以 F K i ( L i − 1 , R i − 1 ) = ( L ′ , R ′ ) \mathcal{F}{K_i}(L{i-1}, R_{i-1}) = (L', R') FKi(Li−1,Ri−1)=(L′,R′)。

满射得证------任何密文都一定能解密回唯一的明文。


既是单射又是满射,那就是双射,也就是置换。

每一轮都是置换, r r r 轮复合之后,整个加密函数也是置换:

E = F K r ∘ F K r − 1 ∘ ⋯ ∘ F K 1 \mathcal{E} = \mathcal{F}{K_r} \circ \mathcal{F}{K_{r-1}} \circ \cdots \circ \mathcal{F}_{K_1} E=FKr∘FKr−1∘⋯∘FK1

这就从数学上保证了解密一定是可行的。


1.4 核心性质:加解密对称性证明

Feistel 结构最巧妙、最优美的性质,就是加解密几乎完全一样

加密和解密使用同一套运算结构,唯一区别是子密钥倒序使用。

该性质工程价值极高:硬件实现无需设计两套独立电路;软件实现加密、解密可复用绝大多数代码。下面完成数学证明。


1.4.1 单轮的逆变换

正向单轮 Feistel 变换:

L i = R i − 1 R i = L i − 1 ⊕ F ( R i − 1 , K i ) \begin{align*} L_i &= R_{i-1} \\ R_i &= L_{i-1} \oplus F(R_{i-1}, K_i) \end{align*} LiRi=Ri−1=Li−1⊕F(Ri−1,Ki)

已知输出状态 ( L i , R i ) (L_i,R_i) (Li,Ri),求解上一轮状态 ( L i − 1 , R i − 1 ) (L_{i-1},R_{i-1}) (Li−1,Ri−1)。

由第一式直接得到: R i − 1 = L i R_{i-1}=L_i Ri−1=Li,代入第二式:

R i = L i − 1 ⊕ F ( L i , K i ) R_i = L_{i-1} \oplus F(L_i, K_i) Ri=Li−1⊕F(Li,Ki)

等式两侧同时异或 F ( L i , K i ) F(L_i,K_i) F(Li,Ki):

L i − 1 = R i ⊕ F ( L i , K i ) L_{i-1} = R_i \oplus F(L_i, K_i) Li−1=Ri⊕F(Li,Ki)

得到单轮逆变换:

L i − 1 = R i ⊕ F ( L i , K i ) R i − 1 = L i \begin{align*} L_{i-1} &= R_i \oplus F(L_i, K_i) \\ R_{i-1} &= L_i \end{align*} Li−1Ri−1=Ri⊕F(Li,Ki)=Li

对比正向变换与逆变换:二者运算结构高度相似,等效于将分组左右两半交换后再执行 Feistel 迭代。


1.4.2 多轮的逆变换

设加密共 r r r 轮,加密子密钥序列: K 1 , K 2 , ... , K r K_1,K_2,\dots,K_r K1,K2,...,Kr,输入明文 ( L 0 , R 0 ) (L_0,R_0) (L0,R0),输出密文 ( L r , R r ) (L_r,R_r) (Lr,Rr)。

解密规则:使用逆序子密钥 K r , K r − 1 , ... , K 1 K_r,K_{r-1},\dots,K_1 Kr,Kr−1,...,K1,调用完全相同的 Feistel 迭代函数;解密迭代前,先将密文交换左右分组,以 ( R r , L r ) (R_r,L_r) (Rr,Lr) 作为解密初始输入。

考察解密第1轮(抵消加密第 r r r 轮):

解密输入 ( R r , L r ) (R_r,L_r) (Rr,Lr),子密钥 K r K_r Kr,执行正向Feistel规则:

{ L ′ = L r R ′ = R r ⊕ F ( L r , K r ) \begin{cases} L' = L_r \\ R' = R_r \oplus F(L_r, K_r) \end{cases} {L′=LrR′=Rr⊕F(Lr,Kr)

加密第 r r r 轮满足:

{ L r = R r − 1 R r = L r − 1 ⊕ F ( R r − 1 , K r ) \begin{cases} L_r = R_{r-1} \\ R_r = L_{r-1} \oplus F(R_{r-1}, K_r) \end{cases} {Lr=Rr−1Rr=Lr−1⊕F(Rr−1,Kr)

将 L r = R r − 1 L_r=R_{r-1} Lr=Rr−1 代入解密输出右分量:

R ′ = ( L r − 1 ⊕ F ( R r − 1 , K r ) ) ⊕ F ( R r − 1 , K r ) = L r − 1 R' = \big(L_{r-1} \oplus F(R_{r-1}, K_r)\big) \oplus F(R_{r-1}, K_r) = L_{r-1} R′=(Lr−1⊕F(Rr−1,Kr))⊕F(Rr−1,Kr)=Lr−1

解密一轮输出状态为 ( L r , L r − 1 ) = ( R r − 1 , L r − 1 ) (L_r, L_{r-1})=(R_{r-1},L_{r-1}) (Lr,Lr−1)=(Rr−1,Lr−1)。

可见:每执行一轮解密迭代,即可抵消一轮加密变换,但分组左右保持倒置。以此递推,全部 r r r 轮解密迭代完成后,输出状态为 ( R 0 , L 0 ) (R_0,L_0) (R0,L0)。

最后交换左右分组,恢复原始明文 ( L 0 , R 0 ) (L_0,R_0) (L0,R0)。

证毕。


1.4.3 一个极其重要的推论

整个证明过程中,并未对轮函数 F F F 施加可逆要求

Feistel 结构整体可逆性依托异或运算实现,与轮函数是否为双射无关。轮函数可以任意构造,无需考虑逆运算实现。

这给予密码设计者极大自由度:可以在轮函数中大量引入非线性组件(S盒、复杂置换等),专注提升密码抗攻击能力。这也是 Feistel 结构能够广泛流行的关键原因。


1.5 Feistel 结构的优势与局限

优势 说明
① 加解密高度对称 加密与解密复用同一套结构,仅子密钥倒序使用,硬件/软件实现成本低
② 轮函数无需可逆 整体可逆性由异或运算保障,轮函数可自由设计,便于引入非线性组件
③ 安全性分析成熟 差分、线性密码分析等经典方法均基于 Feistel 框架发展,评估体系完善
局限 说明
① 每轮仅处理半部分组 左半分组直接平移,单比特扰动需经过两轮才能传播至全部分组
② 扩散速度较慢 半分组处理机制导致扩散效率低于 SPN 结构,达到同等安全强度通常需要更多轮数

Feistel 结构简洁优雅,深刻影响了现代分组密码发展。DES 作为其最经典的实现,是密码学史上的里程碑。接下来我们以 DES 为案例,完整拆解 Feistel 密码的工程落地与设计思想。


二、DES 算法概览

DES(Data Encryption Standard,数据加密标准)是密码学史上第一个被广泛应用的民用标准化分组密码,它的诞生标志着现代密码学从军事、外交领域正式走向商业和民用。


2.1 诞生与标准化历程

故事始于 1973 年,美国国家标准局 NBS(即后来的 NIST)公开征集加密标准,要求算法公开、安全可靠、易于实现,以解决当时民间加密算法各自为政、互不兼容的问题。

IBM 公司响应了征集,他们提交了一个内部项目 Lucifer 的改进版本------由 Horst Feistel 领导开发,采用的正是我们上一章讲的 Feistel 结构。

经过 NSA 参与修改(主要是 S 盒设计和密钥长度调整)后,算法于 1977 年 正式被采纳为联邦标准,命名为 DES。

DES 一用就是二十多年,银行、金融、通信、政府......到处都能看到它的身影。但随着计算机算力的飞速提升,56 位密钥逐渐显得力不从心。1998 年,电子前沿基金会 EFF 用专用机器"Deep Crack"仅用 56 小时就暴力破解了 DES。

2001 年,NIST 正式宣布 AES 取代 DES,成为新的加密标准。不过 DES 的衍生版本 3DES(三重 DES)又沿用了很多年,直到 2023 年才被正式弃用。

💡 关于 NSA 修改 S 盒的争议:当年很多人怀疑 NSA 在 S 盒里留了后门。但后来差分密码分析公开后,人们发现修改后的 S 盒反而增强了抗差分攻击的能力------也就是说,NSA 当年其实是在帮 DES 变得更安全,只是他们早就知道差分攻击这种方法,而学术界还不知道。


2.2 整体加密流程

2.2 整体加密流程

DES 是一个典型的 Feistel 结构分组密码,整体流程如下:

明文加密链路(左侧) 密钥生成链路(右侧)
64 位明文输入 64 位主密钥输入
IP 初始置换打乱位置 PC-1 置换压缩到 56 位
拆成左右两半 L 0 L_0 L0、 R 0 R_0 R0,各 32 位 拆成 C 0 C_0 C0、 D 0 D_0 D0 两半,各 28 位
16 轮 Feistel 迭代,每轮使用对应子密钥 每轮循环左移不同位数
16 轮结束后拼接左右两半 PC-2 置换选出 48 位,生成当前轮子密钥
逆初始置换 IP⁻¹,输出 64 位密文 共生成 16 个 48 位子密钥

DES 是一个典型的 Feistel 结构分组密码,整个加密过程分三步:

  1. 初始置换 IP:64 位明文按固定表重排位置
  2. 16 轮 Feistel 迭代:核心部分,每轮使用一个 48 位子密钥
  3. 逆初始置换 IP⁻¹:把 IP 打乱的位置还原,输出 64 位密文

16 轮迭代遵循标准 Feistel 规则:

L i = R i − 1 R i = L i − 1 ⊕ F ( R i − 1 , K i ) \begin{align*} L_i &= R_{i-1} \\ R_i &= L_{i-1} \oplus F(R_{i-1}, K_i) \end{align*} LiRi=Ri−1=Li−1⊕F(Ri−1,Ki)

其中轮函数 F F F 是 DES 最复杂的部分,内部包含 E 扩展盒、S 盒代换、P 置换三个核心组件,我们后面第四章专门拆解。

text 复制代码
明文(64位) → IP → 16轮Feistel迭代 → IP⁻¹ → 密文(64位)

核心参数

参数 长度 说明
分组长度 64 位 每次加密处理 8 字节数据
密钥长度 64 位(有效 56 位) 其中 8 位为奇偶校验位,不参与加密运算
迭代轮数 16 轮 安全性与实现效率的平衡点
  • 64 位分组:在 70 年代是兼顾安全与效率的合理选择,以今天的标准看略短,易受生日攻击等威胁
  • 56 位有效密钥:当年足够安全,随摩尔定律推进,暴力破解成本急剧下降,最终成为 DES 退役的直接原因
  • 16 轮迭代 :经过精心选择。差分攻击攻破 16 轮 DES 约需 2 47 2^{47} 247 个选择明文,已接近暴力破解的 2 56 2^{56} 256 复杂度,再增加轮数安全收益递减

三、初始置换 IP 与逆初始置换

初始置换 IP(Initial Permutation)是 DES 加密的第一步,逆初始置换 IP⁻¹ 是最后一步。这两步操作只换位、不改值,也不涉及密钥,因此很多人刚学 DES 时都会疑惑:这两步到底有啥用?不是多此一举吗?

我们先看它是怎么工作的,再说设计意图。


3.1 IP 置换表与查表规则

初始置换就是一张固定的 64 位置换表,把输入的 64 位数据按表重新排列位置。

先记牢统一读法(所有置换表都适用):

  • 表的位置 = 输出第几位(从上到下、从左到右依次是第 1、2、3......位)
  • 表中的数值 = 取输入的第几位

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

输出位序号计算公式:

输出位 = ( 行号 − 1 ) × 8 + 列号 \text{输出位} = (\text{行号} - 1) \times 8 + \text{列号} 输出位=(行号−1)×8+列号

举两个例子:

例 1:第 1 行第 1 列

  • 输出位 = (1 - 1) × 8 + 1 = 第 1 位
  • 数值 = 58
  • 含义:输出第 1 位 = 输入第 58 位

例 2:第 5 行第 8 列

  • 输出位 = (5 - 1) × 8 + 8 = 第 40 位
  • 数值 = 1
  • 含义:输出第 40 位 = 输入第 1 位

简单说就是:把输入的 64 位按这张表重新排个队。

💡 注意:DES 标准中位编号从 1 开始,写代码时要转换成 0 基索引,别搞混了。


3.2 逆初始置换 IP⁻¹

逆初始置换就是 IP 的逆操作------IP 把位置打乱,IP⁻¹ 再按逆表换回去。如果先做 IP 再做 IP⁻¹,数据就完全恢复原样。

IP⁻¹ 置换表如下(读法和 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

IP 表和 IP⁻¹ 表是严格互逆的,满足:

如果 IP 中输出第 i 位 = 输入第 j 位,那么 IP⁻¹ 中输出第 j 位 = 输入第 i 位。

用数学语言写就是:

IP i = j    ⟺    IP − 1 j = i \text{IP}i = j \iff \text{IP}^{-1}j = i IPi=j⟺IP−1j=i

我们来完整验证一个:

第一步:从 IP 表找

  • 第 1 行第 1 列 → 输出第 1 位 → 值为 58
  • 即: IP 1 = 58 \text{IP}1 = 58 IP1=58
  • 含义:输出第 1 位取输入第 58 位

第二步:从 IP⁻¹ 表验证

  • 互逆的话,应该有 IP − 1 58 = 1 \text{IP}^{-1}58 = 1 IP−158=1
  • 也就是:输出第 58 位取输入第 1 位
  • 算位置:输出第 58 位 = 第几行第几列?
    • 行号 = ⌊(58 - 1) / 8⌋ + 1 = ⌊57 / 8⌋ + 1 = 7 + 1 = 第 8 行
    • 列号 = (58 - 1) % 8 + 1 = 57 % 8 + 1 = 1 + 1 = 第 2 列
  • 第 8 行第 2 列的值是 1
  • 即: IP − 1 58 = 1 ✓ \text{IP}^{-1}58 = 1 \quad ✓ IP−158=1✓

完全对得上。

⚠️ 常见坑提醒:别把"格子里的数字"和"输出位序号"搞混了。格子里写的 58 是输入位,不是输出位。先定位到输出第几位,再读格子里的值。


3.3 设计意图与争议

初始置换是 DES 最受争议的设计之一。很多人觉得它只换位、不改值,也不涉及密钥,纯属多余。

关于它的作用,主要有两种说法:

① 硬件实现的工程优化

这是比较主流的观点。DES 设计年代以硬件实现为主,初始置换把同一个字节的 8 位打散到不同位置,让后续轮函数的数据分布更"散",硬件布线更方便。

简单说:不是为了安全,是为了工程实现便利。

② 增加软件实现难度

另一种说法:NSA 要求加这一步,是为了抬高纯软件实现 DES 的门槛。初始置换打乱字节边界,软件实现要做大量位操作,效率不高;而硬件实现就是走几根线,几乎零成本。


从密码分析角度看,初始置换不会提升算法理论安全强度 。攻击者只需在分析前预先执行逆置换,即可完全抵消IP带来的比特重排效果。正因如此,AES、SM4等现代分组密码,都取消了这种首尾无密钥参与的固定置换。

不管怎样,初始置换是 DES 的标准组成部分,了解即可。接下来进入 DES 的核心------轮函数。


四、DES 轮函数深度拆解

轮函数 F F F 是 DES 安全性的核心,它接受 32 位右半分组 R i − 1 R_{i-1} Ri−1 和 48 位子密钥 K i K_i Ki,输出 32 位结果。

内部完整结构如下:

从左到右看,整个轮函数分四步:

  1. E 扩展(Expansion):把 32 位输入扩展成 48 位
  2. 密钥异或:48 位数据与 48 位子密钥按位异或
  3. S 盒代换(Substitution):48 位分成 8 组,每组 6 位,经 8 个 S 盒各输出 4 位,共 32 位
  4. P 置换(Permutation):32 位按固定表重排位置

用公式表示:

R i − 1 → E扩展 48 位 → ⊕ K i 48 位 → S盒代换 32 位 → P置换 32 位 R_{i-1} \xrightarrow{\text{E扩展}} 48\text{位} \xrightarrow{\oplus K_i} 48\text{位} \xrightarrow{\text{S盒代换}} 32\text{位} \xrightarrow{\text{P置换}} 32\text{位} Ri−1E扩展 48位⊕Ki 48位S盒代换 32位P置换 32位

输出结果与左半分组 L i − 1 L_{i-1} Li−1 异或,得到新一轮右半分组 R i R_i Ri。

我们逐个拆解。


4.1 轮函数整体结构与 E 扩展

轮函数输入 :32 位右半分组 R i − 1 R_{i-1} Ri−1 + 48 位子密钥 K i K_i Ki

轮函数输出:32 位

完整四步:

  1. E 扩展:32 位 → 48 位(对齐子密钥长度 + 加速扩散)
  2. 密钥异或:48 位数据与 48 位子密钥按位异或
  3. S 盒代换:48 位分成 8 组,每组 6 位,经 8 个 S 盒各输出 4 位,共 32 位
  4. P 置换:32 位按固定表重排位置,进一步扩散

输出结果与左半分组 L i − 1 L_{i-1} Li−1 异或,得到新一轮右半分组 R i R_i Ri。


E 扩展盒详解

E 扩展(Expansion)把 32 位输入扩展为 48 位。看图中轮函数的第一步,就是 Expansion Permutation。

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

扩展规律:

把 32 位输入从左到右每 4 位分成一组,共 8 组。每组 4 位扩展成 6 位------保留中间 4 位,再从左右邻居各借 1 位

举个例子:第 1 组是输入第 1~4 位,扩展后变成:

  • 左边借 1 位:第 32 位(首尾环形相连)
  • 中间 4 位:第 1、2、3、4 位
  • 右边借 1 位:第 5 位

所以第 1 组扩展后是:32, 1, 2, 3, 4, 5,共 6 位。

💡 关键细节:因为是首尾相连的环形扩展,每一位输入都会出现在两个输出位置。这样一位变化就能影响两个 S 盒,加速了扩散。

扩展之后的 48 位数据,和 48 位子密钥做异或,然后送入 S 盒。


4.2 S 盒代换:DES 的非线性核心

S盒(Substitution Box,代换盒)是DES唯一的非线性组件 ,也是实现香农「混淆」特性的核心。

如果移除全部S盒,整个加密流程仅剩下比特置换、按位异或这类线性运算,攻击者只需建立线性方程组,就能直接破解密码。

结合轮函数结构图观察:E扩展与子密钥异或后得到48比特数据,从左至右均等切分为8组,每组6比特 ;8组数据依次送入独立的 S 1 ∼ S 8 S_1 \sim S_8 S1∼S8 八个S盒;每个S盒输出4比特,8组输出拼接得到32比特,送入后续P置换。

简单概括:6比特输入查表压缩,得到4比特输出


4.2.1 查表规则(标准固定拆分方式)

单个S盒由一张 4行×16列 的静态查找表构成,表格内数值范围 0 ∼ 15 0\sim15 0∼15,最终转换为4位二进制作为输出。

设某一组6位输入比特串: b 1 b 2 b 3 b 4 b 5 b 6 \boldsymbol{b_1\ b_2\ b_3\ b_4\ b_5\ b_6} b1 b2 b3 b4 b5 b6

  1. 行号构造 :取首尾比特 b 1 b 6 b_1b_6 b1b6,拼接为2位二进制,转为十进制(取值区间 0 ∼ 3 0\sim3 0∼3,对应表格4行)
  2. 列号构造 :取中间4位 b 2 b 3 b 4 b 5 b_2b_3b_4b_5 b2b3b4b5,拼接为4位二进制,转为十进制(取值区间 0 ∼ 15 0\sim15 0∼15,对应表格16列)
  3. 使用「行号,列号」定位表格数值,补齐为4位二进制,即为S盒输出

⚠️ 极易混淆的编号规则

S盒表格行、列从0开始计数 ;而前文IP初始置换、E扩展表比特位置编号从1开始,两套计数标准不能混用。

完整演算示例

6位输入比特串:1 1 0 1 0 1

  • b 1 = 1 , b 6 = 1 b_1=1,\ b_6=1 b1=1, b6=1,二进制11 → 十进制 3(第3行)
  • b 2 b 3 b 4 b 5 = 1010 b_2b_3b_4b_5 = \boldsymbol{1010} b2b3b4b5=1010,二进制1010 → 十进制 10(第10列)

4.2.2 S 1 S_1 S1 查表实操

S 1 S_1 S1 标准表:

行\列 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 14 4 13 1 2 15 11 8 3 10 6 12 5 9 0 7
1 0 15 7 4 14 2 13 1 10 6 12 11 9 5 3 8
2 4 1 14 8 13 6 2 11 15 12 9 7 3 10 5 0
3 15 12 8 2 4 9 1 7 5 11 3 14 10 0 6 13

定位:第3行、第10列,数值 = 3

十进制3补齐4位二进制:0011

S 1 S_1 S1 最终输出:0011

重要知识点: S 1 ∼ S 8 S_1 \sim S_8 S1∼S8 是8张互不相同、预定义的固定常量表,写死在FIPS 46标准中;不存在数学公式可以计算表内数字,只能查表。所有DES程序必须使用完全一致的S盒数据表。


4.2.3 S盒硬性设计约束

8组S盒表格并非随机填充,在标准化时严格满足以下约束:

  1. 每行是 0 ∼ 15 0\sim15 0∼15 的完整置换
    表格任意一行内16个数字互不重复,覆盖0~15全部取值。保证同一输入行下,所有4比特输出均有机会产生。
  2. 严格雪崩准则(SAC)
    输入任意翻转1比特,输出至少改变2比特。实现雪崩效应:输入微小变化,引发输出大范围变动。
  3. 比特独立性准则(BIC)
    任意两个输出比特不存在稳定相关性,攻击者无法依靠部分输出比特推测剩余比特。
  4. 差分概率上界约束
    任意输入差分,无法以极高概率产生固定输出差分;DES单个S盒最大差分概率恰好等于 1 / 4 1/4 1/4,这也是当年NSA刻意约束的指标。

💡 历史插曲

IBM最初Lucifer原型密码的S盒被NSA修改,却未公开修改理由,长期引发「内置后门」猜想。直到差分密码分析在1990年对外发表,学界才证实:NSA调整S盒的目的,正是抵御差分密码分析;差分分析在当时属于美国涉密密码技术,无法公开解释。


4.2.4 S盒与差分抗性(攻击视角)

差分密码分析原理:构造两组具有固定异或差值的明文,观察加密后密文差值的统计学规律,逆向猜测密钥。

S盒是差分攻击最重要的突破口:若S盒频繁出现「固定输入差值 → 高概率固定输出差值」,攻击者就可以构造贯穿多轮的差分路径,大幅降低破解难度。

DES S盒针对性限制差分特征:

  1. 单个S盒最大差分概率不高于 1 / 4 1/4 1/4
  2. 经过16轮迭代、P置换扩散后,有效差分路径概率衰减至约 2 − 47 2^{-47} 2−47
  3. 该复杂度已经十分接近暴力穷举56位密钥的 2 − 56 2^{-56} 2−56,继续增加迭代轮数,安全提升幅度极小。
    这也是DES最终选定16轮Feistel迭代的根本原因。

如果你需要,我可以把文字适度精简适配公众号/CSDN排版,或者补齐剩余 S 2 ∼ S 8 S_2\sim S_8 S2∼S8 完整表格附录。


4.3 P 置换与一轮完整流程

S 盒输出的 32 位,还要经过一次 P 置换(Permutation)。看图中轮函数的最后一步,就是 Straight Permutation(P 置换)。

4.3.1 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

P 置换的作用是扩散 :把每个 S 盒的输出位打散,让一个 S 盒的输出位,在下一轮能影响到多个不同的 S 盒

具体来说:第 i i i 个 S 盒的 4 个输出位,经过 P 置换后,会被送到 4 个不同的位置;下一轮经过 E 扩展后,这 4 位又会影响到更多的 S 盒。

这样就形成了 E 扩展 → S 盒 → P 置换 的扩散循环:

  • E扩展保证任意输入比特会影响两个S盒;
  • P置换打散S盒输出,使得单个S盒的输出比特在下一轮扩散至多个不同S盒。

多轮叠加后,一位明文的变化会迅速扩散到整个分组。


4.3.2 一轮完整流程走查

我们结合流程图,把一轮 Feistel 迭代的完整流程串起来:

  1. 输入 :左半 L i − 1 L_{i-1} Li−1(32 位)、右半 R i − 1 R_{i-1} Ri−1(32 位)、子密钥 K i K_i Ki(48 位)
  2. E 扩展 : R i − 1 R_{i-1} Ri−1 从 32 位扩展到 48 位
  3. 密钥异或 :扩展后的 48 位与子密钥 K i K_i Ki 异或
  4. S 盒代换:48 位分成 8 组,每组 6 位,经 8 个 S 盒代换,输出 32 位
  5. P 置换:32 位按 P 表重排位置,得到轮函数最终输出
  6. 异或左半 :轮函数输出与 L i − 1 L_{i-1} Li−1 异或(图中蓝色圆圈加号),得到新的右半 R i R_i Ri
  7. 左右更新 :原来的右半 R i − 1 R_{i-1} Ri−1 直接成为新的左半 L i L_i Li
  8. 输出 : L i L_i Li、 R i R_i Ri

这就是 DES 的一轮完整迭代。16 轮全部跑完之后,把左右两半拼接起来,再经过逆初始置换 IP⁻¹,就得到了最终的 64 位密文。

⚠️ 注意:DES 16轮迭代内部不会自动执行左右交换;迭代完成后,需要手动拼接 R 16 ∥ L 16 R_{16}\|L_{16} R16∥L16,再执行逆初始置换,编写代码时千万不要遗漏。


五、子密钥生成算法

回顾第四章轮函数,DES 每一轮 Feistel 迭代都需要独立的 48 位子密钥 K i K_i Ki。算法不会直接使用原始 64 位主密钥参与运算,而是通过密钥调度算法,迭代生成 K 1 ∼ K 16 K_1 \sim K_{16} K1∼K16 共16组独立子密钥送入每一轮轮函数。

整体流程公式:

64位主密钥 → P C − 1 C 0 ∥ D 0    ( 56 b i t ) → 循环左移 C i ∥ D i → P C − 2 48 b i t 子密钥 K i \text{64位主密钥} \xrightarrow{PC-1} C_0\|D_0\;(56\mathrm{bit}) \xrightarrow{\text{循环左移}} C_i\|D_i \xrightarrow{PC-2} 48\mathrm{bit}\text{子密钥}K_i 64位主密钥PC−1 C0∥D0(56bit)循环左移 Ci∥DiPC−2 48bit子密钥Ki


5.1 PC-1 置换:64 位到 56 位的密钥压缩

DES 输入密钥标称长度64比特,每字节最低比特定义为奇偶校验位,8位校验比特不参与任何加密运算。PC-1置换的两个核心作用:丢弃8个奇偶校验位、剩余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

PC-1输出56比特数据,均等切分为两组:

  • 前28比特: C 0 C_0 C0
  • 后28比特: D 0 D_0 D0

⚠️ 重点区分:PC-1只做选取与置换,无比特扩展、无异或;奇偶校验位在这一步直接永久丢弃。


5.2 循环左移:为什么每轮移位数不同?

对每一轮 i ∈ 1 , 16 i\in1,16 i∈1,16,对上一轮状态 C i − 1 , D i − 1 C_{i-1},D_{i-1} Ci−1,Di−1 分别执行相同位数的循环左移。循环左移含义:左侧移出的比特追加至分组最右端。

各轮移位规则表:

轮数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
左移位数 1 1 2 2 2 2 2 2 1 2 2 2 2 2 2 1

移位后得到新分组 C i , D i C_i,D_i Ci,Di,一方面保留用于下一轮移位,另一方面拼接送入PC-2生成当前轮子密钥。

差异化移位的设计目的:

  1. 若固定移位位数, C , D C,D C,D 分组会出现周期性循环,造成多轮子密钥高度相似,产生线性依赖;
  2. 首尾第1、2、9、16轮仅移位1位,打破完整周期,消除子密钥之间简易推导关系;
  3. 杜绝攻击者利用子密钥的规律性,构造密钥猜测路径。

5.3 PC-2 置换:56 位到 48 位的子密钥选择

将移位完成后的 C i ∥ D i C_i\|D_i Ci∥Di(合计56比特)送入PC-2置换。PC-2会从56比特中挑选48个比特并打乱顺序,丢弃8个比特 ,最终输出48位子密钥 K i K_i Ki,恰好匹配轮函数异或层的数据长度。

PC-2置换表(数值代表选取 C i ∥ D i C_i\|D_i Ci∥Di 的第几位)

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

关键特性:PC-1、PC-2两张置换相互独立,不存在互逆关系;连续两次置换增加密钥比特扩散程度,增大从子密钥反向还原原始主密钥的计算代价。


5.4 16 轮子密钥完整生成流程

完整执行步骤汇总:

  1. 输入64比特原始密钥,依照PC-1表筛选比特,丢弃8位奇偶校验位,得到56比特,并拆分为 C 0 、 D 0 C_0、D_0 C0、D0;
  2. 循环执行 1~16 轮:
    • 根据轮数规则,对 C i − 1 C_{i-1} Ci−1、 D i − 1 D_{i-1} Di−1 同步循环左移;
    • 移位结果记为 C i 、 D i C_i、D_i Ci、Di;
    • 拼接 C i ∥ D i C_i\|D_i Ci∥Di,送入PC-2置换;
    • PC-2输出48比特,作为本轮子密钥 K i K_i Ki;
  3. 循环结束,得到有序子密钥序列 { K 1 , K 2 , ... , K 16 } \{K_1,K_2,\dots,K_{16}\} {K1,K2,...,K16}。

加密与解密子密钥使用规则:

加密顺序: K 1 → K 2 → ⋯ → K 16 K_1 \to K_2 \to \dots \to K_{16} K1→K2→⋯→K16

解密顺序: K 16 → K 15 → ⋯ → K 1 K_{16} \to K_{15} \to \dots \to K_{1} K16→K15→⋯→K1
安全小结

子密钥调度属于确定性算法,不存在随机成分。只要原始主密钥固定,16个子密钥完全确定。一旦主密钥被暴力破解,全部子密钥随之泄露,这也是56位短密钥最大短板之一。


六、多重DES:DES 的兼容改进方案

既然标准DES存在56位密钥长度不足的致命短板,无法抵抗现代暴力破解,在全新分组密码标准诞生之前,业界提出了多重DES方案,通过多次迭代加密拓展有效密钥长度,最具代表性的便是3DES(Triple DES)。

6.1 双重 DES(2DES)

设想最简单的改进思路:使用两组独立密钥依次加密:

C = E K 2 ( E K 1 ( P ) ) C = E_{K_2}(E_{K_1}(P)) C=EK2(EK1(P))

直观上大家会认为有效密钥长度提升至 56 × 2 = 112 56\times2=112 56×2=112 位。

中间相遇攻击(Meet-in-the-Middle) 可以将攻击复杂度压缩至约 2 57 2^{57} 257,安全增益十分有限,无法达到预期安全强度,因此双重DES从未正式投入大规模使用。

6.2 三重 DES(3DES / TDEA)

三重DES执行三次DES运算,存在三种主流密钥模式:

  1. 3密钥模式(3TDEA,推荐) : C = E K 3 ( D K 2 ( E K 1 ( P ) ) ) C=E_{K_3}(D_{K_2}(E_{K_1}(P))) C=EK3(DK2(EK1(P)))
    K 1 , K 2 , K 3 K_1,K_2,K_3 K1,K2,K3 相互独立,等效有效密钥长度112 bit(安全强度上限)。
  2. 2密钥模式(2TDEA) : K 1 = K 3 ≠ K 2 K_1=K_3 \neq K_2 K1=K3=K2,有效密钥长度约80 bit。
  3. 单密钥模式 : K 1 = K 2 = K 3 K_1=K_2=K_3 K1=K2=K3,等价于标准DES,无任何安全提升。

加解密规则说明:加密顺序为 加密→解密→加密;解密对应反向:解密→加密→解密。

6.3 3DES 的优劣与现状

优势:完全复用DES组件,能够兼容老旧基于DES的业务系统,是过渡时期的折中方案。

明显短板:执行三次DES运算,运算开销巨大,吞吐量远低于AES。

如今3DES仅存在于遗留金融、老旧工控系统做兼容;新建系统规范中已经禁止选用3DES,优先采用AES或国密SM4。

补充说明

本章仅对多重DES做基础介绍。至于中间相遇攻击完整原理、推导过程,归入后续DES密码分析专题展开讲解。同时DES原生的弱密钥、互补对称性、差分密码分析等安全缺陷,我们同样放在独立专题深入剖析。


七、总结:Feistel 结构与 DES 的历史遗产

本文完整梳理了经典 Feistel 网络范式,并以 DES 作为典型实现案例,剖析了整体架构、轮函数、S盒非线性变换以及密钥调度流程。

作为分组密码两大主流架构之一,Feistel 结构最大创新在于将分组划分为左右两半迭代运算,轮函数无需设计可逆变换,极大降低了密码设计难度,同时实现加解密电路高度对称。在 DES 之后,Blowfish、Twofish、国密 SM4 等算法都沿用广义 Feistel 的设计思想,足以看出该范式深远的影响力。

DES 是全球首个广泛商用标准化分组密码,推动现代对称密码工程体系成型。但受制于时代局限,56 位有效密钥长度使其难以抵御现代暴力破解,因此业界提出多重 DES(2DES、3DES)作为过渡兼容方案。然而多重 DES 只是折中补救手段,性能开销高,无法从根源解决 DES 架构遗留问题。

需要再次区分:Feistel ≠ DES 。Feistel 是通用架构,DES 只是该架构下的一个具体实例。

在下一篇文章,我们将转向分组密码另一核心设计范式:SPN 结构,讲解混淆、扩散、S盒与P盒的基础理论,为后续 AES 的深度解析搭建理论基础。

本文侧重于架构原理与算法流程实现。DES 的弱密钥、互补对称性,以及中间相遇攻击、差分密码分析等各类密码分析手段,内容体量较大,后续将设立独立专题详细推演。


免责声明

本文所有内容仅用于密码学理论学习、高校课程研究、CTF竞赛合法训练,仅供技术原理科普。

文中讲解的各类密码分析思路、攻击方法,禁止直接用于未获得授权的任何系统、设备、业务环境。

未经授权开展密码破解、数据窃听等行为违反《中华人民共和国网络安全法》《中华人民共和国密码法》《中华人民共和国刑法》相关规定,由此产生一切法律责任由行为人自行承担。

相关推荐
青山木1 小时前
Hot 100 --- 搜索插入位置
java·数据结构·算法·leetcode
alexwang2112 小时前
HDU 4348 详细题解
c++·算法·题解·hdu·主席树·可持久化数据结构·可持久化线段树
可编程芯片开发3 小时前
基于分段变步长搜索RMDCFT算法的天基雷达空间机动目标检测方法MATLAB仿真,对比RMDCFT算法
算法
2501_946736163 小时前
在线考试平台如何选型?从功能、优势与应用场景角度详解
大数据·人工智能·算法
天辛大师3 小时前
天心大师:不确定中锚定自我,AI生活的哲学命题
人工智能·算法·决策树·机器学习·生活·启发式算法
皓月斯语4 小时前
B2132 素数对
c++·算法·题解
星轨初途4 小时前
LeetCode 热题 100——day2 字母异位词分组
c++·算法·leetcode
happyprince4 小时前
篇1:整体观 · bitsandbytes项目全貌解读
人工智能·算法
青梅橘子皮5 小时前
STL---map/set... “家族“详解(从使用到底层)(1)
数据结构·算法