AES 加解密介绍

发布时间: 更新时间: 总字数:1765 阅读时间:4m 作者:IP:上海 网址

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 的大数分解),而是通过多轮的位运算来混淆数据。

每一轮加密包含以下四个步骤:

  1. 字节代换 (SubBytes):通过一个非线性的 S-盒 (S-Box) 替换每个字节,起到混淆作用。
  2. 行移位 (ShiftRows):将矩阵中的每一行进行循环移位,打乱数据顺序。
  3. 列混合 (MixColumns):对每一列进行线性变换,使数据在列之间扩散(最后一轮不执行此步)。
  4. 轮密钥加 (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 库。

安装:

bash
pip install pycryptodome

示例:使用 AES-GCM 模式(最安全、推荐)

GCM 模式不需要填充,且提供完整性校验。

python
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。注意它需要填充。

python
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()}`)

总结

  1. AES 是标准:如果你需要加密数据,首选 AES。
  2. 模式选择
    • 新系统开发首选 AES-GCM(安全、快、防篡改)。
    • 兼容旧系统可能需要 AES-CBC。
    • 绝对不要使用 AES-ECB
  3. 随机性
    • 密钥 (Key) 必须足够随机且保密。
    • 初始化向量 (IV) 或 Nonce 不需要保密,但同一个 Key 下绝对不能重复使用同一个 Nonce/IV(尤其是在 GCM 模式下,重复 Nonce 会导致密钥泄露)。