RSA 作為非對稱加密的基本,在資安領域扮演著關鍵角色。理解其金鑰生成、載入、加解密流程至關重要。本文將以 Python cryptography 函式庫示範 RSA 金鑰的實務操作,包含金鑰的生成、儲存、讀取以及如何進行加密和解密。同時,也將探討對稱加密與非對稱加密的差異、數字簽章的應用,以及與 TLS/SSL、HTTPS 的關聯。這些技術在保障網路安全和資料完整性方面至關重要,是現代軟體開發人員必備的知識。
Fernet 的優點
Fernet 有以下優點:
- 安全:Fernet 使用 AES-128-CBC 進行加密,能夠確保資料的機密性。
- 簡單:Fernet 的使用方法簡單,易於理解和實作。
- 驗證:Fernet 使用 HMAC-SHA256 進行驗證,能夠確保資料的完整性。
MultiFernet
MultiFernet 是 Fernet 的一種變體,允許使用多個金鑰進行加密和解密。這使得在金鑰更新或更換時,可以使用舊的金鑰進行解密,而不需要重新加密所有的資料。
什麼是對稱加密?
對稱加密是一種加密方法,使用相同的金鑰進行加密和解密。這種方法的優點是速度快、效率高,但缺點是需要安全地儲存和傳遞金鑰。
什麼是非對稱加密?
非對稱加密是一種加密方法,使用一對金鑰進行加密和解密,其中一把是公開的,另一把是私有的。這種方法的優點是可以安全地傳遞公開金鑰,而不需要擔心私有金鑰的安全性。
什麼是數字簽名?
數字簽名是一種技術,使用私有金鑰生成一個數字碼,該碼可以用於驗證訊息的真實性和完整性。這種技術可以用於確保訊息的不可否認性和完整性。
AES
AES(Advanced Encryption Standard)是一種對稱加密演算法,廣泛用於各種應用中。它的優點是速度快、效率高、安全性好。
什麼是 CBC 模式?
CBC(Cipher Block Chaining)模式是一種分塊加密模式,使用前一塊的加密結果作為下一塊的初始向量。這種模式可以提高加密的安全性。
什麼是 GCM 模式?
GCM(Galois/Counter Mode)模式是一種分塊加密模式,使用計數器作為初始向量。這種模式可以提高加密的安全性和效率。
什麼是 IV?
IV(Initialization Vector)是一個用於初始化加密演算法的向量。它可以提高加密的安全性和不可預測性。
什麼是 Fernet 的限制?
Fernet 的限制包括:
- 只能使用 AES-128-CBC 進行加密。
- 只能使用 HMAC-SHA256 進行驗證。
- 不支援其他加密演算法或模式。
什麼是對稱加密的限制?
對稱加密的限制包括:
- 需要安全地儲存和傳遞金鑰。
- 如果金鑰被洩露,所有使用該金鑰的資料都可能被解密。
什麼是非對稱加密的限制?
非對稱加密的限制包括:
- 速度慢於對稱加密。
- 需要更大的金鑰尺寸來達到相同的安全性。
什麼是數字簽名的限制?
數字簽名的限制包括:
- 需要一個可靠的時間戳記機制來防止重播攻擊。
- 需要一個可靠的認證機制來確保簽名者的身份。
5.2 RSA:一種經典的非對稱加密演算法
RSA是一種廣泛使用的非對稱加密演算法,於1970年代末期由Ron Rivest、Adi Shamir和Leonard Adleman發明。其名稱來自三位發明者的姓氏首字母。
生成RSA金鑰
為了生成RSA金鑰,我們可以使用OpenSSL工具。以下命令生成了一個3072位元的RSA私鑰:
openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:3072
這將生成一個名為private_key.pem
的私鑰檔案。
提取公鑰
從私鑰中,我們可以提取出公鑰:
openssl rsa -pubout -in private_key.pem -out public_key.pem
這將生成一個名為public_key.pem
的公鑰檔案。
金鑰格式
OpenSSL工具生成的金鑰檔案是以PEM(Privacy-Enhanced Mail)格式儲存的。PEM是一種標準的金鑰格式,其檔案內容以-----BEGIN
開頭,結尾為-----END
。
設定金鑰許可權
為了確保金鑰安全,我們需要設定適當的許可權。私鑰檔案應該只有擁有者才能讀寫,而公鑰檔案可以讓任何人讀取:
chmod 600 private_key.pem
chmod 644 public_key.pem
使用Python生成RSA金鑰
我們也可以使用Python的cryptography函式庫來生成RSA金鑰:
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=3072,
backend=default_backend()
)
public_key = private_key.public_key()
這將生成一個私鑰和公鑰物件。
儲存金鑰
最後,我們可以將金鑰儲存到檔案中:
with open('private_key.pem', 'wb') as f:
f.write(private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption()
))
with open('public_key.pem', 'wb') as f:
f.write(public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
))
這將儲存私鑰和公鑰到檔案中。
生成 RSA 金鑰對並儲存
首先,我們需要生成一對 RSA 金鑰,包括私鑰和公鑰。這可以透過以下 Python 程式碼實作:
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
# 生成私鑰
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
)
# 取得公鑰
public_key = private_key.public_key()
# 將私鑰序列化為 PEM 格式
private_bytes = private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption(),
)
# 將公鑰序列化為 PEM 格式
public_bytes = public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo,
)
# 寫入私鑰和公鑰到檔案
with open('private_key.pem', 'wb') as private_file:
private_file.write(private_bytes)
with open('public_key.pem', 'wb') as public_file:
public_file.write(public_bytes)
從檔案載入 RSA 金鑰對
接下來,我們可以從檔案中載入已經生成的 RSA 金鑰對:
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
# 載入私鑰
with open('private_key.pem', 'rb') as private_file:
loaded_private_key = serialization.load_pem_private_key(
private_file.read(),
password=None,
)
# 載入公鑰
with open('public_key.pem', 'rb') as public_file:
loaded_public_key = serialization.load_pem_public_key(
public_file.read(),
)
使用 RSA 進行加密和解密
現在,我們可以使用 RSA 金鑰對進行加密和解密:
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
# 設定加密模式為 OAEP
padding_config = padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None,
)
# 原始訊息
plaintext = b'message from Alice to Bob'
# 使用公鑰加密訊息
ciphertext = loaded_public_key.encrypt(
plaintext=plaintext,
padding=padding_config,
)
# 使用私鑰解密訊息
decrypted_by_private_key = loaded_private_key.decrypt(
ciphertext=ciphertext,
padding=padding_config,
)
# 驗證解密結果
assert decrypted_by_private_key == plaintext
注意:在實際應用中,應該使用安全的隨機數生成器生成金鑰對,並且應該妥善儲存私鑰以防止洩露。
第五章:非對稱式加密
非對稱式加密是一種加密技術,使用一對金鑰:公開金鑰和私人金鑰。公開金鑰用於加密資料,而私人金鑰則用於解密資料。這種加密方式可以確保資料的機密性和完整性。
5.3:不可否認性
不可否認性是指確保資料的真實性和來源的能力。非對稱式加密可以用於實作不可否認性,方法是使用私人金鑰加密資料,然後使用公開金鑰解密資料。如果資料被篡改,則解密後的資料將不正確。
5.3.1:數位簽章
數位簽章是一種使用非對稱式加密的技術,用於確保資料的真實性和來源。數位簽章使用私人金鑰加密資料,然後使用公開金鑰解密資料。這種技術可以確保資料的機密性和完整性。
下面是使用Python實作的RSA數位簽章演算法:
import json
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes
message = b'from Bob to Alice'
padding_config = padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
)
private_key = load_rsa_private_key()
signature = private_key.sign(
message,
padding_config,
hashes.SHA256()
)
這段程式碼使用RSA演算法和SHA-256雜湊函式生成數位簽章。
5.3.2:使用RSA進行資料簽署
下面是使用RSA演算法進行資料簽署的範例:
import json
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes
message = b'from Bob to Alice'
padding_config = padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
)
private_key = load_rsa_private_key()
signature = private_key.sign(
message,
padding_config,
hashes.SHA256()
)
這段程式碼使用RSA演算法和SHA-256雜湊函式生成數位簽章。
圖表翻譯:
下圖展示了使用RSA演算法進行資料簽署的流程:
- 生成隨機資料
- 使用私人金鑰加密資料
- 使用公開金鑰解密資料
flowchart TD A[生成隨機資料] --> B[使用私人金鑰加密資料] B --> C[使用公開金鑰解密資料]
這個流程可以確保資料的機密性和完整性。
驗證數字簽章
當 Alice 收到 Bob 的訊息和數字簽章後,她需要驗證簽章以確保訊息的真實性和完整性。以下是驗證過程:
步驟 1:計算訊息的雜湊值
Alice 首先計算訊息的雜湊值,使用 SHA-256 雜湊函式。
步驟 2:解密簽章
Alice 使用 Bob 的公鑰解密簽章,得到原始的雜湊值。
步驟 3:比較雜湊值
Alice 比較她計算出的雜湊值與從簽章中解密出的雜湊值。如果兩個雜湊值相同,則簽章有效,Alice 可以信任這個訊息。
以下是 Python 程式碼實作:
import json
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.exceptions import InvalidSignature
def receive(inbound_msg_from_bob):
signed_msg = json.loads(inbound_msg_from_bob)
message = bytes(signed_msg['message'])
signature = bytes(signed_msg['signature'])
padding_config = padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
)
public_key = load_rsa_public_key()
try:
public_key.verify(
signature,
message,
padding_config,
hashes.SHA256()
)
except InvalidSignature:
print("Invalid signature")
else:
print("Signature is valid")
在這個程式碼中,load_rsa_public_key()
函式負責載入 Bob 的公鑰。verify()
方法使用 PSS 填充方案和 SHA-256 雜湊函式驗證簽章。如果簽章有效,則方法不會丟擲異常;否則,會丟擲 InvalidSignature
異常。
Mermaid 圖表:驗證數字簽章
flowchart TD A[收到訊息和簽章] --> B[計算訊息的雜湊值] B --> C[解密簽章] C --> D[比較雜湊值] D --> E[簽章有效] E --> F[信任訊息] D --> G[簽章無效] G --> H[不信任訊息]
圖表翻譯:
此圖表展示了 Alice 驗證數字簽章的過程。首先,她收到 Bob 的訊息和簽章。然後,她計算訊息的雜湊值,解密簽章,比較兩個雜湊值。如果簽章有效,則她信任這個訊息;否則,她不信任這個訊息。
非對稱密碼學的應用:數字簽章與驗證
在非對稱密碼學中,數字簽章是一種確保訊息真實性和完整性的重要機制。它允許傳送者使用自己的私鑰對訊息進行簽署,然後接收者可以使用傳送者的公鑰來驗證簽章的有效性。
數字簽章的原理
數字簽章的過程通常涉及以下步驟:
- 訊息摘要:首先,對要傳送的訊息進行摘要,產生一個固定長度的雜湊值(Hash Value)。
- 私鑰簽署:然後,使用傳送者的私鑰對這個雜湊值進行加密,產生數字簽章。
- 公鑰驗證:接收者收到訊息和數字簽章後,使用傳送者的公鑰對數字簽章進行解密,得到原雜湊值。
- 驗證:最後,接收者對收到的訊息再次計算雜湊值,並將其與從數字簽章中解密出的雜湊值進行比較。如果兩者匹配,則證明訊息在傳輸過程中沒有被篡改。
根據RSA的數字簽章
RSA是一種常用的非對稱密碼演算法,也可以用於數字簽章。以下是根據RSA的數字簽章過程:
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import rsa, padding
# 生成RSA金鑰對
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
backend=default_backend()
)
public_key = private_key.public_key()
# 要傳送的訊息
message = b'Hello, World!'
# 簽署訊息
signature = private_key.sign(
message,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
),
hashes.SHA256()
)
# 驗證簽章
try:
public_key.verify(
signature,
message,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
),
hashes.SHA256()
)
print("簽章有效")
except:
print("簽章無效")
根據橢圓曲線密碼學的數字簽章
橢圓曲線密碼學(ECC)是一種根據數論難題的公鑰密碼體系,相比RSA,ECC具有更高的安全性和更小的金鑰尺寸。以下是根據ECC的數字簽章過程:
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec
# 生成ECC金鑰對
private_key = ec.generate_private_key(ec.SECP384R1(), default_backend())
public_key = private_key.public_key()
# 要傳送的訊息
message = b'Hello, World!'
# 簽署訊息
signature = private_key.sign(
message,
ec.ECDSA(hashes.SHA256())
)
# 驗證簽章
try:
public_key.verify(
signature,
message,
ec.ECDSA(hashes.SHA256())
)
print("簽章有效")
except:
print("簽章無效")
網路安全:Transport Layer Security(TLS)概覽
Transport Layer Security(TLS)是一種廣泛使用的網路安全協定,負責確保網路通訊的安全性和完整性。TLS 的前身是 Secure Sockets Layer(SSL),但由於 SSL 已經不再安全,目前已被 TLS 取代。
TLS、SSL 和 HTTPS 的區別
- SSL(Secure Sockets Layer):是一種早期的網路安全協定,已經不再安全。
- TLS(Transport Layer Security):是一種更新的網路安全協定,取代了 SSL,提供更好的安全性和效能。
- HTTPS(Hypertext Transfer Protocol Secure):是一種將 HTTP 通訊協定封裝在 TLS 或 SSL 中的安全通訊協定,提供加密和身份驗證的功能。
TLS 的工作原理
TLS 的工作原理涉及以下幾個步驟:
- 連線確認:客戶端和伺服器端建立連線,並交換彼此的憑證和加密引數。
- 加密:客戶端和伺服器端使用分享的秘密金鑰對資料進行加密。
- 身份驗證:客戶端和伺服器端使用憑證和數字簽章進行身份驗證。
TLS 的優點
- 保證資料完整性:TLS 可以確保資料在傳輸過程中不會被竄改或破壞。
- 保證資料機密性:TLS 可以確保資料在傳輸過程中不會被擷取或竊聽。
- 提供身份驗證:TLS 可以確保客戶端和伺服器端的身份是真實的。
實踐 TLS
要實踐 TLS,需要以下幾個步驟:
- 取得憑證:申請並取得憑證,憑證包含了公開金鑰和身份資訊。
- 組態伺服器:組態伺服器以支援 TLS,並設定憑證和加密引數。
- 更新客戶端:更新客戶端以支援 TLS,並設定憑證和加密引數。
資料安全在數位時代的重要性日益凸顯,非對稱加密技術與 TLS/SSL 協定的應用成為保障網路安全的基本。本文深入探討了 Fernet、MultiFernet 的特性與限制,並詳細闡述了對稱加密、非對稱加密、數字簽章等核心概念,同時也分析了 RSA 和 ECC 等非對稱加密演算法的實作細節,以及在 TLS/SSL 協定中的應用。技術限制深析顯示,對稱加密的金鑰管理和非對稱加密的效能瓶頸仍是待突破的挑戰。而整合價值分析則表明,將這些加密技術與 TLS/SSL 協定結合,能有效提升網路通訊的安全性。展望未來,隨著量子計算的發展,後量子密碼學將成為新的研究熱點,而更輕量級、更高效的加密演算法也將不斷湧現,推動網路安全技術的持續演進。玄貓認為,掌握這些密碼學基礎知識和實務技巧,對於構建更安全的網路環境至關重要。