常见加密算法整理
TEA家族
TEA算法每一次可以操作64bit(8byte),采用128bit(16byte)作为key,算法采用迭代的形式,推荐的迭代轮数是64轮,最少32轮(可以改变)。
TEA系列算法中均使用了一个DELTA常数,但DELTA的值对算法并无什么影响,只是为了避免不良的取值,推荐DELTA的值取为黄金分割数(5√-2)/2与232的乘积,取整后的十六进制值为0x9e3779B9(也可以改变),用于保证每一轮加密都不相同。
XTEA:使用与TEA相同的简单运算,但四个子密钥采取不正规的方式进行混合以阻止密钥表攻击。
Block TEA算法可以对32位的任意整数倍长度的变量块进行加解密的操作,该算法将XTEA轮循函数依次应用于块中的每个字,并且将它附加于被应用字的邻字。
XXTEA使用跟Block TEA相似的结构,但在处理块中每个字时利用了相邻字,且用拥有两个输入量的MX函数代替了XTEA轮循函数。上面提到的相邻字其实就是数组中相邻的项。
算法 | 年代 | 设计目标 | 缺点 / 改进动因 |
---|---|---|---|
TEA | 1994 | 简洁、快速的加密算法 | 存在相关密钥攻击,弱点已知 |
XTEA | 1997 | 修复 TEA 的弱点 | 算法结构仍然容易分析 |
XXTEA | 1998 | 完全重构的块加密算法 | 更安全,结构非 Feistel |
Feistel结构
- TEA和XTEA都是Feistel网络
- XXTEA完全摆脱Feustel网络
Feistel 网络(Feistel Network)是一种加密算法的结构框架。
设计理念:
把一个东西“拆成左右两半”,然后通过反复、对称的方式迭代加密。
Feistel 网络结构图
1 | 原始明文块: (L0, R0) #原始数据被拆成的两部分 |
TEA
- 分组加密:
TEA算法将64位明文分成两个32位的部分(V0 和V1),使用128位密钥分成四个32位的部分(K0,K1,K2,K3)。 迭代过程:
算法通过多次迭代(循环)进行加密,每次迭代对明文分组进行变换。变换:
每次迭代都会对明文分组进行非线性变换,包括加法、左移、右移等操作。密钥使用::
密钥的每个部分在每轮迭代中都会被使用,以确保加密的安全性。Delta (δ):
常量δ(0x9e3779b9)在每一轮迭代中累加,使得每轮的加密与前一轮不同,从而提升抗差分攻击能力。
循环次数:
算法的循环次数影响加密的强度。建议使用32轮或64轮的迭代,可以根据具体应用场景调整。
- 解密:
解密过程与加密过程相似,但方向相反,使用相同的密钥和循环次数即可。1
2
3
4
5
6
7
8
9
10
11
12
13
14
void ecbtea_encrypt(uint32_t* v, uint32_t* k) {
uint32_t v0 = v[0], v1 = v[1], i;
uint32_t delta = 0x9E3779B9;
uint32_t sum = 0;
uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];
for (i = 0; i < 32; i++) {
sum += delta;
v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
}
v[0] = v0;
v[1] = v1;
}XTEA
- 不再使用对称结构,而是交替处理
1
2
3v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
sum += delta;
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]);
XXTEA
扩展了加密块大小,可以处理任意长度的数据块(至少64位)。
- 将数据分成32位字数组(V[0]…V[n-1])
- 仍使用128位密钥(K0-K3)
优点
- 可变块大小:可以处理任意长度数据块
- 更强的安全性:更复杂的混合函数
- 整体处理:对整个数据块进行操作
- 保持简单性:实现仍相对简单
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
rounds = 6 + 52/n;
sum = rounds * delta;
while (sum != 0) {
e = (sum >> 2) & 3;
for (p = n-1; p > 0; p--) {
z = V[p-1];
V[p] -= ((z << 4 ^ z >> 5) + z) ^ (sum + K[(p & 3) ^ e]);
}
z = V[n-1];
V[0] -= ((z << 4 ^ z >> 5) + z) ^ (sum + K[(0 & 3) ^ e]);
sum -= delta;
}
DES & AES
DES
特性:
- 分组加密:每次加密 64 位(8 字节) 的明文块。
- 密钥长度:64 位密钥(其中 8 位用于奇偶校验,有效密钥是 56 位)。
- 加密轮数:16 轮 Feistel 结构。
加密过程:
1、初始置换(IP)
2、分为左右两部分 L0 和 R0。
3、进入 16 轮迭代,每轮:
- 利用子密钥对右半部分做 Feistel 函数(包含扩展、异或、S-box 替代、P置换)
- 与左半部分异或,交换左右。
4、最终置换(IP⁻¹)1
2
3
4
5
6
7
8
9明文 (64 位)
↓ IP 初始置换
分为 L0 和 R0 各 32 位
↓ 进入 16 轮迭代:
Li = Ri-1
Ri = Li-1 ⊕ F(Ri-1, Ki)
↓ 合并 L16 和 R16
↓ IP⁻¹ 逆置换
→ 密文
每轮结构:Feistel Round1
2
3
4
5
6
7
8
9输入:Li-1, Ri-1, Ki
F(Ri-1, Ki):
- 扩展置换 E (32 → 48 位)
- 与子密钥 Ki 异或
- S-box 替换(8 个 S-box:48 → 32 位)
- P 置换(重排)
输出:
Li = Ri-1
Ri = Li-1 ⊕ F(Ri-1, Ki)
3DES
3DES = DES × 3
密钥模式
3DES 使用 3 个子密钥(K1、K2、K3):
- 3-key 模式:K1 ≠ K2 ≠ K3 → 共 168 位密钥;
- 2-key 模式:K1 = K3 → 共 112 位密钥;
- 1-key 模式:K1 = K2 = K3 → 实际就是普通 DES,不推荐使用。
加密过程
默认使用 EDE 模式:Encrypt → Decrypt → Encrypt
${\displaystyle {\textrm {ciphertext}}=E{K3}(D{K2}(E_{K1}({\textrm {plaintext}}))).}$
- 第一次:使用 K1 加密;
- 第二次:使用 K2 解密(增加复杂性);
- 第三次:使用 K3 再加密,得到最终密文。
解密过程
${\displaystyle {\textrm {plaintext}}=D{K1}(E{K2}(D_{K3}({\textrm {ciphertext}})))).}$
使用 K3 解密,使用 K2 加密 ,然后使用 K1 解密
AES
特性
- 分组加密:以 128 位(16 字节)为一个分组处理。
- 支持三种密钥长度:
- AES-128:10 轮
- AES-192:12 轮
- AES-256:14 轮
加密过程
初始轮:
- AddRoundKey
主轮(重复 9~13 次):
- 字节代换SubBytes → 字节替换(S-box)
- 行移位ShiftRows → 行移位
- 列混淆MixColumns → 列混合
- 轮密钥加AddRoundKey → 异或子密钥
最终轮(无 MixColumns):
- SubBytes
- ShiftRows
- AddRoundKey
1、SubBytes(S-box 替换)
- AES 的 S-box 是基于 GF(2⁸) 有限域逆元 + 仿射变换,非线性极强。
- 每个字节独立替换,提升抗差分攻击能力。
例如,加密时,输出的字节S1为0x12,则查S盒的第0x01行和0x02列,得到值0xc9,然后替换S1原有的0x12为0xc9。
2、ShiftRows(行移位)
第 24 行左移 13 位,实现字节扩散。
3、 MixColumns(列混合)
- 每列与固定矩阵相乘
- 计算在 GF(2⁸) 上完成
4、 AddRoundKey(轮密钥异或)
- 每轮都与 128 位子密钥异或,确保密钥参与每轮。
AES_ECB
1 | from Crypto.Cipher import AES |