对称加密算法(AES、ChaCha20和SM4)Python实现——密码学基础(Python出现No module named “Crypto” 解决方案)
文章目录
- 一、对称加密算法基础
- 1.1 对称加密算法的基本原理
- 1.2 对称加密的主要工作模式
- 二、AES加密算法详解
- 2.1 AES基本介绍
- 2.2 AES加密过程
- 2.3 Python中实现AES加密
- Python出现No module named “Crypto” 解决方案
- 2.4 AES的安全考量
- 三、ChaCha20加密算法
- 3.1 ChaCha20基本介绍
- 3.2 ChaCha20加密过程
- 3.3 Python中实现ChaCha20加密
- 3.4 ChaCha20的优势与应用场景
- 四、SM4加密算法
- 4.1 SM4基本介绍
- 4.2 SM4加密过程
- 4.3 Python中实现SM4加密
- 4.4 SM4的安全考量与应用场景
- 五、对称加密算法的性能比较
- 5.1 性能测试代码
- 5.2 性能比较结果与分析
- 六、实际应用中的对称加密选择指南
- 6.1 应用场景决策树
- 6.2 常见系统中的应用示例
- 6.3 对称加密的最佳实践
- 七、对称加密的未来发展趋势
- 八、总结与实践建议
- 附录:对称加密技术专业术语表
续篇:非对称加密算法(RSA、ECC、SM2)——密码学基础
一、对称加密算法基础
对称加密是现代密码学的基础之一,其特点是加密和解密使用相同的密钥。对称加密具有实现简单、计算效率高、加密强度可靠等优点,在数据保护领域被广泛应用。本章将详细介绍三种主要的对称加密算法:AES、ChaCha20和SM4,并通过Python代码(为了方便)示例展示其实际应用。
1.1 对称加密算法的基本原理
对称加密算法基于以下核心原则:
- 加密和解密使用相同的密钥
- 加密算法必须足够复杂以抵抗密码分析
- 密钥必须保密,而算法通常是公开的
对称加密算法分为两大类:
- 块加密:将明文分成固定长度的块,逐块加密
- 流加密:逐比特或逐字节加密数据流
1.2 对称加密的主要工作模式
电子密码本模式(ECB):
- 最简单的加密模式,将明文分成固定大小的块,每块独立加密
- 优点:实现简单,支持并行处理
- 缺点:相同的明文块产生相同的密文块,缺乏语义安全性
密码块链接模式(CBC):
- 每个明文块在加密前与前一个密文块进行XOR操作
- 需要初始向量(IV)来加密第一个块
- 优点:相同明文产生不同密文,提高安全性
- 缺点:不支持并行加密,受到填充oracle攻击
密码反馈模式(CFB):
- 将块密码转换为流密码
- 优点:不需要填充,错误不会扩散
- 缺点:不支持并行加密
输出反馈模式(OFB):
- 生成密钥流,与明文XOR生成密文
- 优点:预计算密钥流,不扩散错误
- 缺点:不支持随机访问,对初始向量敏感
计数器模式(CTR):
- 使用递增计数器生成密钥流
- 优点:支持并行处理,无需填充
- 缺点:需要确保计数器不重复
伽罗瓦/计数器模式(GCM):
- 结合CTR模式和认证功能
- 优点:提供加密和认证,支持附加验证数据(AAD)
- 缺点:实现复杂,对IV重用敏感
二、AES加密算法详解
2.1 AES基本介绍
高级加密标准(Advanced Encryption Standard, AES)是美国国家标准与技术研究院(NIST)在2001年确立的加密标准,用于替代老旧的DES算法。AES是一种基于替代-置换网络的块加密算法,具有以下特点:
- 分组大小:128位(16字节)
- 密钥长度:128位、192位、256位
- 轮数:分别为10轮、12轮、14轮
- 设计结构:基于SP网络(Substitution-Permutation Network)
2.2 AES加密过程
AES加密过程包括以下步骤:
- 初始轮密钥加:将初始轮密钥与明文块异或
- 主轮转换:
- SubBytes:通过S盒替换每个字节
- ShiftRows:循环移位操作
- MixColumns:列混合变换
- AddRoundKey:轮密钥加
- 最终轮:不包含MixColumns步骤
2.3 Python中实现AES加密
使用PyCryptodome库实现AES-CBC模式
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.Random import get_random_bytes
import base64def aes_encrypt_cbc(plaintext, key):"""使用AES-CBC模式加密数据参数:plaintext (bytes): 要加密的数据key (bytes): 16, 24 或 32字节的密钥返回:tuple: (iv, ciphertext) 初始向量和密文"""# 创建一个AES密码对象,CBC模式iv = get_random_bytes(AES.block_size) # 生成随机初始向量cipher = AES.new(key, AES.MODE_CBC, iv)# 对数据进行填充并加密padded_data = pad(plaintext, AES.block_size)ciphertext = cipher.encrypt(padded_data)return iv, ciphertextdef aes_decrypt_cbc(iv, ciphertext, key):"""使用AES-CBC模式解密数据参数:iv (bytes): 初始向量ciphertext (bytes): 密文key (bytes): 16, 24 或 32字节的密钥返回:bytes: 解密后的明文"""# 创建一个AES密码对象,CBC模式cipher = AES.new(key, AES.MODE_CBC, iv)# 解密数据并去除填充padded_plaintext = cipher.decrypt(ciphertext)plaintext = unpad(padded_plaintext, AES.block_size)return plaintext# 示例用法
def aes_cbc_example():# 生成一个随机的256位密钥key = get_random_bytes(32) # 32字节 = 256位# 使用 UTF-8 编码将中文字符串转换为字节message = "这是一条需要加密的重要数据".encode('utf-8')# 加密iv, ciphertext = aes_encrypt_cbc(message, key)# 将结果转换为Base64以便于打印iv_b64 = base64.b64encode(iv).decode('utf-8')ciphertext_b64 = base64.b64encode(ciphertext).decode('utf-8')print(f"原始消息: {message.decode('utf-8')}")print(f"密钥(Base64): {base64.b64encode(key).decode('utf-8')}")print(f"初始向量(IV): {iv_b64}")print(f"加密后的密文: {ciphertext_b64}")# 解密decrypted = aes_decrypt_cbc(iv, ciphertext, key)print(f"解密后的消息: {decrypted.decode('utf-8')}")# 运行示例
aes_cbc_example()
Python出现No module named “Crypto” 解决方案
参考链接:Python出现No module named “Crypto” 解决方案
可用sys查看安装到哪了,然后手动将crypto改为Crypto便可执行!
实现AES-GCM模式(提供认证加密)
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
import base64def aes_encrypt_gcm(plaintext, key, associated_data=None):"""使用AES-GCM模式加密数据参数:plaintext (bytes): 要加密的数据key (bytes): 16, 24 或 32字节的密钥associated_data (bytes, optional): 附加认证数据返回:tuple: (nonce, ciphertext, tag) 随机数、密文和认证标签"""# 创建一个AES密码对象,GCM模式nonce = get_random_bytes(12) # GCM推荐使用12字节的noncecipher = AES.new(key, AES.MODE_GCM, nonce=nonce)# 添加附加认证数据(如果有)if associated_data:cipher.update(associated_data)# 加密并获取认证标签ciphertext, tag = cipher.encrypt_and_digest(plaintext)return nonce, ciphertext, tagdef aes_decrypt_gcm(nonce, ciphertext, tag, key, associated_data=None):"""使用AES-GCM模式解密数据参数:nonce (bytes): 随机数ciphertext (bytes): 密文tag (bytes): 认证标签key (bytes): 16, 24 或 32字节的密钥associated_data (bytes, optional): 附加认证数据返回:bytes: 解密后的明文,如果认证失败则抛出异常"""# 创建一个AES密码对象,GCM模式cipher = AES.new(key, AES.MODE_GCM, nonce=nonce)# 添加附加认证数据(如果有)if associated_data:cipher.update(associated_data)# 解密并验证plaintext = cipher.decrypt_and_verify(ciphertext, tag)return plaintext# 示例用法
def aes_gcm_example():# 生成一个随机的256位密钥key = get_random_bytes(32) # 32字节 = 256位message = b"这是一条需要加密和认证的重要数据"aad = b"附加认证数据 - 不会被加密但会被认证"# 加密nonce, ciphertext, tag = aes_encrypt_gcm(message, key, aad)# 将结果转换为Base64以便于打印nonce_b64 = base64.b64encode(nonce).decode('utf-8')ciphertext_b64 = base64.b64encode(ciphertext).decode('utf-8')tag_b64 = base64.b64encode(tag).decode('utf-8')print(f"原始消息: {message.decode('utf-8')}")print(f"附加认证数据: {aad.decode('utf-8')}")print(f"密钥(Base64): {base64.b64encode(key).decode('utf-8')}")print(f"随机数(Nonce): {nonce_b64}")print(f"加密后的密文: {ciphertext_b64}")print(f"认证标签: {tag_b64}")# 解密try:decrypted = aes_decrypt_gcm(nonce, ciphertext, tag, key, aad)print(f"解密后的消息: {decrypted.decode('utf-8')}")except ValueError:print("认证失败!数据可能被篡改。")# 运行示例
aes_gcm_example()
2.4 AES的安全考量
-
密钥管理:
- 避免硬编码密钥
- 考虑使用密钥派生函数(KDF),如PBKDF2、Argon2
- 定期轮换密钥
-
工作模式选择:
- 避免使用ECB模式,它无法提供语义安全性
- 对于大多数场景,推荐GCM模式(提供认证)或CTR模式
- 对于不需要随机访问的场景,CBC模式也是可接受的
-
初始向量(IV)处理:
- 确保IV是随机的(CBC)或不重用的(CTR/GCM)
- IV不需要保密,但需要与密文一起传输
-
认证:
- 最好使用认证加密(AE)或带关联数据的认证加密(AEAD),如GCM模式
- 如果使用非认证模式,应单独实现认证机制(如HMAC)
-
填充:
- 使用安全的填充方案,如PKCS#7
- 注意填充oracle攻击风险
三、ChaCha20加密算法
3.1 ChaCha20基本介绍
ChaCha20是由Daniel J. Bernstein设计的流密码,是Salsa20算法的改进版本。作为一种流加密算法,它具有以下特点:
- 密钥长度:256位(32字节)
- Nonce长度:96位(12字节)
- 计数器长度:32位
- 基于ARX(Add-Rotate-XOR)操作,优化了软件实现性能
- 抵抗时序攻击的能力强
- 被IETF选为TLS 1.3的标准算法之一
3.2 ChaCha20加密过程
ChaCha20加密过程基于以下步骤:
- 初始化一个4×4的32位字矩阵,包含常量、密钥、计数器和nonce
- 对矩阵进行20轮变换(10轮内部变换)
- 将变换后的矩阵与初始矩阵相加
- 生成密钥流,与明文进行XOR操作
3.3 Python中实现ChaCha20加密
使用PyCryptodome库实现ChaCha20
from Crypto.Cipher import ChaCha20
from Crypto.Random import get_random_bytes
import base64def chacha20_encrypt(plaintext, key):"""使用ChaCha20加密数据参数:plaintext (bytes): 要加密的数据key (bytes): 32字节的密钥返回:tuple: (nonce, ciphertext) 随机数和密文"""# 生成随机noncenonce = get_random_bytes(12) # 12字节 = 96位# 创建ChaCha20密码对象cipher = ChaCha20.new(key=key, nonce=nonce)# 加密数据ciphertext = cipher.encrypt(plaintext)return nonce, ciphertextdef chacha20_decrypt(nonce, ciphertext, key):"""使用ChaCha20解密数据参数:nonce (bytes): 随机数ciphertext (bytes): 密文key (bytes): 32字节的密钥返回:bytes: 解密后的明文"""# 创建ChaCha20密码对象cipher = ChaCha20.new(key=key, nonce=nonce)# 解密数据plaintext = cipher.decrypt(ciphertext)return plaintext# 示例用法
def chacha20_example():# 生成一个随机的256位密钥key = get_random_bytes(32) # 32字节 = 256位# 使用UTF-8编码将中文字符串转换为字节message = "这是一条使用ChaCha20加密的重要数据".encode('utf-8')# 加密nonce, ciphertext = chacha20_encrypt(message, key)# 将结果转换为Base64以便于打印nonce_b64 = base64.b64encode(nonce).decode('utf-8')ciphertext_b64 = base64.b64encode(ciphertext).decode('utf-8')print(f"原始消息: {message.decode('utf-8')}")print(f"密钥(Base64): {base64.b64encode(key).decode('utf-8')}")print(f"随机数(Nonce): {nonce_b64}")print(f"加密后的密文: {ciphertext_b64}")# 解密decrypted = chacha20_decrypt(nonce, ciphertext, key)print(f"解密后的消息: {decrypted.decode('utf-8')}")# 运行示例
chacha20_example()
同理,也可以加入附加认证数据 - 不会被加密但会被认证
3.4 ChaCha20的优势与应用场景
-
性能优势:
- 在没有硬件加速的情况下,比AES更快
- 尤其适合移动设备和低功耗环境
- 易于实现无分支代码,抵抗侧信道攻击
-
安全性:
- 被广泛分析且被认为是安全的
- 与Poly1305结合提供认证加密
- 支持大量数据加密且不需要分块
-
应用场景:
- TLS 1.3协议
- 移动应用加密
- VPN和安全通信
- 嵌入式系统和IoT设备
四、SM4加密算法
4.1 SM4基本介绍
SM4是中国商用密码标准,原名"SMS4",是无线局域网标准的分组数据算法。其特点包括:
- 分组大小:128位(16字节)
- 密钥长度:128位(16字节)
- 轮数:32轮
- 设计结构:非平衡Feistel网络
SM4是中国密码局批准的唯一分组密码算法,在中国的政府、金融和商业应用中广泛使用。
4.2 SM4加密过程
SM4加密过程包括以下步骤:
- 密钥扩展:从128位主密钥生成32个轮密钥
- 数据处理:
- 将128位数据块分为4个32位字
- 进行32轮变换,每轮使用一个轮密钥
- 变换包括非线性S盒替代和线性变换
4.3 Python中实现SM4加密
使用gmssl库实现SM4-ECB模式
from gmssl.sm4 import CryptSM4, SM4_ENCRYPT, SM4_DECRYPT
import base64def sm4_encrypt_ecb(plaintext, key):"""使用SM4-ECB模式加密数据参数:plaintext (bytes): 要加密的数据key (bytes): 16字节的密钥返回:bytes: 加密后的密文"""# 创建SM4加密器crypt_sm4 = CryptSM4()crypt_sm4.set_key(key, SM4_ENCRYPT)# 加密数据ciphertext = crypt_sm4.crypt_ecb(plaintext)return ciphertextdef sm4_decrypt_ecb(ciphertext, key):"""使用SM4-ECB模式解密数据参数:ciphertext (bytes): 密文key (bytes): 16字节的密钥返回:bytes: 解密后的明文"""# 创建SM4解密器crypt_sm4 = CryptSM4()crypt_sm4.set_key(key, SM4_DECRYPT)# 解密数据plaintext = crypt_sm4.crypt_ecb(ciphertext)return plaintext# 示例用法
def sm4_ecb_example():# 16字节的密钥key = b'1234567890abcdef'# 确保数据是16字节的倍数(ECB模式需要)message = b'This is a Chinese SM4 algorithm test message.'# 简单的填充(实际应用中应使用PKCS#7等标准填充)padded_message = message + b'\x00' * (16 - len(message) % 16) if len(message) % 16 != 0 else message# 加密ciphertext = sm4_encrypt_ecb(padded_message, key)# 将结果转换为Base64以便于打印ciphertext_b64 = base64.b64encode(ciphertext).decode('utf-8')print(f"原始消息: {message.decode('utf-8')}")print(f"密钥: {key.decode('utf-8')}")print(f"加密后的密文(Base64): {ciphertext_b64}")# 解密decrypted = sm4_decrypt_ecb(ciphertext, key)print(f"解密后的消息: {decrypted.rstrip(b'\x00').decode('utf-8')}")# 运行示例
sm4_ecb_example()
4.4 SM4的安全考量与应用场景
-
安全性考量:
- 需要使用随机生成的IV
- 避免使用ECB模式,优先选择CBC、CTR等模式
- 需要实现合适的填充方案,如PKCS#7
- 密钥管理同样重要
-
标准兼容性:
- 符合中国密码行业标准
- 政府和金融机构的合规性要求
- 与其他国密算法(如SM2、SM3)配套使用
-
应用场景:
- 国内银行金融应用
- 政府部门信息系统
- 工业控制系统
- 电子政务和电子商务应用
五、对称加密算法的性能比较
5.1 性能测试代码
以下是对AES、ChaCha20和SM4三种算法进行性能比较的Python代码:
import time
from Crypto.Cipher import AES, ChaCha20
from Crypto.Util.Padding import pad, unpad
from Crypto.Random import get_random_bytes
from gmssl.sm4 import CryptSM4, SM4_ENCRYPT, SM4_DECRYPTdef measure_performance(encrypt_func, decrypt_func, data_size_mb=10, iterations=5):"""测量加密和解密的性能"""# 创建测试数据data_size_bytes = data_size_mb * 1024 * 1024data = get_random_bytes(data_size_bytes)# 测量加密性能encrypt_times = []decrypt_times = []encrypted_data = Nonefor _ in range(iterations):# 加密性能start_time = time.time()encrypted_data = encrypt_func(data)encrypt_time = time.time() - start_timeencrypt_times.append(encrypt_time)# 解密性能start_time = time.time()decrypt_func(encrypted_data)decrypt_time = time.time() - start_timedecrypt_times.append(decrypt_time)# 计算平均性能avg_encrypt_time = sum(encrypt_times) / len(encrypt_times)avg_decrypt_time = sum(decrypt_times) / len(decrypt_times)encrypt_speed = data_size_mb / avg_encrypt_timedecrypt_speed = data_size_mb / avg_decrypt_timereturn {'avg_encrypt_time': avg_encrypt_time,'avg_decrypt_time': avg_decrypt_time,'encrypt_speed_mbps': encrypt_speed,'decrypt_speed_mbps': decrypt_speed}# AES-CBC 测试函数
def aes_cbc_encrypt(data):key = get_random_bytes(32) # 256位密钥iv = get_random_bytes(AES.block_size)padded_data = pad(data, AES.block_size)cipher = AES.new(key, AES.MODE_CBC, iv)return (iv, cipher.encrypt(padded_data), key)def aes_cbc_decrypt(encrypted_data):iv, ciphertext, key = encrypted_datacipher = AES.new(key, AES.MODE_CBC, iv)padded_plaintext = cipher.decrypt(ciphertext)return unpad(padded_plaintext, AES.block_size)# AES-GCM 测试函数
def aes_gcm_encrypt(data):key = get_random_bytes(32) # 256位密钥cipher = AES.new(key, AES.MODE_GCM)ciphertext, tag = cipher.encrypt_and_digest(data)return (cipher.nonce, ciphertext, tag, key)def aes_gcm_decrypt(encrypted_data):nonce, ciphertext, tag, key = encrypted_datacipher = AES.new(key, AES.MODE_GCM, nonce=nonce)return cipher.decrypt_and_verify(ciphertext, tag)# ChaCha20 测试函数
def chacha20_encrypt(data):key = get_random_bytes(32)nonce = get_random_bytes(12)cipher = ChaCha20.new(key=key, nonce=nonce)return (nonce, cipher.encrypt(data), key)def chacha20_decrypt(encrypted_data):nonce, ciphertext, key = encrypted_datacipher = ChaCha20.new(key=key, nonce=nonce)return cipher.decrypt(ciphertext)# ChaCha20-Poly1305 测试函数
def chacha20_poly1305_encrypt(data):from Crypto.Cipher import ChaCha20_Poly1305key = get_random_bytes(32)cipher = ChaCha20_Poly1305.new(key=key)ciphertext, tag = cipher.encrypt_and_digest(data)return (cipher.nonce, ciphertext, tag, key)def chacha20_poly1305_decrypt(encrypted_data):from Crypto.Cipher import ChaCha20_Poly1305nonce, ciphertext, tag, key = encrypted_datacipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)return cipher.decrypt_and_verify(ciphertext, tag)# SM4-CBC 测试函数
def sm4_cbc_encrypt(data):key = get_random_bytes(16)iv = get_random_bytes(16)# 确保数据是16字节的倍数if len(data) % 16 != 0:data = data + b'\x00' * (16 - len(data) % 16)crypt_sm4 = CryptSM4()crypt_sm4.set_key(key, SM4_ENCRYPT)ciphertext = crypt_sm4.crypt_cbc(iv, data)return (iv, ciphertext, key)def sm4_cbc_decrypt(encrypted_data):iv, ciphertext, key = encrypted_datacrypt_sm4 = CryptSM4()crypt_sm4.set_key(key, SM4_DECRYPT)return crypt_sm4.crypt_cbc(iv, ciphertext)# 执行性能测试
def run_performance_tests():data_size_mb = 5 # 使用5MB的数据进行测试iterations = 3 # 每个测试重复3次取平均值print(f"性能测试: 处理{data_size_mb}MB数据,重复{iterations}次")# 测试AES-CBCaes_cbc_perf = measure_performance(aes_cbc_encrypt, aes_cbc_decrypt, data_size_mb, iterations)print("\nAES-CBC性能:")print(f" 加密: {aes_cbc_perf['avg_encrypt_time']:.4f}秒 ({aes_cbc_perf['encrypt_speed_mbps']:.2f} MB/s)")print(f" 解密: {aes_cbc_perf['avg_decrypt_time']:.4f}秒 ({aes_cbc_perf['decrypt_speed_mbps']:.2f} MB/s)")# 测试AES-GCMaes_gcm_perf = measure_performance(aes_gcm_encrypt, aes_gcm_decrypt, data_size_mb, iterations)print("\nAES-GCM性能:")print(f" 加密: {aes_gcm_perf['avg_encrypt_time']:.4f}秒 ({aes_gcm_perf['encrypt_speed_mbps']:.2f} MB/s)")print(f" 解密: {aes_gcm_perf['avg_decrypt_time']:.4f}秒 ({aes_gcm_perf['decrypt_speed_mbps']:.2f} MB/s)")# 测试ChaCha20chacha20_perf = measure_performance(chacha20_encrypt, chacha20_decrypt, data_size_mb, iterations)print("\nChaCha20性能:")print(f" 加密: {chacha20_perf['avg_encrypt_time']:.4f}秒 ({chacha20_perf['encrypt_speed_mbps']:.2f} MB/s)")print(f" 解密: {chacha20_perf['avg_decrypt_time']:.4f}秒 ({chacha20_perf['decrypt_speed_mbps']:.2f} MB/s)")# 测试ChaCha20-Poly1305chacha20_poly1305_perf = measure_performance(chacha20_poly1305_encrypt, chacha20_poly1305_decrypt, data_size_mb, iterations)print("\nChaCha20-Poly1305性能:")print(f" 加密: {chacha20_poly1305_perf['avg_encrypt_time']:.4f}秒 ({chacha20_poly1305_perf['encrypt_speed_mbps']:.2f} MB/s)")print(f" 解密: {chacha20_poly1305_perf['avg_decrypt_time']:.4f}秒 ({chacha20_poly1305_perf['decrypt_speed_mbps']:.2f} MB/s)")# 测试SM4-CBCsm4_cbc_perf = measure_performance(sm4_cbc_encrypt, sm4_cbc_decrypt, data_size_mb, iterations)print("\nSM4-CBC性能:")print(f" 加密: {sm4_cbc_perf['avg_encrypt_time']:.4f}秒 ({sm4_cbc_perf['encrypt_speed_mbps']:.2f} MB/s)")print(f" 解密: {sm4_cbc_perf['avg_decrypt_time']:.4f}秒 ({sm4_cbc_perf['decrypt_speed_mbps']:.2f} MB/s)")# 运行性能测试
if __name__ == "__main__":run_performance_tests()
5.2 性能比较结果与分析
实践下来,不一定,但SM4-CBC确实最慢。
在典型的现代计算机上,上述代码的性能测试结果可能如下(结果会因硬件、操作系统和库的实现而异):
算法 | 加密速度 (MB/s) | 解密速度 (MB/s) | 特点 |
---|---|---|---|
AES-CBC | 180-220 | 190-230 | 硬件加速支持广泛 |
AES-GCM | 150-180 | 160-190 | 提供认证,略慢于CBC |
ChaCha20 | 250-300 | 250-300 | 软件实现性能优秀 |
ChaCha20-Poly1305 | 200-250 | 210-260 | 提供认证,比AES-GCM快 |
SM4-CBC | 80-120 | 80-120 | 无硬件加速,最慢 |
性能分析:
-
硬件加速影响:
- AES在现代CPU上通常有硬件加速指令集(AES-NI),在有硬件支持的环境中性能极佳
- ChaCha20不依赖硬件加速,在纯软件实现中通常比AES快
- SM4目前很少有硬件加速支持,通常是纯软件实现,性能较低
-
认证加密开销:
- 带认证的加密模式(GCM, Poly1305)比纯加密模式略慢
- 认证计算增加了约10-20%的处理时间
- 安全性提升值得这一性能代价
-
各种设备的表现:
- 在高端桌面/服务器:AES-NI加速的AES通常最快
- 在移动设备/低功耗设备:ChaCha20通常表现更好
- 在需要国密合规的系统:SM4是唯一选择,尽管性能较低
六、实际应用中的对称加密选择指南
6.1 应用场景决策树
以下是选择对称加密算法的决策树:
-
是否需要合规性?
- 需要中国密码标准合规性 → 选择SM4
- 需要FIPS合规性 → 选择AES
- 无特殊合规要求 → 继续下一步
-
运行环境是什么?
- 具有AES硬件加速的环境 → 优先考虑AES
- 移动设备/嵌入式系统 → 优先考虑ChaCha20
- 跨平台环境 → 两者都可以,根据具体需求选择
-
是否需要认证加密?
- 需要 → 选择AES-GCM或ChaCha20-Poly1305
- 不需要(将单独实现认证)→ 选择AES-CBC/CTR或ChaCha20
-
数据量和性能需求如何?
- 大量数据,高性能需求 → 根据环境选择AES(硬件加速)或ChaCha20
- 少量数据,性能不敏感 → 任意选择均可
6.2 常见系统中的应用示例
TLS 1.3中的对称加密
TLS 1.3协议中支持以下对称加密算法:
TLS_AES_128_GCM_SHA256 - 使用AES-128-GCM
TLS_AES_256_GCM_SHA384 - 使用AES-256-GCM
TLS_CHACHA20_POLY1305_SHA256 - 使用ChaCha20-Poly1305
在大多数现代TLS实现中,优先顺序通常为:
- 如果客户端CPU支持AES-NI,则选择AES-GCM
- 否则,选择ChaCha20-Poly1305(特别是移动设备)
文件加密应用
针对文件加密的Python示例:
import os
import json
import base64
from cryptography.hazmat.primitives.ciphers.aead import AESGCM, ChaCha20Poly1305
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives import hashesdef derive_key(password, salt, key_length=32):"""从密码派生加密密钥"""kdf = PBKDF2HMAC(algorithm=hashes.SHA256(),length=key_length,salt=salt,iterations=100000,)return kdf.derive(password.encode())def encrypt_file(file_path, password, algorithm='AES-GCM'):"""加密文件参数:file_path: 要加密的文件路径password: 用户密码algorithm: 'AES-GCM' 或 'ChaCha20-Poly1305'"""# 读取文件内容with open(file_path, 'rb') as f:plaintext = f.read()# 生成随机盐值和noncesalt = os.urandom(16)nonce = os.urandom(12)# 从密码派生密钥key = derive_key(password, salt)# 加密数据if algorithm == 'AES-GCM':cipher = AESGCM(key)ciphertext = cipher.encrypt(nonce, plaintext, None)elif algorithm == 'ChaCha20-Poly1305':cipher = ChaCha20Poly1305(key)ciphertext = cipher.encrypt(nonce, plaintext, None)else:raise ValueError("不支持的算法,请使用 'AES-GCM' 或 'ChaCha20-Poly1305'")# 创建输出文件名output_file = file_path + '.enc'# 构建元数据metadata = {'algorithm': algorithm,'salt': base64.b64encode(salt).decode('utf-8'),'nonce': base64.b64encode(nonce).decode('utf-8'),}# 将元数据和密文写入文件with open(output_file, 'wb') as f:# 写入JSON元数据(UTF-8编码)和一个换行符f.write(json.dumps(metadata).encode('utf-8') + b'\n')# 写入加密的文件内容f.write(ciphertext)return output_filedef decrypt_file(encrypted_file_path, password):"""解密文件参数:encrypted_file_path: 加密文件的路径password: 用户密码"""# 读取加密文件with open(encrypted_file_path, 'rb') as f:# 读取第一行作为JSON元数据metadata_line = f.readline()# 读取剩余内容作为密文ciphertext = f.read()# 解析元数据metadata = json.loads(metadata_line.decode('utf-8'))algorithm = metadata['algorithm']salt = base64.b64decode(metadata['salt'])nonce = base64.b64decode(metadata['nonce'])# 从密码派生密钥key = derive_key(password, salt)# 解密数据try:if algorithm == 'AES-GCM':cipher = AESGCM(key)plaintext = cipher.decrypt(nonce, ciphertext, None)elif algorithm == 'ChaCha20-Poly1305':cipher = ChaCha20Poly1305(key)plaintext = cipher.decrypt(nonce, ciphertext, None)else:raise ValueError(f"不支持的算法: {algorithm}")except Exception as e:raise ValueError("解密失败:密码错误或文件已损坏") from e# 创建输出文件名(移除.enc扩展名)output_file = encrypted_file_path.rsplit('.enc', 1)[0]if output_file == encrypted_file_path:output_file = encrypted_file_path + '.decrypted'# 写入解密后的内容with open(output_file, 'wb') as f:f.write(plaintext)return output_file# 使用示例
def file_encryption_example():# 加密文件encrypt_file('example.txt', 'secure_password', 'ChaCha20-Poly1305')# 解密文件decrypt_file('example.txt.enc', 'secure_password')if __name__ == "__main__":file_encryption_example()
6.3 对称加密的最佳实践
-
密钥管理:
- 永远不要硬编码密钥
- 使用密钥派生函数(KDF)从密码生成密钥
- 考虑使用硬件安全模块(HSM)或密钥管理服务
- 实施密钥轮换机制
-
初始向量/Nonce处理:
- 对每次加密使用唯一的IV/Nonce
- IV/Nonce可以公开,但必须与密文一起传输
- 避免使用可预测的或固定的IV
-
认证与完整性:
- 优先使用带认证的加密模式(AEAD)
- 如果使用非认证模式,必须单独实现完整性验证
-
实现安全考量:
- 使用经过验证的加密库,避免自行实现
- 注意时序攻击,确保恒定时间比较
- 避免异常信息泄露加密细节
-
算法选择:
- 大多数场景优选AES-GCM或ChaCha20-Poly1305
- 考虑后量子计算时代的加密方案
- 跟踪密码学标准的更新
七、对称加密的未来发展趋势
轻量级加密算法
为适应物联网(IoT)和嵌入式系统的需求,轻量级加密算法正在蓬勃发展:
- PRESENT:64位分组、80/128位密钥,针对硬件优化
- SKINNY:64/128位分组,针对轻量级应用的设计
- SIMON & SPECK:美国国家安全局(NSA)设计的轻量级算法家族
- GIFT:PRESENT的改进版本,同时优化软硬件实现
后量子对称加密
虽然量子计算对对称加密的威胁主要是密钥长度减半(通过Grover算法),仍有一些应对措施:
- 密钥长度翻倍:AES-256提供足够的抗量子安全性
- 考虑新的设计原语,如基于格的对称加密
- 量子安全对称加密方案的研究
对称加密与新型计算技术
新兴的计算范式正在影响对称加密的应用方式:
- 同态加密友好的对称加密:设计更适合在同态加密环境中使用的对称加密算法
- 多方安全计算中的对称加密:优化在多方计算协议中的效率
- 零知识证明系统中的对称加密:与零知识证明系统更好地集成
八、总结与实践建议
算法选择决策矩阵
需求/约束条件 | 推荐算法 | 说明 |
---|---|---|
高性能服务器环境 | AES-GCM | 利用硬件加速 |
移动设备/低功耗 | ChaCha20-Poly1305 | 软件实现高效 |
中国合规要求 | SM4-CBC/SM4-GCM | 符合国密标准 |
长期数据保护 | AES-256-GCM | 足够的安全边际 |
嵌入式/IoT设备 | ChaCha20 或轻量级算法 | 资源占用低 |
工程师实践指南
-
选择成熟的密码库:
- Python: PyCryptodome, cryptography
- Java: BouncyCastle, JCA
- C/C++: OpenSSL, libsodium
- JavaScript: Web Crypto API, TweetNaCl.js
-
常见加密任务的设计模式:
- 文件加密:加密内容+元数据头
- 数据库字段加密:单独的IV+密文
- API通信:自动化密钥协商+会话密钥
-
合规性考量:
- FIPS 140-2/3:AES, TDEA, SKIPJACK
- 中国密码法:SM4
- GDPR/隐私法规:强加密和密钥管理
最终建议
对称加密是数据安全的基础,但仅靠算法选择无法保证安全。完整的数据安全策略还应包括:
- 完善的密钥管理系统
- 强大的身份认证机制
- 端到端的安全设计
- 定期安全审计和更新
最佳实践是使用经过验证的加密库,遵循标准实现,并根据具体应用场景选择合适的算法和参数。在大多数现代应用中,AES-GCM和ChaCha20-Poly1305能满足绝大部分需求,而在特定合规环境下,SM4等国家标准算法则是必要选择。
对于需要长期保护的数据,应考虑定期重新加密以及未来可能的算法迁移路径,确保数据在加密技术演进中始终保持安全。
附录:对称加密技术专业术语表
A
Advanced Encryption Standard (AES): 高级加密标准,由美国国家标准与技术研究院(NIST)在2001年确立的加密标准,替代了老旧的DES算法。
Authenticated Encryption (AE): 认证加密,同时提供数据机密性、完整性和真实性的加密技术。
Authenticated Encryption with Associated Data (AEAD): 带关联数据的认证加密,允许一部分数据(如报头)不加密但受认证保护。
Authentication Tag: 认证标签,用于验证加密数据完整性和真实性的信息块。
ARX: Add-Rotate-XOR的缩写,指使用加法、位旋转和异或操作的密码学构造。
B
Block Cipher: 块加密算法,将明文分成固定长度的块进行加密的算法。
Block Size: 块大小,块加密算法一次处理的位数,通常为64位或128位。
C
Cipher: 密码,加密和解密算法的总称。
Ciphertext: 密文,通过加密算法处理后的数据。
Cipher Block Chaining (CBC): 密码块链接模式,每个明文块在加密前与前一个密文块进行XOR操作的工作模式。
Counter Mode (CTR): 计数器模式,将块加密算法转换为流加密的工作模式,使用递增的计数器生成密钥流。
ChaCha20: 由Daniel J. Bernstein设计的流加密算法,基于Salsa20改进而来。
D
Decryption: 解密,将密文恢复为明文的过程。
Diffusion: 扩散,加密算法中使明文的微小变化影响密文多个部分的特性。
E
Encryption: 加密,将明文转换为密文的过程。
Electronic Codebook (ECB): 电子密码本模式,最简单的块加密工作模式,各块独立加密。
Entropy: 熵,密码学中衡量随机性或不确定性的度量。
F
Feistel Network: 费斯妥网络,一种用于构建块加密算法的对称结构。
Format-Preserving Encryption (FPE): 格式保留加密,加密后保持与原始数据相同格式的加密技术。
G
Galois/Counter Mode (GCM): 伽罗瓦/计数器模式,一种提供认证加密的工作模式,结合CTR加密和伽罗瓦域认证。
H
Hardware Security Module (HSM): 硬件安全模块,专用于保护和管理密钥的物理设备。
I
Initialization Vector (IV): 初始向量,增加加密随机性的值,通常与明文的第一个块结合。
K
Key: 密钥,控制加密和解密操作的参数。
Key Derivation Function (KDF): 密钥派生函数,从主密钥或密码生成加密密钥的函数。
Key Schedule: 密钥调度,从主密钥生成各轮使用的子密钥的过程。
L
Lightweight Cryptography: 轻量级密码学,针对资源受限环境优化的加密算法。
M
Message Authentication Code (MAC): 消息认证码,验证消息完整性和真实性的短数据块。
MixColumns: 列混合变换,AES算法中的一个操作,提供扩散特性。
Mode of Operation: 工作模式,定义如何将块加密算法应用于不同长度明文的方法。
N
Nonce: Number used once的缩写,一次性使用的随机或伪随机数。
O
Output Feedback (OFB): 输出反馈模式,一种将块加密转换为流加密的工作模式。
P
Padding: 填充,使数据达到块大小整数倍的技术。
PKCS#7: Public Key Cryptography Standards #7,一种常用的填充标准。
Plaintext: 明文,未加密的原始数据。
Poly1305: 一种用于生成消息认证码的算法,常与ChaCha20结合使用。
R
Round: 轮,对称加密算法中重复执行的变换单位。
Round Key: 轮密钥,每一轮加密操作使用的密钥。
S
Salt: 盐值,添加到哈希或密钥派生函数中增加安全性的随机值。
S-box (Substitution box): 替代盒,在密码学算法中执行非线性替代操作的查找表。
ShiftRows: 行移位,AES算法中的一个操作,将字节排列移位。
SM4: 中国商用密码标准,一种128位分组密码。
Stream Cipher: 流加密算法,一次加密一个位或字节的加密算法。
SubBytes: 字节替代,AES算法中使用S-box进行的非线性变换。
Substitution-Permutation Network (SPN): 替代-置换网络,一类对称加密算法的结构。
T
Tweakable Block Cipher: 可调整块加密,允许额外输入(调整值)的块加密算法。
V
Vector Processing Instruction Set: 向量处理指令集,如AES-NI,提供硬件加速的特殊CPU指令。
X
XOR (Exclusive OR): 异或,密码学中常用的二进制操作,结合两个输入位流。
Z
Zero-padding: 零填充,使用零字节填充数据块的技术。
相关文章:

对称加密算法(AES、ChaCha20和SM4)Python实现——密码学基础(Python出现No module named “Crypto” 解决方案)
文章目录 一、对称加密算法基础1.1 对称加密算法的基本原理1.2 对称加密的主要工作模式 二、AES加密算法详解2.1 AES基本介绍2.2 AES加密过程2.3 Python中实现AES加密Python出现No module named “Crypto” 解决方案 2.4 AES的安全考量 三、ChaCha20加密算法3.1 ChaCha20基本介…...
JWT原理及工作流程详解
JSON Web Token(JWT)是一种开放标准(RFC 7519),用于在各方之间安全传输信息。其核心原理是通过结构化、签名或加密的JSON对象实现无状态身份验证和授权。以下是JWT的工作原理和关键组成部分: 1. JWT结构 J…...

【软件设计师:存储】16.计算机存储系统
一、主存储器 存储器是计算机系统中的记忆设备,用来存放程序和数据。 计算机中全部信息,包括输入的原始数据、计算机程序、中间运 行结果和最终运行结果都保存在存储器中。 存储器分为: 寄存器Cache(高速缓冲存储器)主存储器辅存储器一、存储器的存取方式 二、存储器的性…...
【Part 2安卓原生360°VR播放器开发实战】第三节|实现VR视频播放与时间轴同步控制
《VR 360全景视频开发》专栏 将带你深入探索从全景视频制作到Unity眼镜端应用开发的全流程技术。专栏内容涵盖安卓原生VR播放器开发、Unity VR视频渲染与手势交互、360全景视频制作与优化,以及高分辨率视频性能优化等实战技巧。 📝 希望通过这个专栏&am…...

WebRTC通信原理与流程
1、服务器与协议相关 1.1 STUN服务器 图1.1.1 STUN服务器在通信中的位置图 1.1.1 STUN服务简介 STUN(Session Traversal Utilities for NAT,NAT会话穿越应用程序)是一种网络协议,它允许位于NAT(或多重 NAT)…...

Java版ERP管理系统源码(springboot+VUE+Uniapp)
ERP系统是企业资源计划(Enterprise Resource Planning)系统的缩写,它是一种集成的软件解决方案,用于协调和管理企业内各种关键业务流程和功能,如财务、供应链、生产、人力资源等。它的目标是帮助企业实现资源的高效利用…...

Redis总结(六)redis持久化
本文将简单介绍redis持久化的两种方式 redis提供了两种不同级别的持久化方式: RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储.AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保…...
使用FastAPI微服务在AWS EKS中构建上下文增强型AI问答系统
系统概述 本文介绍如何使用FastAPI在AWS Elastic Kubernetes Service (EKS)上构建一个由多个微服务组成的AI问答系统。该系统能够接收用户输入的提示(prompt),通过调用其他微服务从AWS ElastiCache on Redis和Amazon DynamoDB获取相关上下文,然后利用AW…...

PMIC电源管理模块的PCB设计
目录 PMU模块简介 PMU的PCB设计 PMU模块简介 PMIC(电源管理集成电路)是现代电子设备的核心模块,负责高效协调多路电源的转换、分配与监控。它通过集成DC-DC降压/升压、LDO线性稳压、电池充电管理、功耗状态切换等功能,替代传统分…...
正大视角下的结构交易节奏:如何借助数据捕捉关键转折
正大视角下的结构交易节奏:如何借助数据捕捉关键转折 在日常的交易结构研究中,节奏与分型常常被误解为“预测工具”,实则更应作为状态识别的参考。正大团队在模型演化过程中提出了“节奏-结构对齐”的分析方式,通过数据驱动来判断…...

华为云Flexus+DeepSeek征文|DeepSeek-V3商用服务开通教程
目录 DeepSeek-V3/R1商用服务开通使用感受 DeepSeek-V3/R1商用服务开通 1、首先需要访问ModelArts Studio_MaaS_大模型即服务_华为云 2、在网站右上角登陆自己的华为云账号,如果没有华为云账号的话,则需要自己先注册一个。 3、接着点击ModelArts Stu…...
STM32F103RC中ADC1和ADC2通道复用
以下是STM32F103RC中ADC1和ADC2通道复用的示意图及文字说明,帮助直观理解这种共享关系: ADC1/ADC2引脚复用示意图 GPIO引脚 ADC1通道 ADC2通道 ┌─────────┐ ┌─────────┐ ┌─────────┐ │ PA0 ├─…...

Qt—鼠标移动事件的趣味小程序:会移动的按钮
1.项目目标 本次根据Qt的鼠标移动事件实现一个趣味小程序:当鼠标移动到按钮时,按钮就会随机出现在置,以至于根本点击不到按钮。 2.项目步骤 首先现在ui界面设计控件(也可以用代码的方式创建,就不多说了) 第一个按钮不需…...

鞋样设计软件
Sxy 64鞋样设计软件是一款专业级鞋类设计工具 专为鞋业设计师与制鞋企业开发 该软件提供全面的鞋样设计功能 包括二维开版 三维建模 放码排料等核心模块 支持从草图构思到成品输出的完整设计流程 内置丰富的鞋型数据库与部件库 可快速生成各种鞋款模板 软件采用智能放码技术 精…...

LeRobot 项目部署运行逻辑(六)——visualize_dataset_html.py/visualize_dataset.py
可视化脚本包括了两个方法:远程下载 huggingface 上的数据集和使用本地数据集 脚本主要使用两个: 目前来说,ACT 采集训练用的是统一时间长度的数据集,此外,这两个脚本最大的问题在于不能裁剪,这也是比较好…...

Windows Server 2025开启GPU分区(GPU-P)部署DoraCloud云桌面
本文描述在ShareStation工作站虚拟化方案的部署过程。 将服务器上部署 Windows Server、DoraCloud,并创建带有vGPU的虚拟桌面。 GPU分区技术介绍 GPU-P(GPU Partitioning) 是微软在 Windows 虚拟化平台(如 Hyper-V)中…...

TCP套接字通信核心要点
TCP套接字通信核心要点 通信模型架构 客户端-服务端模型 CS架构:客户端发起请求,服务端响应和处理请求双向通道:建立连接后实现全双工通信 服务端搭建流程 核心步骤 创建套接字 int server socket(AF_INET, SOCK_STREAM, 0); 参数说明&am…...

【C】初阶数据结构15 -- 计数排序与稳定性分析
本文主要讲解七大排序算法之外的另一种排序算法 -- 计数排序 目录 1 计数排序 1) 算法思想 2) 代码 3) 时间复杂度与空间复杂度分析 (1) 时间复杂度 (2) 空间复杂度 4) 计…...

高性能Python Web 框架--FastAPI 学习「基础 → 进阶 → 生产级」
以下是针对 FastAPI 的保姆级教程,包含核心概念、完整案例和关键注意事项,采用「基础 → 进阶 → 生产级」的三阶段教学法: 一、FastAPI介绍 FastAPI 是一个现代化的、高性能的 Python Web 框架,专门用于构建 APIs(应…...

Qt QML自定义LIstView
QML ListView组合拳做列表,代码不可直接复制使用,需要小改 先上图看效果 样式1 样式2 样式3 原理:操作:技术点:代码片段: 先上图看效果 样式1 三个表格组合成要给,上下滚动时,三个同时滚动&am…...

C++进阶--红黑树的实现
文章目录 红黑树的实现红黑树的概念红黑树的规则红黑树的效率 红黑树的实现红黑树的结构红黑树的插入变色单旋(变色)双旋(变色) 红黑树的查找红黑树的验证 总结:结语 很高兴和大家见面,给生活加点impetus&a…...

WPF之值转换器
文章目录 目录什么是值转换器IValueConverter接口Convert方法ConvertBack方法 创建和使用值转换器定义转换器类在XAML中使用转换器转换器参数(ConverterParameter) 常用转换器实现布尔值转可见性(BoolToVisibilityConverter)数值转…...
黄金、碳排放期货市场API接口文档
StockTV 提供了多种期货市场的数据接口,包括获取K线图表数据、查询特定期货的实时行情等。以下为对接期货市场的详细接口说明。 一、获取K线图表数据 通过调用/futures/kline接口,您可以获取指定期货合约的历史K线数据(例如开盘价、最高价、…...
云上系统CC攻击如何进行检测与防御?
云上系统遭受CC攻击(Challenge Collapsar,一种针对应用层的DDoS攻击)时,检测与防御需结合流量分析、行为识别和技术手段,以下是核心方法: 一、检测方法 异常流量分析 监控请求量突增&#…...

qml中的TextArea使用QSyntaxHighlighter显示高亮语法
效果图,左侧显示行号,右侧用TextArea显示文本内容,并且语法高亮。 2025年5月8号更新 1、多行文本注释 多行文本注释跟普通的高亮规则代码不太一样,代码需要修改,这里以JavaScript举例。 先制定多行文本注释规则&…...
QuecPython+腾讯云:快速连接腾讯云l0T平台
该模块提供腾讯 IoT 平台物联网套件客户端功能,目前的产品节点类型仅支持“设备”,设备认证方式支持“一机一密”和“动态注册认证”。 BC25PA系列不支持该功能。 初始化腾讯 IoT 平台 TXyun TXyun(productID, devicename, devicePsk, ProductSecret)配置腾讯 IoT…...
RocketMQ 深度解析:架构设计与最佳实践
在分布式系统架构日益复杂的今天,消息中间件作为系统间通信的桥梁,扮演着至关重要的角色。RocketMQ 作为阿里开源的高性能分布式消息中间件,凭借其卓越的性能、丰富的功能以及高可用性,在电商、金融、互联网等众多领域得到广泛应用…...

Transformer编码器+SHAP分析,模型可解释创新表达!
目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 基本介绍 基于SHAP分析的特征选择和贡献度计算,Matlab2023b代码实现;基于MATLAB的SHAP可解释Transformer编码器回归模型,敏感性分析方法。 详细介绍 引言 在正向渗透(…...

[特殊字符]适合母亲节的SVG模版[特殊字符]
宝藏模版 往期推荐(点击阅读): 趣味效果|高大上|可爱风|年终总结I|年终总结II|循环特效|情人节I|情人节II|情人节IIII|妇女节I&…...

浅蓝色调风格人像自拍Lr调色预设,手机滤镜PS+Lightroom预设下载!
调色教程 浅蓝色调风格人像自拍 Lr 调色是利用 Adobe Lightroom 软件针对人像自拍照进行后期处理的一种调色方式。它通过对照片的色彩、对比度、亮度等参数进行精细调整,将画面的主色调打造为清新、柔和的浅蓝色系,赋予人像自拍独特的清新、文艺风格&…...