0Pricing
Cryptology Academy · 课时

在 Python 中使用 AES-GCM 加密与解密

正确管理随机数,实现在认证加密

在 Python 中使用 AES-GCM 加密与解密 是 CoddyKit 上的免费 Cryptology Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Cryptology Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Cryptology Academy 课程共包含 4 节课。

为什么使用 AES-GCM

AES-GCM 是一种带关联数据的认证加密(AEAD)方案。它在一次处理中同时提供机密性(AES-CTR)和完整性/真实性(GHASH MAC),是现代加密的标准方案。

GCM 组件:CTR + GHASH

AES-GCM = 计数器模式下的 AES(加密)+ GHASH 多项式 MAC(认证)。128 位认证标签会同时覆盖密文和可选的附加认证数据(AAD)。

随机数要求

对于同一个密钥,96 位随机数绝不能重复使用。重复使用随机数会彻底破坏 GCM——攻击者可以恢复认证密钥并伪造密文。请使用随机随机数,或使用计数器并进行密钥轮换。

在 Python 中使用 AES-GCM 加密

使用 hazmat 层:

import os
from cryptography.hazmat.primitives.ciphers.aead import AESGCM

# Generate a 256-bit key
key = AESGCM.generate_key(bit_length=256)
aesgcm = AESGCM(key)

# Fresh 96-bit nonce per encryption
nonce = os.urandom(12)

plaintext = b"sensitive payload"
aad = b"user_id=42"  # authenticated but not encrypted

ciphertext = aesgcm.encrypt(nonce, plaintext, aad)
print("Nonce:", nonce.hex())
print("Ciphertext+tag:", ciphertext.hex())

在 Python 中使用 AES-GCM 解密

解密会自动验证标签;验证失败时会引发 InvalidTag:

from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from cryptography.exceptions import InvalidTag

# key, nonce, ciphertext, aad from previous step
try:
    recovered = aesgcm.decrypt(nonce, ciphertext, aad)
    print("Decrypted:", recovered)
except InvalidTag:
    print("Authentication failed — ciphertext tampered!")

存储随机数与密文

存储前,将随机数置于密文之前。解密时,在字节位置 12 处分割:

def encrypt_blob(key: bytes, data: bytes, aad: bytes = b"") -> bytes:
    aesgcm = AESGCM(key)
    nonce = os.urandom(12)
    ct = aesgcm.encrypt(nonce, data, aad or None)
    return nonce + ct  # prepend nonce

def decrypt_blob(key: bytes, blob: bytes, aad: bytes = b"") -> bytes:
    aesgcm = AESGCM(key)
    nonce, ct = blob[:12], blob[12:]
    return aesgcm.decrypt(nonce, ct, aad or None)

附加认证数据(AAD)

AAD 会经过认证,但不会被加密。请使用它将密文绑定到具体上下文:用户 ID、记录 ID、API 版本。这样可以防止攻击者将有效密文转移到其他上下文中。

使用低级 Cipher API

对于流式加密或原地加密,请直接使用带 GCM 模式的 Cipher API:

from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes

key = os.urandom(32)
nonce = os.urandom(12)
cipher = Cipher(algorithms.AES(key), modes.GCM(nonce))
encryptor = cipher.encryptor()
encryptor.authenticate_additional_data(b"aad-value")
ct = encryptor.update(b"hello world") + encryptor.finalize()
tag = encryptor.tag
print("Tag:", tag.hex())

防止随机数误用:AES-GCM-SIV

AES-GCM-SIV(RFC 8452)可以抵抗随机数误用:重复使用随机数会泄露两个明文相同这一事实,但不会破坏真实性。如果难以保证随机数唯一,请优先使用它。

加密前进行密钥派生

绝不要直接使用原始密码作为 AES 密钥。请使用 Argon2 或 HKDF 派生密钥:

from cryptography.hazmat.primitives.kdf.hkdf import HKDF
from cryptography.hazmat.primitives import hashes
import os

master_secret = b"shared_secret_from_ECDH"
salt = os.urandom(16)
kdf = HKDF(algorithm=hashes.SHA256(), length=32, salt=salt, info=b"aes-gcm-key")
aes_key = kdf.derive(master_secret)
print("Derived AES key:", aes_key.hex())

性能注意事项

AES-NI 硬件加速使 AES-GCM 极其快速(现代 CPU 上约为 1–4 GB/s)。Python 的 cryptography 使用 OpenSSL,而 OpenSSL 会利用 AES-NI。对于大于 100 MB 的文件,请使用低级 Cipher API 进行分块流式处理。

知识检查

如果在同一个密钥下使用 AES-GCM 两次相同的随机数,会发生什么?

课程回顾

AES-GCM 可在一次处理中提供认证加密。每次加密都应使用新的 96 位随机随机数。存储时将随机数置于密文之前。AAD 会将密文绑定到具体上下文。AES-GCM-SIV 可以抵抗随机数误用。请使用 HKDF 派生密钥,绝不要使用原始密码。

常见问题解答

「在 Python 中使用 AES-GCM 加密与解密」课时是免费的吗?

是的 — 「在 Python 中使用 AES-GCM 加密与解密」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Cryptology Academy 课程的其余内容,请升级到 CoddyKit PRO。 Cryptology Academy 课程共包含 4 节课。

「在 Python 中使用 AES-GCM 加密与解密」这节课中我会学到什么?

正确管理随机数,实现在认证加密 你通过在浏览器中直接运行的动手代码来练习 Cryptology Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Cryptology Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Cryptology Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「在 Python 中使用 AES-GCM 加密与解密」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Cryptology Academy 课中编写并运行代码吗?

能。每节 Cryptology Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. Python 密码学库概览
  2. 在 Python 中使用 AES-GCM 加密与解密
  3. Python 中的 RSA 与 ECDSA 密钥对
  4. 常见 Python 加密陷阱与安全模式
← 返回 Cryptology Academy