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
2
3
4
5
6
7
原始明文块:  (L0, R0)   #原始数据被拆成的两部分

一轮加密操作:
L1 = R0
R1 = L0 ⊕ F(R0, K0) #轮函数

输出密文块: (L1, R1)

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
    3
    v0 += (((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
    #define DELTA 0x9e3779b9
    #define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z)))

    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 Round
1
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from Crypto.Cipher import AES

password = b'secret!!secret!!' # 秘钥必须为 16 字节或者 16 字节的倍数的字节型数据
text = b'TextTextTextText' # 明文必须为 16 字节或者 16 字节的倍数的字节型数据,如果不够 16 字节需要进行补全
aes = AES.new(password, AES.MODE_ECB) # 创建一个 aes 对象
# AES.MODE_ECB 表示模式是 ECB 模式
en_text = aes.encrypt(text) # 加密明文
print("密文:", en_text) # 加密明文,bytes 类型
de_text = aes.decrypt(en_text) # 解密密文
print("明文:", de_text)

'''
密文: b'\t9\x9b\xc5\x19E\xeb4oL\x1a`\xc7\x8b\xd4\xb2'
明文: b'TextTextTextText'
'''