AES (Advanced Encryption Standard,高级加密标准) 是目前世界上最广泛使用的对称加密算法。它被设计用来替代旧的 DES 算法,以保护电子数据的安全。本文是关于 AES 加解密的详细介绍,包括其原理、特点、工作模式以及代码示例。
核心概念
对称加密 (Symmetric Encryption)
AES 属于对称加密,这意味着加密和解密使用同一个密钥 (Key)。
- 发送方:明文 + 密钥 $\rightarrow$ 密文
- 接收方:密文 + 密钥 $\rightarrow$ 明文
- 核心痛点:密钥的保管和传输非常关键,一旦密钥泄露,数据就不再安全。
分组密码 (Block Cipher)
AES 是一种分组密码(块加密)。它将数据切分成固定长度的数据块,然后对每个块进行加密。
- AES 的块大小固定为 128 位 (16 字节),无论密钥长度是多少。
- 如果数据长度不是 16 字节的倍数,通常需要进行填充 (Padding)(如 PKCS#7)。
密钥长度
AES 支持三种密钥长度,安全性随长度增加而提高,但运算速度略有下降(现代 CPU 上差异极小):
- AES-128:10 轮加密循环(最快,常用于移动设备)。
- AES-192:12 轮加密循环。
- AES-256:14 轮加密循环(最安全,军用/金融级标准)。
内部工作原理 (简化版)
AES 的算法核心是一个称为 SP 网络 (Substitution-Permutation Network) 的结构。它不依赖复杂的数学难题(如 RSA 的大数分解),而是通过多轮的位运算来混淆数据。
每一轮加密包含以下四个步骤:
- 字节代换 (SubBytes):通过一个非线性的 S-盒 (S-Box) 替换每个字节,起到混淆作用。
- 行移位 (ShiftRows):将矩阵中的每一行进行循环移位,打乱数据顺序。
- 列混合 (MixColumns):对每一列进行线性变换,使数据在列之间扩散(最后一轮不执行此步)。
- 轮密钥加 (AddRoundKey):将数据与当轮的子密钥进行 XOR (异或) 运算。
加密模式 (Modes of Operation)
这是使用 AES 时最重要的部分。直接使用 AES 算法只能加密一个 16 字节的块,为了加密任意长度的数据,需要选择一种“模式”。
3.1 ECB (Electronic Codebook) - 不推荐
- 原理:将数据分块,每个块独立加密。
- 缺点:相同的明文块会产生相同的密文块。无法隐藏数据模式(例如加密一张企鹅图片,ECB 模式加密后还能看出企鹅的轮廓)。
- 安全性:极低,严禁在生产环境使用。
3.2 CBC (Cipher Block Chaining) - 常用
- 原理:引入了 IV (初始化向量)。当前明文块在加密前,先与前一个密文块(或 IV)进行 XOR。
- 特点:
- 必须串行处理,无法并行加速。
- 需要填充 (Padding)。
- IV 必须随机且每次唯一。
- 应用:许多传统系统和数据库加密。
3.3 GCM (Galois/Counter Mode) - 推荐 (现代标准)
- 原理:结合了 CTR (计数器模式) 和 GMAC (认证)。
- 特点:
- AEAD (Authenticated Encryption with Associated Data):不仅加密数据,还能验证数据的完整性(防篡改)。
- 可以并行计算,速度极快。
- 不需要填充 (Padding)。
- 应用:HTTPS (TLS 1.2/1.3), VPN, SSH。
为什么选择 AES?
- 安全性高:目前没有已知的有效攻击手段能在合理时间内破解 AES(尤其是 AES-256)。
- 性能优越:现代 CPU(Intel/AMD/ARM)都有 AES-NI 指令集,硬件层面加速 AES 运算,速度非常快。
- 标准化:被 NIST 选为标准,全球通用。
实战代码示例 (Python)
在 Python 中,推荐使用 pycryptodome 库。
安装:
pip install pycryptodome示例:使用 AES-GCM 模式(最安全、推荐)
GCM 模式不需要填充,且提供完整性校验。
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
# --- 配置 ---
key = get_random_bytes(32) # 生成 256位 (32字节) 密钥
data = b`Hello, this is a secret message!` # 待加密数据 (bytes)
# ================= 加密过程 =================
def encrypt_aes_gcm(key, plaintext):
# GCM 模式下,每次加密都需要一个唯一的 nonce (类似 IV)
cipher = AES.new(key, AES.MODE_GCM)
nonce = cipher.nonce
# encrypt_and_digest 同时进行加密和生成认证标签(tag)
ciphertext, tag = cipher.encrypt_and_digest(plaintext)
return nonce, ciphertext, tag
nonce, ciphertext, tag = encrypt_aes_gcm(key, data)
print(f`密钥 (Hex): {key.hex()}`)
print(f`Nonce (Hex): {nonce.hex()}`)
print(f`密文 (Hex): {ciphertext.hex()}`)
print(f`Tag (Hex): {tag.hex()}`)
# ================= 解密过程 =================
def decrypt_aes_gcm(key, nonce, ciphertext, tag):
try:
cipher = AES.new(key, AES.MODE_GCM, nonce=nonce)
# decrypt_and_verify 解密并验证数据是否被篡改
plaintext = cipher.decrypt_and_verify(ciphertext, tag)
return plaintext
except ValueError:
return `解密失败:密钥错误或数据被篡改!`
decrypted_data = decrypt_aes_gcm(key, nonce, ciphertext, tag)
print(f`解密后数据: {decrypted_data.decode('utf-8')}`)示例:使用 AES-CBC 模式 (传统、需要填充)
如果你需要对接旧系统,可能需要 CBC。注意它需要填充。
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.Random import get_random_bytes
key = get_random_bytes(16) # 128位密钥
iv = get_random_bytes(16) # CBC 需要 16字节 IV
data = b`Hello AES CBC`
# 加密
cipher = AES.new(key, AES.MODE_CBC, iv)
# pad 将数据填充到 16 的倍数
ciphertext = cipher.encrypt(pad(data, AES.block_size))
print(f`CBC 密文: {ciphertext.hex()}`)
# 解密
cipher_dec = AES.new(key, AES.MODE_CBC, iv)
# unpad 去除填充
decrypted = unpad(cipher_dec.decrypt(ciphertext), AES.block_size)
print(f`CBC 解密: {decrypted.decode()}`)总结
- AES 是标准:如果你需要加密数据,首选 AES。
- 模式选择:
- 新系统开发首选 AES-GCM(安全、快、防篡改)。
- 兼容旧系统可能需要 AES-CBC。
- 绝对不要使用 AES-ECB。
- 随机性:
- 密钥 (Key) 必须足够随机且保密。
- 初始化向量 (IV) 或 Nonce 不需要保密,但同一个 Key 下绝对不能重复使用同一个 Nonce/IV(尤其是在 GCM 模式下,重复 Nonce 会导致密钥泄露)。
最近更新
最新评论