對稱加密算法(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加密過程包括以下步驟:

  1. 初始輪密鑰加:將初始輪密鑰與明文塊異或
  2. 主輪轉換
    • SubBytes:通過S盒替換每個字節
    • ShiftRows:循環移位操作
    • MixColumns:列混合變換
    • AddRoundKey:輪密鑰加
  3. 最終輪:不包含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的安全考量

  1. 密鑰管理

    • 避免硬編碼密鑰
    • 考慮使用密鑰派生函數(KDF),如PBKDF2、Argon2
    • 定期輪換密鑰
  2. 工作模式選擇

    • 避免使用ECB模式,它無法提供語義安全性
    • 對于大多數場景,推薦GCM模式(提供認證)或CTR模式
    • 對于不需要隨機訪問的場景,CBC模式也是可接受的
  3. 初始向量(IV)處理

    • 確保IV是隨機的(CBC)或不重用的(CTR/GCM)
    • IV不需要保密,但需要與密文一起傳輸
  4. 認證

    • 最好使用認證加密(AE)或帶關聯數據的認證加密(AEAD),如GCM模式
    • 如果使用非認證模式,應單獨實現認證機制(如HMAC)
  5. 填充

    • 使用安全的填充方案,如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加密過程基于以下步驟:

  1. 初始化一個4×4的32位字矩陣,包含常量、密鑰、計數器和nonce
  2. 對矩陣進行20輪變換(10輪內部變換)
  3. 將變換后的矩陣與初始矩陣相加
  4. 生成密鑰流,與明文進行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的優勢與應用場景

  1. 性能優勢

    • 在沒有硬件加速的情況下,比AES更快
    • 尤其適合移動設備和低功耗環境
    • 易于實現無分支代碼,抵抗側信道攻擊
  2. 安全性

    • 被廣泛分析且被認為是安全的
    • 與Poly1305結合提供認證加密
    • 支持大量數據加密且不需要分塊
  3. 應用場景

    • TLS 1.3協議
    • 移動應用加密
    • VPN和安全通信
    • 嵌入式系統和IoT設備

四、SM4加密算法

4.1 SM4基本介紹

SM4是中國商用密碼標準,原名"SMS4",是無線局域網標準的分組數據算法。其特點包括:

  • 分組大小:128位(16字節)
  • 密鑰長度:128位(16字節)
  • 輪數:32輪
  • 設計結構:非平衡Feistel網絡

SM4是中國密碼局批準的唯一分組密碼算法,在中國的政府、金融和商業應用中廣泛使用。

4.2 SM4加密過程

SM4加密過程包括以下步驟:

  1. 密鑰擴展:從128位主密鑰生成32個輪密鑰
  2. 數據處理:
    • 將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的安全考量與應用場景

  1. 安全性考量

    • 需要使用隨機生成的IV
    • 避免使用ECB模式,優先選擇CBC、CTR等模式
    • 需要實現合適的填充方案,如PKCS#7
    • 密鑰管理同樣重要
  2. 標準兼容性

    • 符合中國密碼行業標準
    • 政府和金融機構的合規性要求
    • 與其他國密算法(如SM2、SM3)配套使用
  3. 應用場景

    • 國內銀行金融應用
    • 政府部門信息系統
    • 工業控制系統
    • 電子政務和電子商務應用

五、對稱加密算法的性能比較

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-CBC180-220190-230硬件加速支持廣泛
AES-GCM150-180160-190提供認證,略慢于CBC
ChaCha20250-300250-300軟件實現性能優秀
ChaCha20-Poly1305200-250210-260提供認證,比AES-GCM快
SM4-CBC80-12080-120無硬件加速,最慢

性能分析:

  1. 硬件加速影響

    • AES在現代CPU上通常有硬件加速指令集(AES-NI),在有硬件支持的環境中性能極佳
    • ChaCha20不依賴硬件加速,在純軟件實現中通常比AES快
    • SM4目前很少有硬件加速支持,通常是純軟件實現,性能較低
  2. 認證加密開銷

    • 帶認證的加密模式(GCM, Poly1305)比純加密模式略慢
    • 認證計算增加了約10-20%的處理時間
    • 安全性提升值得這一性能代價
  3. 各種設備的表現

    • 在高端桌面/服務器:AES-NI加速的AES通常最快
    • 在移動設備/低功耗設備:ChaCha20通常表現更好
    • 在需要國密合規的系統:SM4是唯一選擇,盡管性能較低

六、實際應用中的對稱加密選擇指南

6.1 應用場景決策樹

以下是選擇對稱加密算法的決策樹:

  1. 是否需要合規性?

    • 需要中國密碼標準合規性 → 選擇SM4
    • 需要FIPS合規性 → 選擇AES
    • 無特殊合規要求 → 繼續下一步
  2. 運行環境是什么?

    • 具有AES硬件加速的環境 → 優先考慮AES
    • 移動設備/嵌入式系統 → 優先考慮ChaCha20
    • 跨平臺環境 → 兩者都可以,根據具體需求選擇
  3. 是否需要認證加密?

    • 需要 → 選擇AES-GCM或ChaCha20-Poly1305
    • 不需要(將單獨實現認證)→ 選擇AES-CBC/CTR或ChaCha20
  4. 數據量和性能需求如何?

    • 大量數據,高性能需求 → 根據環境選擇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實現中,優先順序通常為:

  1. 如果客戶端CPU支持AES-NI,則選擇AES-GCM
  2. 否則,選擇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 對稱加密的最佳實踐

  1. 密鑰管理

    • 永遠不要硬編碼密鑰
    • 使用密鑰派生函數(KDF)從密碼生成密鑰
    • 考慮使用硬件安全模塊(HSM)或密鑰管理服務
    • 實施密鑰輪換機制
  2. 初始向量/Nonce處理

    • 對每次加密使用唯一的IV/Nonce
    • IV/Nonce可以公開,但必須與密文一起傳輸
    • 避免使用可預測的或固定的IV
  3. 認證與完整性

    • 優先使用帶認證的加密模式(AEAD)
    • 如果使用非認證模式,必須單獨實現完整性驗證
  4. 實現安全考量

    • 使用經過驗證的加密庫,避免自行實現
    • 注意時序攻擊,確保恒定時間比較
    • 避免異常信息泄露加密細節
  5. 算法選擇

    • 大多數場景優選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 或輕量級算法資源占用低

工程師實踐指南

  1. 選擇成熟的密碼庫

    • Python: PyCryptodome, cryptography
    • Java: BouncyCastle, JCA
    • C/C++: OpenSSL, libsodium
    • JavaScript: Web Crypto API, TweetNaCl.js
  2. 常見加密任務的設計模式

    • 文件加密:加密內容+元數據頭
    • 數據庫字段加密:單獨的IV+密文
    • API通信:自動化密鑰協商+會話密鑰
  3. 合規性考量

    • 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: 零填充,使用零字節填充數據塊的技術。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/79661.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/79661.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/79661.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MATLAB圖像加密案例

下面是一個使用 MATLAB 編寫的簡單圖像塊置亂加密/解密程序,主要利用了函數來組織代碼。 這個程序通過將圖像分割成小塊,然后根據一個密鑰(用于隨機數生成器種子)打亂這些塊的順序來實現加密。解密過程則使用相同的密鑰恢復原始塊順序。 核心思想: 分塊: 將圖像劃分為 …

阿里云服務器全棧技術指導手冊(2025版)

阿里云服務器全棧技術指導手冊(2025版) 一、基礎配置與核心架構設計 1. 精準實例選型策略 ? 通用計算場景:選擇ECS通用型(如ecs.g7)實例,搭載第三代Intel Xeon處理器,適合Web應用、中小型數…

word批量轉pdf工具

word批量轉pdf工具 圖片 說到了辦公,怎能不提PDF轉換哦? 這是一款一鍵就可以批量word轉換為PDF的小工具,簡直是VB界的一股清流。 圖片 操作簡單到不行,只要把需要轉換的word文件和這個工具放在同一個文件夾里,雙擊…

C++類_協變返回類型

協變返回類型定義 在 C11 中,協變返回類型是指在基類和派生類的虛函數重寫時,派生類中重寫的虛函數的返回類型可以是基類中對應虛函數返回類型的派生類型。也就是說,當基類的虛函數返回一個基類指針或引用時,派生類中重寫該虛函數…

補充:建立實體類與數據表的映射關系

目錄 前言 1 成員變量數據類型和字段類型 保持對應 2 成員變量的變量名,應采用小駝峰命名法 3 數據表中的主鍵如id 應采用自增方式 4 數據表中的時間類型數據與實體類中的時間類型的變量無法實現自動映射可以使用JsonFormat 注解 4.1 配置全局時間處理器&#x…

HTML/CSS 魔法第二彈:會逃跑的調皮按鈕(懸停自動閃避)

引言 在網頁設計中,交互性是吸引用戶的關鍵因素之一。普通的按鈕在用戶懸停時可能只是顏色或樣式發生改變,但今天我們要創造一個 “調皮” 的按鈕,當用戶鼠標懸停在上面時,它會自動閃避,仿佛在和用戶玩游戲。本文將詳…

**Java面試:技術大比拼**

互聯網大廠Java面試:一場嚴肅與搞笑交織的技術拷問 場景:互聯網大廠面試間 面試官(嚴肅):請坐。馬小帥,我們今天主要考察一下你在Java技術棧上的掌握程度,以及如何將這些技術應用于實際業務場景…

25考頻高的前端面試題

請求失敗會彈出一個toast,如何保證批量請求失敗,只彈出一個toast 設置全局標志位,定義一個全局變量(如isToastShown)來表示是否已經彈出過toast。在請求失敗的處理邏輯中,首先檢查該標志位。如果尚未彈出toast&#xf…

命令模式(Command Pattern)詳解

文章目錄 1. 什么是命令模式?2. 為什么需要命令模式?3. 命令模式的核心概念4. 命令模式的結構5. 命令模式的基本實現5.1 簡單的燈光控制示例5.2 家電控制示例6. 帶有撤銷功能的命令模式6.1 修改命令接口6.2 實現可撤銷的燈光命令6.3 實現可撤銷的風扇命令6.4 修改調用者,支持…

《Vue3學習手記8》

vue3中的一些API shallowRef ( ) 和shallowReactive ( ) shallowRef (淺層響應式) 1.作用:創建一個響應式數據,但只對頂層屬性進行響應式處理。 2.用法: const originalref(...) const original2shallowRef(original) 3.特點:只跟蹤引用值的變化,不關心…

雙列集合——map集合和三種遍歷方式

雙列集合的特點 鍵和值一一對應,每個鍵只能對應自己的值 一個鍵和值整體稱為鍵值對或鍵值對對象,java中叫做entry對象。 map常見的api map接口中定義了雙列集合所有的共性方法,下面三個實現類就沒有什么額外新的方法要學習了。 map接口…

Linux安裝部署Postgresql數據庫

聯網安裝方案 Linux能在線安裝依賴組件的前提下,可以快速安裝部署PG數據庫,安裝過程使用root管理員帳號: 首先,使用如下命令自動下載Postgresql組件: # 在openEuler、Fedora或CentOS 8上,你可能會使用&a…

供應鏈算法整理(二)--- 智能補貨

供應鏈業務的目標價值是:優化貨品的供給、銷售提供支撐,以降低成本,提高時效、收益,最終提升用戶體驗。基于目標價值,整體的算法模塊分為:智能選品、智能預測、品倉鋪貨、智能補貨、智能調撥、倉網路由、快…

vscode 個性化

vscode 個性化 設置 吸頂效果 使用前使用后 設置方法 VS Code 的粘性滾動預覽 - 類似于 Excel 的凍結首行 插件 代碼片段分享 - CodeSnap 使用方式 CtrlShiftP輸入CodeSnap 喚起插件選擇代碼 行內報錯提示 - Error Lens 使用前使用后 VSCode Error Lens插件介紹&…

Rockermq的部署與使用(0-1)

?RocketMQ? 是阿里巴巴開源的一款 ?分布式消息中間件,具有高吞吐、低延遲、高可用等特點,廣泛應用于多個領域,包括異步通信解耦、企業解決方案、金融支付、電信、電子商務、快遞物流、廣告營銷、社交、即時通信、移動應用、手游、視頻、物…

軟件測試報告機構如何保障軟件質量并維護其安全性?

軟件測試報告機構在軟件開發流程里起著十分關鍵的作用,它可以保障軟件的質量,它還能夠維護軟件的安全性。下面,我們就來深入了解一下這類機構。 機構作用 軟件測試報告機構是軟件質量的“把關者”,能對軟件進行全面評估&#xf…

4個純CSS自定義的簡單而優雅的滾動條樣式

今天發現 uni-app 項目的滾動條不顯示,查了下原來是設置了 ::-webkit-scrollbar {display: none; } 那么怎么用 css 設置滾動條樣式呢? 定義滾動條整體樣式? ::-webkit-scrollbar 定義滾動條滑塊樣式 ::-webkit-scrollbar-thumb 定義滾動條軌道樣式?…

ES6入門---第二單元 模塊五:模塊化

js不支持模塊化 注意: 需要放到服務器環境 1、如何定義模塊? export 東西 例:1.js文件中 console.log(1模塊加載了);//顯示是否加載了 export const a 12; export const b 5; export let c 101; const a12; const b5; const c101;ex…

14.Excel:排序和篩選

一 位置 兩個位置。 二 排序:如何使用 1.常規使用 補充:不彈出排序提醒排序。 選中要排序列中的任意一個單元格,然后排序。 2.根據要求進行排序 1.根據姓名筆畫進行降序排序 要勾選上數據包含標題,默認是勾選了。 2.根據運營部、…

嵌入式系統基礎知識

目錄 一、馮諾依曼結構與哈佛結構 (一)馮諾依曼結構 (二)哈佛架構 二、ARM存儲模式 (一)大端模式 (二)小端模式 (三)混合模式 三、CISC 與 RISC &am…