代码片段:
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
import base64
def string_to_uint8_array(data: str) -> bytes:
"""将字符串转换为字节数组 (类似 JavaScript 的 stringToUint8Array)"""
return data.encode()
def aes_gcm_encrypt_fixed(key: bytes, plaintext: str, nonce: bytes, associated_data: bytes) -> dict:
"""
使用固定密钥、随机数、关联数据的 AES-GCM 加密
:param key: 密钥 (16, 24, or 32 bytes)
:param plaintext: 明文字符串
:param nonce: 随机数 (IV, 12 bytes)
:param associated_data: 关联数据 (AAD)
:return: 包含密文和认证标签的字典
"""
aes_gcm = Cipher(algorithms.AES(key), modes.GCM(nonce), backend=default_backend()).encryptor()
if associated_data:
aes_gcm.authenticate_additional_data(associated_data)
ciphertext = aes_gcm.update(string_to_uint8_array(plaintext)) + aes_gcm.finalize()
return {
"ciphertext": ciphertext,
"tag": aes_gcm.tag,
}
def aes_gcm_decrypt_fixed(key: bytes, ciphertext: bytes, nonce: bytes, tag: bytes, associated_data: bytes) -> str:
"""
使用固定密钥、随机数、关联数据的 AES-GCM 解密
:param key: 密钥
:param ciphertext: 密文
:param nonce: 随机数 (IV, 12 bytes)
:param tag: 认证标签
:param associated_data: 关联数据 (AAD)
:return: 解密后的明文字符串
"""
aes_gcm = Cipher(algorithms.AES(key), modes.GCM(nonce, tag), backend=default_backend()).decryptor()
if associated_data:
aes_gcm.authenticate_additional_data(associated_data)
plaintext = aes_gcm.update(ciphertext) + aes_gcm.finalize()
return plaintext.decode()
# 测试代码
if __name__ == "__main__":
# 固定密钥(与 JavaScript 中的 "r*************" 对应)
key = string_to_uint8_array("r**********") # 必须是 16 字节
# 固定随机数(与 JavaScript 中的 Uint8Array([107, -6, -128, -1, ...]) 对应)
nonce = bytes([107, 250, 128, 255, 71, 217, 212, 105, 222, 129, 215, 168])
# 固定附加数据(与 JavaScript 中的 Uint8Array([97, 115, ...]) 对应)
associated_data = bytes([97, 115, 115, 111, 99, 105, 97, 116, 105, 111, 110])
plaintext = "123456" # 明文字符串
# 加密
encrypted_data = aes_gcm_encrypt_fixed(key, plaintext, nonce, associated_data)
print(f"Ciphertext (Base64): {base64.b64encode(encrypted_data['ciphertext']).decode()}")
print(f"Tag (Base64): {base64.b64encode(encrypted_data['tag']).decode()}")
res = base64.b64encode(encrypted_data['ciphertext']).decode() +base64.b64encode(encrypted_data['tag']).decode()
print("final:",res)
# 解密
decrypted_text = aes_gcm_decrypt_fixed(
key,
encrypted_data['ciphertext'],
nonce,
encrypted_data['tag'],
associated_data,
)
print(f"Decrypted Text: {decrypted_text}")