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演算法進行資料簽署的流程:

  1. 生成隨機資料
  2. 使用私人金鑰加密資料
  3. 使用公開金鑰解密資料
  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 的訊息和簽章。然後,她計算訊息的雜湊值,解密簽章,比較兩個雜湊值。如果簽章有效,則她信任這個訊息;否則,她不信任這個訊息。

非對稱密碼學的應用:數字簽章與驗證

在非對稱密碼學中,數字簽章是一種確保訊息真實性和完整性的重要機制。它允許傳送者使用自己的私鑰對訊息進行簽署,然後接收者可以使用傳送者的公鑰來驗證簽章的有效性。

數字簽章的原理

數字簽章的過程通常涉及以下步驟:

  1. 訊息摘要:首先,對要傳送的訊息進行摘要,產生一個固定長度的雜湊值(Hash Value)。
  2. 私鑰簽署:然後,使用傳送者的私鑰對這個雜湊值進行加密,產生數字簽章。
  3. 公鑰驗證:接收者收到訊息和數字簽章後,使用傳送者的公鑰對數字簽章進行解密,得到原雜湊值。
  4. 驗證:最後,接收者對收到的訊息再次計算雜湊值,並將其與從數字簽章中解密出的雜湊值進行比較。如果兩者匹配,則證明訊息在傳輸過程中沒有被篡改。

根據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 的工作原理涉及以下幾個步驟:

  1. 連線確認:客戶端和伺服器端建立連線,並交換彼此的憑證和加密引數。
  2. 加密:客戶端和伺服器端使用分享的秘密金鑰對資料進行加密。
  3. 身份驗證:客戶端和伺服器端使用憑證和數字簽章進行身份驗證。

TLS 的優點

  • 保證資料完整性:TLS 可以確保資料在傳輸過程中不會被竄改或破壞。
  • 保證資料機密性:TLS 可以確保資料在傳輸過程中不會被擷取或竊聽。
  • 提供身份驗證:TLS 可以確保客戶端和伺服器端的身份是真實的。

實踐 TLS

要實踐 TLS,需要以下幾個步驟:

  1. 取得憑證:申請並取得憑證,憑證包含了公開金鑰和身份資訊。
  2. 組態伺服器:組態伺服器以支援 TLS,並設定憑證和加密引數。
  3. 更新客戶端:更新客戶端以支援 TLS,並設定憑證和加密引數。

資料安全在數位時代的重要性日益凸顯,非對稱加密技術與 TLS/SSL 協定的應用成為保障網路安全的基本。本文深入探討了 Fernet、MultiFernet 的特性與限制,並詳細闡述了對稱加密、非對稱加密、數字簽章等核心概念,同時也分析了 RSA 和 ECC 等非對稱加密演算法的實作細節,以及在 TLS/SSL 協定中的應用。技術限制深析顯示,對稱加密的金鑰管理和非對稱加密的效能瓶頸仍是待突破的挑戰。而整合價值分析則表明,將這些加密技術與 TLS/SSL 協定結合,能有效提升網路通訊的安全性。展望未來,隨著量子計算的發展,後量子密碼學將成為新的研究熱點,而更輕量級、更高效的加密演算法也將不斷湧現,推動網路安全技術的持續演進。玄貓認為,掌握這些密碼學基礎知識和實務技巧,對於構建更安全的網路環境至關重要。