AES加密算法原理的详细介绍与实现
AES 加密算法原理的详细介绍与实现
AES(Advanced Encryption Standard,高级加密标准)是一种对称密钥块加密算法,由比利时密码学家 Joan Daemen 和 Vincent Rijmen 设计(基于 Rijndael 算法),于 2001 年被美国国家标准与技术研究院 (NIST) 选定为联邦信息处理标准 (FIPS PUB 197),取代了旧的 DES 算法。AES 被广泛用于数据加密,如文件存储、网络通信(SSL/TLS)和磁盘加密。它支持 128 位块大小,密钥长度为 128、192 或 256 位,安全性高,目前尚未被有效破解。
AES 的核心是替换-置换网络(Substitution-Permutation Network,SPN)结构,而不是 DES 的 Feistel 网络。这使得它在软件和硬件实现中高效。加密过程将明文转换为密文,使用相同的密钥进行加密和解密(解密是逆操作)。
以下是 AES 原理的详细介绍,重点以 AES-128(128 位密钥,10 轮)为例。算法处理数据以 4×4 字节矩阵(称为状态,State)形式,矩阵按列优先顺序排列:
[
\begin{bmatrix}
b_0 & b_4 & b_8 & b_{12} \
b_1 & b_5 & b_9 & b_{13} \
b_2 & b_6 & b_{10} & b_{14} \
b_3 & b_7 & b_{11} & b_{15}
\end{bmatrix}
]
加密包括初始轮密钥加法、多个主轮次和最终轮次。轮次数量取决于密钥长度:128 位密钥 10 轮,192 位 12 轮,256 位 14 轮。
1. 密钥扩展(Key Expansion)
AES 使用密钥调度(Key Schedule)从原始密钥生成轮密钥(Round Keys)。对于 AES-128,原始密钥是 128 位(4 个 32 位字),扩展为 11 个 128 位轮密钥(总 176 字节)。
过程:
- 将原始密钥复制到扩展密钥的前 4 个字。
- 对于后续字:
- 如果是 Nk(密钥字数,AES-128 为 4)的倍数:旋转前一个字(RotWord:左移 1 字节)、替换每个字节(SubWord:使用 S-Box)、XOR 轮常量(Rcon)。
- 如果密钥长度 > 192 位且 i % Nk == 4:仅 SubWord。
- 否则:XOR 前 Nk 个字的前一个字。
Rcon 是预定义常量数组,如 Rcon[1] = 0x01, Rcon[2] = 0x02 等(在 GF(2^8) 中计算)。
伪代码(基于维基百科描述):
function KeyExpansion(key, Nr):
Nk = key_size / 32 // 4 for 128-bit
expanded_key = array of Nb * (Nr + 1) * 4 bytes // Nb=4
// 复制初始密钥
for i = 0 to Nk-1:
expanded_key[4*i : 4*i+3] = key[4*i : 4*i+3]
// 扩展剩余字
for i = Nk to Nb*(Nr+1)-1:
temp = expanded_key[4*(i-1) : 4*(i-1)+3]
if i % Nk == 0:
temp = RotWord(temp) // 左旋转 1 字节
temp = SubWord(temp) // S-Box 替换
temp = temp XOR Rcon[i/Nk] // XOR 轮常量
elif Nk > 6 and i % Nk == 4:
temp = SubWord(temp)
expanded_key[4*i : 4*i+3] = expanded_key[4*(i-Nk) : 4*(i-Nk)+3] XOR temp
return expanded_key // 分割为轮密钥
此扩展确保每个轮使用独特子密钥,提供安全性。
2. 加密过程(Encryption)
加密包括:
- 初始轮(Initial Round):仅 AddRoundKey,使用第一个轮密钥。
- 主轮次(Main Rounds):Nr-1 次(AES-128 为 9 次),每个轮包括 SubBytes、ShiftRows、MixColumns、AddRoundKey。
- 最终轮(Final Round):SubBytes、ShiftRows、AddRoundKey(省略 MixColumns)。
2.1 SubBytes(字节替换)
非线性替换:每个状态字节通过 S-Box(8 位查找表)替换。S-Box 基于 GF(2^8) 中的乘法逆元加上仿射变换,确保非线性并避免固定点。
S-Box 示例(部分):
- 输入 0x00 → 输出 0x63
- 输入 0x01 → 输出 0x7C
解密使用 InvSubBytes(逆仿射 + 逆元)。
2.2 ShiftRows(行移位)
置换步骤:循环左移状态行:
- 第 0 行:不变
- 第 1 行:左移 1 字节
- 第 2 行:左移 2 字节
- 第 3 行:左移 3 字节
这确保不同列的字节混合,防止独立加密列。
解密:InvShiftRows(右移)。
2.3 MixColumns(列混合)
线性扩散:每个列视为 GF(2^8) 多项式,与固定多项式 ( c(z) = 0x03 z^3 + 0x01 z^2 + 0x01 z + 0x02 ) 乘法(模 ( z^4 + 1 ))。
等价矩阵乘法(加法为 XOR,乘法在 GF(2^8)):
[
\begin{bmatrix}
b_{0,j} \ b_{1,j} \ b_{2,j} \ b_{3,j}
\end{bmatrix}
\begin{bmatrix}
2 & 3 & 1 & 1 \
1 & 2 & 3 & 1 \
1 & 1 & 2 & 3 \
3 & 1 & 1 & 2
\end{bmatrix}
\begin{bmatrix}
a_{0,j} \ a_{1,j} \ a_{2,j} \ a_{3,j}
\end{bmatrix}
]
每个输入字节影响所有输出字节,提供扩散。
解密:InvMixColumns 使用逆矩阵:
[
\begin{bmatrix}
0E & 0B & 0D & 09 \
09 & 0E & 0B & 0D \
0D & 09 & 0E & 0B \
0B & 0D & 09 & 0E
\end{bmatrix}
]
2.4 AddRoundKey(轮密钥加法)
状态与当前轮密钥逐字节 XOR。这引入密钥依赖。
伪代码(整体加密):
function AES_Encrypt(plaintext, key, key_size):
Nr = 10 if key_size == 128 else 12 if key_size == 192 else 14
round_keys = KeyExpansion(key, Nr)
state = plaintext // 128 位明文加载到状态
AddRoundKey(state, round_keys[0]) // 初始轮
for round = 1 to Nr-1: // 主轮次
SubBytes(state)
ShiftRows(state)
MixColumns(state)
AddRoundKey(state, round_keys[round])
// 最终轮
SubBytes(state)
ShiftRows(state)
AddRoundKey(state, round_keys[Nr])
return state // 密文
解密过程类似,但逆序应用逆变换。
3. 实现注意事项
- 有限域运算:所有操作在 GF(2^8) 中,模多项式 ( x^8 + x^4 + x^3 + x + 1 )(0x11B)。
- S-Box 生成:基于逆元 + 仿射变换:( S(b) = A \cdot (b^{-1}) + c ),其中 A 是固定矩阵,c 是常量。
- 性能:软件实现需优化表格查找(T-Boxes 结合 SubBytes 和 MixColumns)。硬件使用专用电路。
- 安全性:抵抗差分和线性攻击,通过宽轨策略(Wide Trail Strategy)。
- 模式:AES 通常与 CBC、GCM 等模式结合使用,以处理多块数据和提供完整性。
- 实现示例:在实际编程中,可使用库如 OpenSSL (C) 或 cryptography (Python)。手动实现需小心字节序和填充(PKCS#7)。
以下是一个简化的 Python 伪代码实现(不完整,仅示意;实际需实现所有函数):
# 简化 AES-128 伪代码(不适合生产使用)
S_BOX = [0x63, 0x7c, 0x77, ...] # 完整 S-Box 表
def sub_bytes(state):
return [[S_BOX[state[i][j]] for j in range(4)] for i in range(4)]
def shift_rows(state):
state[1] = state[1][1:] + state[1][:1]
state[2] = state[2][2:] + state[2][:2]
state[3] = state[3][3:] + state[3][:3]
return state
def mix_columns(state):
# 实现矩阵乘法(省略细节)
pass
def add_round_key(state, round_key):
return [[state[i][j] ^ round_key[i][j] for j in range(4)] for i in range(4)]
# 密钥扩展和主函数类似上述伪代码
完整实现复杂,推荐使用成熟库。AES 的安全性依赖正确实现,包括侧信道防护(如常时运算)。
如果需要特定语言的完整代码、解密过程或示例计算,请提供更多细节!