在資訊安全領域,數字簽名和混合加密是保障資料完整性和機密性的關鍵技術。本文將以 Python 語言示範如何運用 cryptography 和 PyCryptodome 函式庫實作這些技術,並深入探討不同加密模式的特性與應用場景。首先,我們會介紹如何生成 RSA 金鑰對,並使用私鑰進行簽名,再以公鑰驗證簽名,確保資料的完整性。接著,我們將示範如何結合對稱加密 AES 和非對稱加密 RSA,實作混合加密,以兼顧效率和安全性。程式碼範例中將涵蓋金鑰生成、加密、解密、簽名和驗證等完整流程,並提供 AES-CBC、AES-GCM 和 DES-CBC 等加密模式的實作細節,同時也將探討填充、隨機數生成等安全性議題,幫助讀者更深入地理解這些技術的實務應用。
實作數字簽名和驗證
在實作數字簽名和驗證時,需要使用私鑰和公鑰。以下是使用 Python 和 cryptography 函式庫實作的例子:
生成私鑰和公鑰
首先,需要生成私鑰和公鑰。這可以使用generate_rsa_keypair
函式實作:
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.backends import default_backend
def generate_rsa_keypair():
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
backend=default_backend()
)
public_key = private_key.public_key()
return private_key, public_key
簽名和驗證
接下來,需要實作簽名和驗證功能。以下是使用private_key
和public_key
實作的例子:
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
def sign_data(private_key, data: bytes) -> bytes:
signature = private_key.sign(
data,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
),
hashes.SHA256()
)
return signature
def verify_signature(public_key, data: bytes, signature: bytes) -> bool:
try:
public_key.verify(
signature,
data,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
),
hashes.SHA256()
)
return True
except Exception:
return False
使用示例
以下是使用上述函式的示例:
private_key, public_key = generate_rsa_keypair()
data = b"Data integrity verification through digital signatures."
signature = sign_data(private_key, data)
assert verify_signature(public_key, data, signature)
安全考量
在實作數字簽名和驗證時,需要考慮安全性。以下是一些安全考量:
- 私鑰和公鑰需要安全儲存和管理。
- 需要使用安全的隨機數生成器來生成非對稱金鑰。
- 需要使用安全的雜湊函式來生成訊息摘要。
- 需要使用安全的填充方案來防止填充攻擊。
結合對稱和非對稱加密
在實際應用中,往往需要結合對稱和非對稱加密來實作安全的資料傳輸。以下是結合對稱和非對稱加密的示例:
from cryptography.hazmat.primitives import padding
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
def encrypt_data(symmetric_key: bytes, data: bytes) -> bytes:
# 生成隨機的IV
iv = os.urandom(16)
# 建立AES-CBC加密器
cipher = Cipher(algorithms.AES(symmetric_key), modes.CBC(iv))
# 對資料進行填充
padder = padding.PKCS7(128).padder()
padded_data = padder.update(data) + padder.finalize()
# 對填充後的資料進行加密
encryptor = cipher.encryptor()
encrypted_data = encryptor.update(padded_data) + encryptor.finalize()
# 傳回IV和加密後的資料
return iv + encrypted_data
def decrypt_data(symmetric_key: bytes, encrypted_data: bytes) -> bytes:
# 提取IV
iv = encrypted_data[:16]
# 建立AES-CBC解密器
cipher = Cipher(algorithms.AES(symmetric_key), modes.CBC(iv))
# 對加密後的資料進行解密
decryptor = cipher.decryptor()
decrypted_padded_data = decryptor.update(encrypted_data[16:]) + decryptor.finalize()
# 對解密後的資料進行去填充
unpadder = padding.PKCS7(128).unpadder()
data = unpadder.update(decrypted_padded_data) + unpadder.finalize()
# 傳回解密後的資料
return data
隨機數生成
在實作加密演算法時,需要使用安全的隨機數生成器來生成隨機數。以下是使用os
模組生成隨機數的示例:
import os
def generate_random_bytes(length: int) -> bytes:
return os.urandom(length)
混合加密技術範例
混合加密是一種結合了對稱加密和非對稱加密優點的技術。以下是使用 Python 實作的混合加密範例:
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
def hybrid_encrypt(public_key, plaintext: bytes) -> tuple:
# 生成隨機的AES金鑰
symmetric_key = get_random_bytes(32)
# 使用AES-GCM模式加密明文
nonce = get_random_bytes(12)
aes_cipher = AES.new(symmetric_key, AES.MODE_GCM, nonce=nonce)
ciphertext, auth_tag = aes_cipher.encrypt_and_digest(plaintext)
# 使用RSA公鑰加密對稱金鑰
encrypted_key = public_key.encrypt(
symmetric_key,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
return encrypted_key, nonce, ciphertext, auth_tag
這個混合加密模型展示瞭如何結合不同的加密函式庫來實作一個安全且高效的解決方案。高階開發人員可以抽象出這些操作並將其轉換為可重用的模組,以確保金鑰材料在其生命週期中被正確管理。
混合加密的優點
混合加密結合了對稱加密和非對稱加密的優點。對稱加密提供了高效的加密和解密,而非對稱加密提供了安全的金鑰交換和身份驗證。透過結合這兩種加密方式,混合加密可以提供一個安全且高效的解決方案。
實踐中的混合加密
在實踐中,混合加密可以用於保護敏感資料。例如,在網路通訊中,可以使用混合加密來保護資料的機密性和完整性。在雲端儲存中,可以使用混合加密來保護資料的安全性。
混合加密的挑戰
混合加密也面臨著一些挑戰。例如,金鑰管理是混合加密中的一個關鍵問題。需要確保金鑰被安全地生成、分發和儲存。此外,混合加密也需要考慮效能問題,因為加密和解密過程可能會耗費大量的計算資源。
圖表翻譯:
flowchart TD A[明文] --> B[對稱加密] B --> C[非對稱加密] C --> D[密鑰]
這個圖表展示了混合加密的過程。首先,明文被對稱加密,然後對稱金鑰被非對稱加密,最後生成密鑰。
對稱加密:AES-CBC 模式實作
對稱加密是一種使用相同金鑰進行加密和解密的加密方式。其中,AES(Advanced Encryption Standard)是一種廣泛使用的對稱加密演算法。本文將介紹如何使用 AES-CBC(Cipher Block Chaining)模式進行加密和解密。
填充函式
在 AES 加密中,塊大小(block size)是固定的,為 128 位元組(16 位元組)。當要加密的資料不足一塊時,需要進行填充。以下是填充函式的實作:
def pad(data: bytes) -> bytes:
"""
對資料進行填充,使其長度成為AES塊大小的倍數。
:param data: 要填充的資料
:return: 填充後的資料
"""
block_size = AES.block_size
padding_length = block_size - len(data) % block_size
return data + bytes([padding_length] * padding_length)
解填充函式
在解密後,需要移除填充的位元組。以下是解填充函式的實作:
def unpad(data: bytes) -> bytes:
"""
移除填充的位元組。
:param data: 要解填充的資料
:return: 解填充後的資料
"""
padding_length = data[-1]
if padding_length > AES.block_size:
raise ValueError("Invalid padding")
return data[:-padding_length]
AES-CBC 加密
以下是 AES-CBC 加密的實作:
def aes_cbc_encrypt(plaintext: bytes, key: bytes) -> tuple:
"""
使用AES-CBC模式進行加密。
:param plaintext: 要加密的明文
:param key: 加密金鑰
:return: (iv, ciphertext) 的 tuple,其中 iv 是初始向量,ciphertext 是加密後的密鑰
"""
iv = get_random_bytes(AES.block_size)
cipher = AES.new(key, AES.MODE_CBC, iv)
padded_text = pad(plaintext)
ciphertext = cipher.encrypt(padded_text)
return iv, ciphertext
AES-CBC 解密
以下是 AES-CBC 解密的實作:
def aes_cbc_decrypt(iv: bytes, ciphertext: bytes, key: bytes) -> bytes:
"""
使用AES-CBC模式進行解密。
:param iv: 初始向量
:param ciphertext: 要解密的密鑰
:param key: 解密金鑰
:return: 解密後的明文
"""
cipher = AES.new(key, AES.MODE_CBC, iv)
padded_plaintext = cipher.decrypt(ciphertext)
return unpad(padded_plaintext)
範例使用
以下是範例使用:
key = get_random_bytes(32) # For AES-256
plaintext = b"Advanced symmetric encryption test message."
iv, ciphertext = aes_cbc_encrypt(plaintext, key)
print(f"IV: {iv.hex()}")
print(f"Ciphertext: {ciphertext.hex()}")
decrypted_text = aes_cbc_decrypt(iv, ciphertext, key)
print(f"Decrypted text: {decrypted_text.decode()}")
內容解密:
在上述範例中,我們首先生成了一個隨機的 32 位元組(256 位元)AES 金鑰。然後,我們使用aes_cbc_encrypt
函式對明文進行加密,得到初始向量iv
和加密後的密鑰ciphertext
。接著,我們使用aes_cbc_decrypt
函式對密鑰進行解密,得到解密後的明文decrypted_text
。
圖表翻譯:
flowchart TD A[明文] -->|加密|> B[初始向量和密鑰] B -->|解密|> C[明文]
在上述流程圖中,我們可以看到明文經過加密後變成初始向量和密鑰,然後再經過解密後還原成明文。
AES 加密模式:CBC 和 GCM
AES(Advanced Encryption Standard)是一種廣泛使用的對稱加密演算法,具有多種加密模式。其中,CBC(Cipher Block Chaining)和 GCM(Galois/Counter Mode)是兩種常用的加密模式。
CBC 加密模式
CBC 加密模式是一種分塊加密模式,每個分塊的加密結果依賴於前一個分塊的加密結果。這種模式需要一個初始向量(IV),用於初始化加密過程。
from Crypto.Cipher import AES
def aes_cbc_encrypt(plaintext: bytes, key: bytes) -> tuple:
iv = get_random_bytes(16)
cipher = AES.new(key, AES.MODE_CBC, iv)
ciphertext = cipher.encrypt(plaintext)
return iv, ciphertext
def aes_cbc_decrypt(iv: bytes, ciphertext: bytes, key: bytes) -> bytes:
cipher = AES.new(key, AES.MODE_CBC, iv)
plaintext = cipher.decrypt(ciphertext)
return plaintext
GCM 加密模式
GCM 加密模式是一種認證加密模式,提供了機密性和完整性保護。GCM 使用了一個 nonce(數字)和一個認證標籤(tag)來確保加密資料的完整性。
from Crypto.Cipher import AES
def aes_gcm_encrypt(plaintext: bytes, key: bytes) -> tuple:
nonce = get_random_bytes(12)
cipher = AES.new(key, AES.MODE_GCM, nonce=nonce)
ciphertext, tag = cipher.encrypt_and_digest(plaintext)
return nonce, ciphertext, tag
def aes_gcm_decrypt(nonce: bytes, ciphertext: bytes, tag: bytes, key: bytes) -> bytes:
cipher = AES.new(key, AES.MODE_GCM, nonce=nonce)
plaintext = cipher.decrypt_and_verify(ciphertext, tag)
return plaintext
DES 加密演算法
DES(Data Encryption Standard)是一種舊的對稱加密演算法,已經不再被視為安全。然而,DES 仍然被用於某些特定的應用中,例如在過渡系統中。
from Crypto.Cipher import DES
def des_cbc_encrypt(plaintext: bytes, key: bytes) -> tuple:
if len(key)!= 8:
raise ValueError("Invalid key length")
iv = get_random_bytes(8)
cipher = DES.new(key, DES.MODE_CBC, iv)
padded_data = des_pad(plaintext)
ciphertext = cipher.encrypt(padded_data)
return iv, ciphertext
def des_pad(data: bytes) -> bytes:
block_size = DES.block_size
padding_length = block_size - len(data) % block_size
return data + bytes([padding_length] * padding_length)
def des_unpad(data: bytes) -> bytes:
padding_length = data[-1]
if padding_length > DES.block_size:
raise ValueError("Invalid padding")
return data[:-padding_length]
圖表翻譯:
flowchart TD A[明文] --> B[加密] B --> C[密鑰] C --> D[解密] D --> E[明文]
內容解密:
上述程式碼實作了 AES 的 CBC 和 GCM 加密模式,以及 DES 的 CBC 加密模式。CBC 加密模式需要一個初始向量(IV),而 GCM 加密模式需要一個 nonce 和一個認證標籤(tag)。DES 加密演算法已經不再被視為安全,但仍然被用於某些特定的應用中。
對稱式加密技術的進階應用
對稱式加密是一種使用相同金鑰進行加密和解密的加密技術。雖然 DES(Data Encryption Standard)已經不再被廣泛使用,但其仍然是一個重要的研究物件,幫助我們瞭解加密演算法的演進和攻擊方法的發展。
DES 加密的實作
以下是使用 Python 實作 DES 加密的例子:
from cryptography.hazmat.primitives import padding
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
import os
def des_cbc_encrypt(plaintext: bytes, key: bytes) -> (bytes, bytes):
if len(key)!= 8:
raise ValueError("DES key must be 8 bytes long")
iv = os.urandom(8)
cipher = Cipher(algorithms.TripleDES(key), modes.CBC(iv), backend=default_backend())
encryptor = cipher.encryptor()
padder = padding.PKCS7(64).padder()
padded_data = padder.update(plaintext) + padder.finalize()
ciphertext = encryptor.update(padded_data) + encryptor.finalize()
return iv, ciphertext
def des_cbc_decrypt(iv: bytes, ciphertext: bytes, key: bytes) -> bytes:
cipher = Cipher(algorithms.TripleDES(key), modes.CBC(iv), backend=default_backend())
decryptor = cipher.decryptor()
padded_plaintext = decryptor.update(ciphertext) + decryptor.finalize()
unpadder = padding.PKCS7(64).unpadder()
plaintext = unpadder.update(padded_plaintext) + unpadder.finalize()
return plaintext
# Example usage for DES
key = os.urandom(8)
plaintext = b"DES encryption test."
iv, ciphertext = des_cbc_encrypt(plaintext, key)
decrypted_text = des_cbc_decrypt(iv, ciphertext, key)
assert decrypted_text == plaintext
非對稱式加密技術
非對稱式加密使用一對金鑰:公鑰用於加密,私鑰用於解密。這種加密方法的安全性根據數學問題的複雜性,例如整數分解、格子還原或橢圓曲線離散對數。
從技術架構視角來看,本文深入淺出地介紹了數字簽名、混合加密和對稱加密的實作方法,涵蓋了 RSA、AES-CBC、AES-GCM 以及過時的 DES 演算法。透過 Python 程式碼範例,清晰地展現了這些加密技術的核心概念和實作細節,尤其在填充、金鑰管理和安全隨機數生成方面提供了實務上的指導。然而,文章並未深入探討各種加密模式的優缺點及適用場景,例如 CBC 模式的 IV 安全性問題以及 GCM 模式的認證機制。此外,對於金鑰的生命週期管理,僅簡略提及高階開發人員應抽象化並建立可重用模組,缺乏更具體的實務建議。展望未來,隨著量子計算的發展,現有的非對稱加密演算法將面臨嚴峻挑戰,後量子密碼學的研究和應用將成為保障資訊安全的重要方向。對於注重資料安全的企業,建議持續關注密碼學的最新發展,並及早規劃遷移至更安全的加密演算法,以降低未來潛在的資安風險。 玄貓認為,理解並正確應用這些加密技術對於保障資訊安全至關重要,開發者應重視金鑰管理和演算法選擇,並持續學習密碼學的最新進展。