对称加密算法(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基本介…...
n8n 键盘快捷键和控制键
n8n 键盘快捷键和控制键 工作流控制键画布操作移动画布画布缩放画布上的节点操作选中一个或多个节点时的快捷键 节点面板操作节点面板分类操作 节点内部操作 n8n 为部分操作提供了键盘快捷键。 工作流控制键 Ctrl Alt n:创建新工作流Ctrl o:打开工作…...
部署Superset BI(二)再战Superset
上次安装没有成功,这次把superset的安装说明好好看了一下。 rootNocobase:/usr# cd superset rootNocobase:/usr/superset# git clone https://github.com/apache/superset.git Cloning into superset... remote: Enumerating objects: 425644, done. remote: Count…...
生日快乐祝福网页制作教程
原文:https://www.w3cschool.cn/article/88229685.html (本文非我原创,请标记为付费文章,也请勿将我标记为原创) 一、引言 生日是每个人一年中最特别的日子之一。在这个特别的日子里,我们都希望能够给亲…...
Spring MVC @RequestHeader 注解怎么用?
我们来详细解释一下 Spring MVC 中的 RequestHeader 注解。 RequestHeader 注解的作用 RequestHeader 注解用于将 HTTP 请求中的**请求头(Request Headers)**的值绑定到 Controller 方法的参数上。 请求头是 HTTP 请求的一部分,包含了关于…...
【Linux深入浅出】之全连接队列及抓包介绍
【Linux深入浅出】之全连接队列及抓包介绍 理解listen系统调用函数的第二个参数简单实验实验目的实验设备实验代码实验现象 全连接队列简单理解什么是全连接队列全连接队列的大小 从Linux内核的角度理解虚拟文件、sock、网络三方的关系回顾虚拟文件部分的知识struct socket结构…...
Linux C++ JNI封装、打包成jar包供Java调用详细介绍
在前面 Android专栏 中详细介绍了如何在Android Studio中调用通过jni封装的c库。 在Android使用 opencv c代码,需要准备opencv4android,也就是c的任何代码,是使用Android NDK编译的,相当于在windows/mac上使用Android stdido交叉…...
CPO-BP+NSGA,豪冠猪优化BP神经网络+多目标遗传算法!(Matlab完整源码和数据)
目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.CPO-BPNSGA,豪冠猪优化BP神经网络多目标遗传算法!(Matlab完整源码和数据),豪冠猪算法优化BP神经网络的权值和阈值,运行环境Matlab2020b及以上…...
组件通信-v-model
概述:实现 父↔子 之间相互通信。 前序知识 —— v-model的本质 <!-- 使用v-model指令 --> <input type"text" v-model"userName"><!-- v-model的本质是下面这行代码 --> <input type"text" :value"use…...
使用PyMongo连接MongoDB的基本操作
MongoDB是由C语言编写的非关系型数据库,是一个基于分布式文件存储的开源数据库系统,其内容存储形式类似JSON对象,它的字段值可以包含其他文档、数组及文档数组。在这一节中,我们就来回顾Python 3下MongoDB的存储操作。 常用命令:…...
010302-oss_反向代理_负载均衡-web扩展2-基础入门-网络安全
文章目录 1 OSS1.1 什么是 OSS 存储?1.2 OSS 核心功能1.3 OSS 的优势1.4 典型使用场景1.5 如何接入 OSS?1.6 注意事项1.7 cloudreve实战演示1.7.1 配置cloudreve连接阿里云oss1.7.2 常见错误1.7.3 安全测试影响 2 反向代理2.1 正向代理和反向代理2.2 演示…...
PyQt 或 PySide6 进行 GUI 开发文档与教程
一、官网文档 Qt 官方文档:Porting to Qt 6 | Qt 6.9Qt 维基:Qt WikiQt for Python (PySide6) :Qt for Python - Qt WikiPySide6 快速上手指南:Getting Started - Qt for Python PyS…...
【东枫科技】AMD / Xilinx Alveo™ V80计算加速器卡
AMD / Xilinx Alveo™ V80计算加速器卡 AMD/Xilinx Alveo ™ V80计算加速器卡是一款功能强大的计算加速器,基于7nm Versal™ 自适应SoC架构而打造。 AMD/Xilinx Alveo V80卡设计用于内存密集型任务。 这些任务包括HPC、数据分析、网络安全、传感器处理、计算存储和…...
C++ 动态内存管理
operator new和operator delete函数是两个全局函数,编译器在编译new和delete时会调用这两个函数,其底层分别是封装malloc和free 1.new new 内置类型 内置类型没有构造函数,所以使用new就是调operator new函数开空间,如果要初始化…...
(11)Vue-Router路由的详细使用
本系列教程目录:Vue3Element Plus全套学习笔记-目录大纲 文章目录 第2章 路由 Vue-Router2.1 Vue路由快速入门2.1.1 创建项目2.1.2 路由运行流程 2.2 传递参数-useRoute2.2.1 路径参数-params1)普通传参2)传递多个参数3)对象方式传…...
RISCV的smstateen-ssstateen扩展
RISC-V 的 Smstateen / Ssstateen 扩展是为了解决安全性和资源隔离性问题而设计的,尤其是针对在多个上下文(如用户线程、多个虚拟机)之间 潜在的隐蔽信道(covert channel) 风险。 🌐 背景:隐蔽信道与上下文切换问题 当…...
C++ 与 Lua 联合编程
在软件开发的广阔天地里,不同编程语言各有所长。C 以其卓越的性能、强大的功能和对硬件的直接操控能力,在系统开发、游戏引擎、服务器等底层领域占据重要地位,但c编写的程序需要编译,这往往是一个耗时操作,特别对于大型…...
瑞萨 EZ-CUBE2 调试器
瑞萨 EZ-CUBE2 调试器 本文介绍了瑞萨 EZ-CUBE2 调试器的基本信息、调试方式、环境搭建、硬件连接、软件测试等。 包装展示 调试器展示 开关选项 详见:EZ-CUBE2 | Renesas 瑞萨电子 . 环境搭建 使用 Renesas 公司的 e2 studio 开发工具,下载 并安装该…...
MATLAB滤波工具箱演示——自定义维度、滤波方法的例程演示与绘图、数据输出
使用 M A T L A B MATLAB MATLAB的界面做了一个 M A T L A B MATLAB MATLAB滤波工具箱 d e m o demo demo,本文章给出演示:自定义维度、滤波方法的例程演示与绘图、数据输出 文章目录 编辑界面使用方法优势待改进点部分代码 编辑界面 使用 M A T L A B …...
数据库索引优化实战: 如何设计高效的数据库索引
数据库索引优化实战: 如何设计高效的数据库索引 一、理解数据库索引的核心原理 1.1 B树索引的结构特性 数据库索引(Database Index)的本质是通过特定数据结构加速数据检索。现代关系型数据库普遍采用B树(B Tree)作为默认索引结构&…...
TS 安装
TS较JS优势 1 TS静态类型编程语言。编译时发现错误 2 类型系统 强化变量类型概念 3 支持新语法 4 类型推断机制 可以和React框架中的各种hook配合 5 任何地方都有代码提示 tsc 命令 将TS转为JS 1 tsc 文件.ts 生成 js文件 2 执行JS代码...
CMake separate_arguments用法详解
separate_arguments 是 CMake 中用于将字符串分割成参数列表的命令,适用于处理包含空格的参数或复杂命令行参数。以下是其用法详解: 基本语法 separate_arguments(<variable> [UNIX|WINDOWS_COMMAND] [PROGRAM <program>] [ARGS <args&…...
【AI科技】AMD ROCm 6.4 新功能:突破性推理、即插即用容器和模块化部署,可在 AMD Instinct GPU 上实现可扩展 AI
AMD ROCm 6.4 新功能:突破性推理、即插即用容器和模块化部署,可在 AMD Instinct GPU 上实现可扩展 AI 现代 AI 工作负载的规模和复杂性不断增长,而人们对性能和部署便捷性的期望也日益提升。对于在 AMD Instinct™ GPU 上构建 AI 和 HPC 未来…...
2025年- H20-Lc128-240. 搜索二维矩阵 II(矩阵)---java版
1.题目描述 2.思路 遍历矩阵,然后如果遇到矩阵中的值正好等于target,输出true。否则,输出false。 3.代码 public class H240 {public boolean searchMatrix(int[][] matrix, int target) {//1.计算出总的行值,总的列值。int mm…...
LearningFlow:大语言模型城市驾驶的自动化策略学习工作流程
《LearningFlow: Automated Policy Learning Workflow for Urban Driving with Large Language Models》2025年1月发表,来自香港科技大学广州分校的论文。 强化学习(RL)的最新进展表明了自动驾驶的巨大潜力。尽管有这一前景,但奖励…...
C语言数据类型与内存布局
C语言数据类型内存占用 类型32位系统64位系统格式说明符char1字节1字节%cint4字节4字节%dfloat4字节4字节%fdouble8字节8字节%lflong long8字节8字节%lld...
从原理到实战讲解回归算法!!!
哈喽,大家好,我是我不是小upper, 今天系统梳理了线性回归的核心知识,从模型的基本原理、参数估计方法,到模型评估指标与实际应用场景,帮助大家深入理解这一经典的机器学习算法,助力数据分析与预测工作。 …...
linux指令中的竖线(“|”)是干啥的?【含实例展示】
文章目录 一、管道符的基本概念二、管道符的核心作用三、常用实例展示四、进阶技巧五、注意事项总结 实操展示**案例1:统计日志中特定错误的数量****案例2:查找当前运行的进程****案例3:合并排序并去重****案例4:实时监控CPU占用前…...
[HOT 100] 0124. 二叉树中的最大路径和
文章目录 1. 题目链接2. 题目描述3. 题目示例4. 解题思路5. 题解代码6. 复杂度分析 1. 题目链接 124. 二叉树中的最大路径和 - 力扣(LeetCode) 2. 题目描述 二叉树中的 路径 被定义为一条节点序列,序列中每对相邻节点之间都存在一条边。同一…...
[SoC]AXI总线Performance验证方案
AXI总线Performance验证方案 测试 AXI (Advanced eXtensible Interface) 的性能是 SoC 验证中的重要任务,旨在评估其在不同负载和配置下的表现是否满足设计要求。以下详细说明如何测试 AXI 的性能、需要统计的变量、计算方法、在验证环境中动态计算性能的方法,以及如何…...
EMC PowerStore存储学习之一NVMe磁盘的命名规则
PowerStore的日志中经常会看到类似于/dev/nvme1n1的磁盘,在svc_diag list --show_drives中也可以看到类似这样的输出,如下图: 这里的Drives的显示都是 /dev/nvmeXnY的形式,那么这个磁盘命名规则怎么解读呢? 在Linux系…...
apt-mirror搭建ubuntu本地离线源
参考资料 4 Steps to Setup Local Repository in Ubuntu using APT-mirror 使用 APT-mirror 四步配置 Ubuntu 本地软件仓库 ubuntu下的apt-get内网本地源的搭建...
【记录】新Ubuntu20配置voxelmap的环境安装
因为系统总出问题,仅用于个人纪录。 1. 升级CMake到3.28及以上版本(Sophus依赖) wget https://github.com/Kitware/CMake/releases/download/v3.28.3/cmake-3.28.3-linux-x86_64.sh chmod x cmake-3.28.3-linux-x86_64.sh sudo ./cmake-3.2…...
Python全流程开发实战:基于IMAP协议安全下载个人Gmail邮箱内所有PDF附件
在日常办公场景中,面对成百上千封携带PDF附件的邮件,手动逐一下载往往耗时耗力,成为效率瓶颈。如何通过代码实现“一键批量下载”?本文将以**“Gmail全量PDF附件下载工具”**开发为例,完整拆解从需求分析到落地交付的P…...
CPU:AMD的线程撕裂者(Threadripper)和霄龙(EPYC)的区别
AMD的**线程撕裂者(Threadripper)和霄龙(EPYC)**虽然都是面向高性能市场的处理器,但它们在定位、功能和技术规格上有显著区别。以下是两者的主要差异: 1. 目标市场 线程撕裂者(Threadripper&…...
【五一培训】Day 2
注: 1. 本次培训内容的记录将以“Topic”的方式来呈现,用于记录个人对知识点的理解。 2. 由于培训期间,作者受限于一些现实条件,本文的排版及图片等相关优化,需要过一段时间才能完成。 3. 关于老板点评的一些思考 你…...
shell_plus
python manage.py shell_plus 是由 django-extensions 提供的一个增强版的 Django shell,它自动导入你的所有模型和其他一些便捷功能,使得交互式开发更加方便。 如果你遇到配置或运行问题,特别是与 RQ_SHOW_ADMIN_LINK 相关的 ImproperlyCon…...
基于C++、JsonCpp、Muduo库实现的分布式RPC通信框架
⭐️个人主页:小羊 ⭐️所属专栏:RPC框架 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~ 目录 项目介绍JsonCpp库简单介绍Muduo库简单介绍C11异步操作——std::future1. 使用 std::async 关联异步任务2. std::packaged_task…...
Redis TLS 加密对性能的影响分析
Redis TLS 加密对性能的影响分析 是的,Redis 启用 TLS 加密确实会对性能产生一定影响,但影响程度取决于多种因素。以下是详细分析: 一、性能影响的主要来源 加密/解密开销: TLS 握手过程中的非对称加密(如 RSA、…...
树与二叉树完全解析:从基础到应用
目录 一、树形结构的基础认知 1.1 树的定义与特点 1.2 核心术语解析 二、二叉树的深度解析 2.1 二叉树定义 2.2 特殊二叉树类型 2.3 重要性质总结 三、二叉树的存储与遍历 3.1 存储方式对比 3.2 遍历算法精讲 四、经典题型训练 4.1 相同树判断(LeetCode…...
PostgreSQL:pgJDBC 下载和安装
PostgreSQL 的 pgJDBC 是用于 Java 程序连接和操作 PostgreSQL 数据库的 JDBC 驱动程序。 PostgreSQL:pgJDBC v42.7 下载和安装 点击【Application Stack Builder】 安装目录: 运行 cmd cd D:\PostgreSQL\pgJDBC copy postgresql-42.7.2.jar D:\groovy-…...
正则表达式与文本三剑客grep、sed、awk
目录 一、正则表达式 1.1、字符匹配 1.2、次数匹配 1.3、位置锚定 1.4、分组或其他 二、扩展正则表达式 三、grep 四、awk 4.1、常用命令选项 4.2、工作原理 4.3、基础用法 4.4、内置变量 4.5、模式 4.6、条件判断 4.7、awk中的循环语句 4.8、数组 4.9、脚本 …...
(35)VTK C++开发示例 ---将图片映射到平面2
文章目录 1. 概述2. CMake链接VTK3. main.cpp文件4. 演示效果 更多精彩内容👉内容导航 👈👉VTK开发 👈 1. 概述 与上一个示例不同的是,使用vtkImageReader2Factory根据文件扩展名或内容自动创建对应的图像文件读取器&a…...
每日一题洛谷P8635 [蓝桥杯 2016 省 AB] 四平方和c++
P8635 [蓝桥杯 2016 省 AB] 四平方和 - 洛谷 (luogu.com.cn) 直接暴力枚举,不做任何优化的话最后会TLE一个,稍微优化一下就过了(数据给的还是太良心了) 优化:每层循环用if判断一下,如果大于n就直接跳 当然…...
【python】【UV】一篇文章学完新一代 Python 环境与包管理器使用指南
🐍 UV:新一代 Python 环境与包管理器使用指南 一、UV 是什么? UV 是由 Astral 团队开发的高性能 Python 环境管理器,旨在统一替代 pyenv、pip、venv、pip-tools、pipenv 等工具。 1.1 UV 的主要功能 🚀 极速包安装&…...
6.10.单源最短路径问题-Dijkstra算法
一.BFS算法的局限性: 如上图,BFS算法可以解决无权图的单源最短路径问题, 如果是解决带权图的单源最短路径问题,BFS算法就不适用了,如下图: 如上图,比如求G港到其他顶点的最短路径, …...
Python基于深度学习的网络舆情分析系统(附源码,部署)
大家好,我是Python徐师兄,一个有着7年大厂经验的程序员,也是一名热衷于分享干货的技术爱好者。平时我在 CSDN、掘金、华为云、阿里云和 InfoQ 等平台分享我的心得体会。 🍅文末获取源码联系🍅 2025年最全的计算机软件毕…...
mysql--索引
索引作为一种数据结构,其用途是用于提升检索数据的效率。 分类 普通索引(INDEX):索引列值可重复 唯一索引(UNIQUE):索引列值必须唯一,可以为NULL 主键索引(PRIMARY KEY&a…...
【算法题】荷兰国旗问题[力扣75题颜色分类] - JAVA
一、题目 二、文字解释 1.1 前言 本题是经典的「荷兰国旗问题」,由计算机科学家 Edsger W. Dijkstra 首先提出。如同图中所示的荷兰国旗,其由红、白、蓝三色水平排列组成。在算法领域,该问题可类比为将一个由特定的三种元素(可…...
【数据结构】堆的完整实现
堆的完整实现 堆的完整实现GitHub地址前言堆的核心功能实现重温堆的定义堆结构定义1. 堆初始化与销毁2. 元素交换函数3. 堆化操作向上调整(子→父)向下调整(父→子) 4. 堆元素插入5. 堆元素删除6. 辅助功能函数堆的判空获取堆顶元…...