Python中的AES-GCM解密

在 Python 中使用 AES-GCM 进行解密是加密数据处理中的一个重要任务。AES-GCM 是一种基于 AES 的加密模式,结合了加密和认证功能,提供了数据的机密性和完整性保证。下面是对如何在 Python 中使用 AES-GCM 进行解密的详细讲解,包括概念解释、库选择、代码示例以及常见问题的解答。

1. AES-GCM 简介

AES-GCM(Galois/Counter Mode)是一种加密模式,它结合了 AES 的对称加密算法和 Galois 计数器模式,以提供数据加密和认证。AES-GCM 具有以下特点:

  • 机密性:通过 AES 算法对数据进行加密。
  • 完整性:通过 GCM 模式的认证码(Tag)确保数据在传输过程中未被篡改。

2. Python 中的 AES-GCM 解密步骤

2.1 安装 cryptography

cryptography 是 Python 中进行加密操作的标准库之一,提供了对 AES-GCM 的支持。可以通过 pip 安装:

bash
pip install cryptography

2.2 导入必要的模块

python
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend

2.3 解密数据

以下是一个完整的示例,展示如何使用 cryptography 库来解密 AES-GCM 加密的数据。

python
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend def decrypt_aes_gcm(key: bytes, nonce: bytes, ciphertext: bytes, tag: bytes) -> bytes: # 创建 AES-GCM 解密器对象 cipher = Cipher(algorithms.AES(key), modes.GCM(nonce, tag), backend=default_backend()) decryptor = cipher.decryptor() # 解密数据 plaintext = decryptor.update(ciphertext) + decryptor.finalize() return plaintext # 示例数据 key = b'\x00' * 32 # 256-bit 密钥 nonce = b'\x00' * 12 # 96-bit nonce ciphertext = b'...' # 加密的文本数据 tag = b'...' # 认证标签 # 调用解密函数 plaintext = decrypt_aes_gcm(key, nonce, ciphertext, tag) print(f"Plaintext: {plaintext.decode('utf-8')}")

代码解释

  • Cipher(algorithms.AES(key), modes.GCM(nonce, tag), backend=default_backend()):创建一个 AES-GCM 解密器对象。key 是 256 位的密钥,nonce 是 96 位的随机数(也称为 IV),tag 是 16 字节的认证标签。

  • decryptor.update(ciphertext) + decryptor.finalize():解密数据并生成明文。如果数据有任何篡改,decryptor.finalize() 将抛出异常。

2.4 从文件中读取加密数据

如果加密数据存储在文件中,您可以使用以下代码从文件中读取数据并解密:

python
def read_encrypted_file(file_path): with open(file_path, 'rb') as file: # 从文件中读取密钥、nonce、加密数据和标签 key = file.read(32) # 256-bit 密钥 nonce = file.read(12) # 96-bit nonce ciphertext = file.read(-16) # 剩余部分是加密的数据 tag = file.read(16) # 认证标签 return key, nonce, ciphertext, tag # 示例文件路径 file_path = 'encrypted_data.bin' key, nonce, ciphertext, tag = read_encrypted_file(file_path) plaintext = decrypt_aes_gcm(key, nonce, ciphertext, tag) print(f"Plaintext: {plaintext.decode('utf-8')}")

3. 常见问题与解决方案

3.1 问题:InvalidTag 异常

原因:这通常是因为提供的 tag 与实际的 ciphertext 不匹配,或者数据在传输过程中被篡改。

解决方案

  • 确保 noncetag 是从正确的加密数据中提取的。
  • 确保 key 是正确的 256 位 AES 密钥。

3.2 问题:ValueError: Ciphertext length must be greater than tag length

原因ciphertext 的长度应该比 tag 长 16 字节。

解决方案

  • 确保 ciphertext 的长度包括所有加密的数据,而不是仅仅加密的数据。

3.3 问题:TypeError: 'NoneType' object is not callable

原因cipher.decryptor() 返回了一个 None 对象,通常是因为 keynoncetag 的长度不正确。

解决方案

  • 确保所有输入数据的长度是正确的。

4. 完整示例代码

以下是一个完整的 AES-GCM 解密示例,包括加密和解密的代码:

python
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend import os # 加密函数(示例) def encrypt_aes_gcm(key: bytes, plaintext: bytes) -> (bytes, bytes, bytes): nonce = os.urandom(12) # 生成 96-bit nonce cipher = Cipher(algorithms.AES(key), modes.GCM(nonce), backend=default_backend()) encryptor = cipher.encryptor() ciphertext = encryptor.update(plaintext) + encryptor.finalize() tag = encryptor.tag # 获取认证标签 return nonce, ciphertext, tag # 解密函数 def decrypt_aes_gcm(key: bytes, nonce: bytes, ciphertext: bytes, tag: bytes) -> bytes: cipher = Cipher(algorithms.AES(key), modes.GCM(nonce, tag), backend=default_backend()) decryptor = cipher.decryptor() plaintext = decryptor.update(ciphertext) + decryptor.finalize() return plaintext # 示例数据 key = os.urandom(32) # 生成 256-bit 密钥 plaintext = b"Hello, World!" # 加密 nonce, ciphertext, tag = encrypt_aes_gcm(key, plaintext) print(f"Ciphertext: {ciphertext.hex()}") print(f"Tag: {tag.hex()}") # 解密 decrypted_plaintext = decrypt_aes_gcm(key, nonce, ciphertext, tag) print(f"Decrypted Plaintext: {decrypted_plaintext.decode('utf-8')}")

5. 参考资料

总结与关键字

总结

在 Python 中使用 AES-GCM 进行解密需要从 cryptography 库中导入相关模块,并使用 Cipher 对象来解密数据。步骤包括创建解密器、读取加密数据和标签、进行解密处理,并处理常见的错误问题。可以从文件中读取加密数据,也可以处理多种加密场景中的数据。示例代码涵盖了加密、解密以及从文件中读取数据的过程,帮助理解 AES-GCM 模式的基本应用。

关键字

Python, AES-GCM, 解密, cryptography, Cipher, algorithms.AES, modes.GCM, default_backend, 加密, 认证标签, nonce, key, ciphertext, tag, decryptor, update, finalize, os.urandom, `cryptography.hazmat