图片解读
核心就俩字:风险大!
ChaCha20 算法实际使用代码模板
眼见为实:ChaCha20 与 AES 的性能差距
基于 macbook pro M2 Max 芯片、Python 3.12.7 环境实测
从TLS 1.3对AES-CBC的抛弃,我们可以看到加密领域正朝着更简洁、更安全(AEAD是标配)、更高性能(硬件加持)的方向狂奔。
决策依据:
拼速度拼主流的平台?→ AES-GCM-256
拼稳定抗干扰的环境?→ ChaCha20-Poly1305
关注我,带你探索更多密码学应用干货!
附完整测试代码:
from __future__ import annotations
"""
AES-GCM 256 与 ChaCha20-Poly1305 加密算法对比演示
该脚本演示了两种现代认证加密算法的使用、性能差异和安全特性
"""
from cryptography.hazmat.primitives.ciphers.aead import AESGCM , ChaCha20Poly1305
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
import os
import timeit
from typing import Tuple , Callable , Any , Optional
def generate_random_data(size: int) -> bytes:
"""
生成指定大小的随机二进制数据
参数:
size: 要生成的随机数据大小(字节数)
返回:
随机生成的二进制数据
"""
if size <= 0 or size % 16 != 0:
size = 32
return os.urandom(size)
def derive_key(password: bytes ,
salt: Optional[ bytes ] = None ,
key_length: int = 32) -> bytes:
"""
使用 HKDF 从密码派生安全密钥
HKDF (HMAC-based Key Derivation Function) 是一种安全的密钥派生方法
它可以将弱密码(如用户输入的密码)转换为强密码学密钥
参数:
password: 原始密码(二进制格式)
salt: 可选盐值(用于增加派生密钥的随机性)
key_length: 要生成的密钥长度(字节)
返回:
派生的安全密钥
"""
# 如果没有提供盐值,生成随机盐值
if salt is None:
salt = os.urandom(16)
# 创建 HKDF 实例
# 算法:SHA-256,密钥长度,盐值,上下文信息,后端
hkdf = HKDF(
algorithm = hashes.SHA256() ,
length = key_length ,
salt = salt ,
info = b'key-derivation' ,
backend = default_backend() ,
)
# 从密码派生密钥
return hkdf.derive(password)
def aes_gcm_encrypt_decrypt(key: bytes ,
data: bytes ,
associated_data: bytes) -> bytes:
"""
AES-GCM 256 算法的加密和解密过程
步骤:
1. 生成随机 nonce (12字节)
2. 使用密钥初始化 AES-GCM
3. 用 nonce 和关联数据加密数据
4. 使用相同的 nonce 和密钥解密数据
参数:
key: 加密密钥(32字节)
data: 要加密的数据
associated_data: 关联数据(进行认证但不加密)
返回:
解密后的原始数据(用于验证算法正确性)
"""
# 生成随机 nonce (96位,这是AES-GCM的标准推荐长度)
nonce = os.urandom(12)
# 创建 AES-GCM 密码器实例
aes_gcm = AESGCM(key)
# 加密操作:使用 nonce 和关联数据加密原始数据
# 输出 = 加密后的数据 + 认证标签(16字节)
ciphertext = aes_gcm.encrypt(nonce , data , associated_data)
# 解密操作:使用相同的 nonce 和关联数据解密
decrypted_data = aes_gcm.decrypt(nonce , ciphertext , associated_data)
return decrypted_data
def cha_cha20_encrypt_decrypt(key: bytes ,
data: bytes ,
associated_data: bytes) -> bytes:
"""
ChaCha20-Poly1305 算法的加密和解密过程
步骤:
1. 生成随机 nonce (12字节)
2. 使用密钥初始化 ChaCha20-Poly1305
3. 用 nonce 和关联数据加密数据
4. 使用相同的 nonce 和密钥解密数据
参数:
key: 加密密钥(32字节)
data: 要加密的数据
associated_data: 关联数据(进行认证但不加密)
返回:
解密后的原始数据(用于验证算法正确性)
"""
# 生成随机 nonce (96位,这是ChaCha20-Poly1305的标准长度)
nonce = os.urandom(12)
# 创建 ChaCha20-Poly1305 密码器实例
cha_cha = ChaCha20Poly1305(key)
# 加密操作:使用 nonce 和关联数据加密原始数据
# 输出 = 加密后的数据 + 认证标签(16字节)
ciphertext = cha_cha.encrypt(nonce , data , associated_data)
# 解密操作:使用相同的 nonce 和关联数据解密
decrypted_data = cha_cha.decrypt(nonce , ciphertext , associated_data)
return decrypted_data
def performance_test(algorithm_func: Callable[ [ bytes , bytes , bytes ] , bytes ] ,
key: bytes ,
data: bytes ,
associated_data: bytes ,
iterations: int = 2000) -> float:
"""
执行加密算法的性能测试
方法:
1. 创建一个执行单次加密解密操作的函数
2. 预热(执行少量操作)
3. 使用 timeit 测量多次操作的平均时间
参数:
algorithm_func: 要测试的算法函数
key: 加密密钥
data: 测试数据
associated_data: 关联数据
iterations: 测试迭代次数
返回:
平均每次操作所需时间(毫秒)
"""
# 创建测试函数(无参数,调用目标算法)
def test_wrapper() -> bytes:
return algorithm_func(key , data , associated_data)
# 预热:运行5次避免初始开销影响测试结果
for _ in range(5):
_ = test_wrapper()
# 执行性能测试
time_taken = timeit.timeit(test_wrapper , number = iterations)
# 计算每次操作的平均时间(毫秒)
return (time_taken / iterations) * 1000
def demo_encryption_process(algorithm_name: str ,
algorithm: Any ,
data: bytes ,
associated_data: bytes) -> Tuple[ bytes , bytes ]:
"""
演示单个算法的加密过程
参数:
algorithm_name: 算法名称(用于打印)
algorithm: 密码算法实例(AES-GCM-256或ChaCha20Poly1305)
key: 加密密钥
data: 要加密的数据
associated_data: 关联数据
返回:
nonce: 使用的随机值
ciphertext: 加密后的数据(包含认证标签)
"""
print(f"\n{algorithm_name} 加密演示:")
print(f"原始数据: {data.decode()}")
# 生成随机 nonce
nonce = os.urandom(12)
# 加密数据
ciphertext = algorithm.encrypt(nonce , data , associated_data)
print(f"加密结果 (密文+标签): {ciphertext.hex()}")
return nonce , ciphertext
def tampering(algorithm_name: str ,
algorithm: Any ,
nonce: bytes ,
ciphertext: bytes ,
associated_data: bytes):
"""
测试数据篡改检测能力
方法:
1. 修改密文的一个字节
2. 尝试解密修改后的密文
3. 捕获并报告验证失败错误
参数:
algorithm_name: 算法名称(用于打印)
algorithm: 密码算法实例
nonce: 原始加密使用的 nonce
ciphertext: 原始密文
associated_data: 关联数据
"""
print(f"\n测试 {algorithm_name} 的篡改检测...")
try:
# 创建密文的可修改副本
tampered_ciphertext = bytearray(ciphertext)
# 修改一个字节(在位置10进行XOR修改)
tampered_ciphertext[ 10 ] ^= 0x01
# 尝试解密篡改后的数据
algorithm.decrypt(nonce , bytes(tampered_ciphertext) , associated_data)
# 如果成功,说明篡改检测失败(这不应该发生)
print("警告:篡改未被检测到!")
except Exception as e:
# 验证失败时会引发异常
print(f"{algorithm_name} 认证失败: {type(e).__name__} - {str(e)}")
def main_encryption_decryption():
"""主函数:协调整个演示过程"""
# 1. 准备测试数据和参数
password = b"my-secret-password" # 原始密码(实际应用中应使用更复杂的密码)
associated_data = b"authenticated-but-not-encrypted" # 关联数据(进行认证但不加密)
data_size = 1024 * 1024 # 1MB 测试数据
test_data = generate_random_data(data_size)
print(f"测试数据大小: {data_size / 1024:.2f} KB")
# 2. 从密码派生安全的加密密钥(32字节 = 256位)
key = derive_key(password)
print(f"使用的密钥: {key.hex()}")
# 3. 性能测试
# 测试 AES-GCM-256
print("\n性能测试 - AES-GCM-256:")
aes_time = performance_test(aes_gcm_encrypt_decrypt , key , test_data , associated_data)
print(f"加解密时间: {aes_time:.4f} 毫秒")
# 测试 ChaCha20-Poly1305
print("\n性能测试 - ChaCha20-Poly1305:")
cha_cha_time = performance_test(cha_cha20_encrypt_decrypt , key , test_data , associated_data)
print(f"加解密时间: {cha_cha_time:.4f} 毫秒")
# 性能比较
if aes_time < cha_cha_time:
ratio = cha_cha_time / aes_time
print(f"\n性能比较: AES-GCM 比 ChaCha20-Poly1305 快 {ratio:.3f}x")
else:
ratio = aes_time / cha_cha_time
print(f"\n性能比较: ChaCha20-Poly1305 比 AES-GCM 快 {ratio:.3f}x")
# 4. 加密过程演示
small_data = b"Hello, AEAD algorithms!" # 用于演示的小型数据
# 创建算法实例
aes_gcm_256 = AESGCM(key)
cha_cha_256 = ChaCha20Poly1305(key)
# 演示 AES-GCM 加密
aes_nonce , aes_ciphertext = demo_encryption_process("AES-GCM" ,
aes_gcm_256 ,
small_data ,
associated_data)
# 演示 ChaCha20-Poly1305 加密
cha_cha_nonce , cha_cha_ciphertext = demo_encryption_process("ChaCha20-Poly1305" ,
cha_cha_256 ,
small_data ,
associated_data)
# 5. 解密验证
aes_decrypted = aes_gcm_256.decrypt(aes_nonce , aes_ciphertext , associated_data)
cha_cha_decrypted = cha_cha_256.decrypt(cha_cha_nonce , cha_cha_ciphertext , associated_data)
print(f"\nAES-GCM 解密结果: {aes_decrypted.decode()}")
print(f"ChaCha20-Poly1305 解密结果: {cha_cha_decrypted.decode()}")
# 6. 篡改测试
tampering("AES-GCM" , aes_gcm_256 , aes_nonce , aes_ciphertext , associated_data)
tampering("ChaCha20-Poly1305" , cha_cha_256 , cha_cha_nonce , cha_cha_ciphertext , associated_data)
if __name__ == "__main__":
main_encryption_decryption()
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有