非對稱加密技術利用公鑰和私鑰對,確保資料的機密性、完整性和真實性。公鑰加密的資料只能用對應的私鑰解密,反之亦然。數位簽章則利用私鑰簽署資料,接收方使用公鑰驗證簽章,確認資料來源和完整性。這些技術在現代網路安全中扮演著至關重要的角色,例如 TLS 協定,用於保護網站和網路服務的安全性。理解這些技術的工作原理,有助於開發更安全的應用程式。

在資訊安全領域,非對稱加密與數位簽章是不可或缺的技術基本。非對稱加密演算法使用一對金鑰(公鑰和私鑰),其中公鑰用於加密訊息,私鑰則用於解密訊息,確保資料的機密性。數位簽章則利用私鑰對資料進行簽名,接收端使用公鑰驗證簽章的真實性與資料的完整性,防止資料遭到竄改。本文將深入探討非對稱加密與數位簽章的原理和應用,並提供 Python 程式碼範例,幫助讀者更深入理解這些技術。

非對稱加密和數字簽名

非對稱加密是一種使用公鑰和私鑰的加密方式。公鑰用於加密資料,而私鑰則用於解密資料。這種方式可以確保資料的機密性和完整性。

非對稱加密的工作原理

非對稱加密的工作原理是使用公鑰和私鑰的配對。公鑰用於加密資料,而私鑰則用於解密資料。這種方式可以確保資料的機密性和完整性。

加密過程

  1. 首先,需要生成一對公鑰和私鑰。
  2. 對方使用公鑰加密資料。
  3. 加密後的資料傳送給您。
  4. 您使用私鑰解密資料。

解密過程

  1. 首先,需要生成一對公鑰和私鑰。
  2. 對方使用私鑰加密資料。
  3. 加密後的資料傳送給您。
  4. 您使用公鑰解密資料。

數字簽名

數字簽名是一種使用私鑰加密資料的方式,然後使用公鑰解密資料。這種方式可以確保資料的完整性和真實性。

數字簽名的工作原理

數字簽名的工作原理是使用私鑰加密資料,然後使用公鑰解密資料。這種方式可以確保資料的完整性和真實性。

數字簽名的過程

  1. 首先,需要生成一對公鑰和私鑰。
  2. 對方使用私鑰加密資料。
  3. 加密後的資料傳送給您。
  4. 您使用公鑰解密資料。

RSA 數字簽名

RSA 數字簽名是一種使用 RSA 演算法的數字簽名方式。RSA 演算法是一種非對稱加密演算法,使用公鑰和私鑰的配對。

RSA 數字簽名的工作原理

RSA 數字簽名的工作原理是使用私鑰加密資料,然後使用公鑰解密資料。這種方式可以確保資料的完整性和真實性。

RSA 數字簽名的過程

  1. 首先,需要生成一對公鑰和私鑰。
  2. 對方使用私鑰加密資料。
  3. 加密後的資料傳送給您。
  4. 您使用公鑰解密資料。

Python 實作 RSA 數字簽名

以下是 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 = RSA.generate_private_key(
    public_exponent=65537,
    key_size=2048
)

signature = private_key.sign(
    message,
    padding_config,
    hashes.SHA256()
)

public_key = private_key.public_key()

try:
    public_key.verify(
        signature,
        message,
        padding_config,
        hashes.SHA256()
    )
    print("Signature is valid")
except:
    print("Signature is invalid")

這個範例使用了 cryptography 函式庫來實作 RSA 數字簽名。首先,生成了一對公鑰和私鑰,然後使用私鑰加密資料,最後使用公鑰解密資料。

RSA 數字簽名驗證

在接收到 Bob 的訊息和數字簽名後,Alice 需要驗證簽名以確保訊息的真實性和完整性。這個過程涉及三個步驟:對訊息進行雜湊、使用 Bob 的公鑰解密簽名、以及比較雜湊值。

步驟 1:對訊息進行雜湊

Alice 首先對接收到的訊息進行雜湊,以產生一個雜湊值。這個雜湊值將用於與從簽名中解密出的雜湊值進行比較。

步驟 2:使用 Bob 的公鑰解密簽名

Alice 使用 Bob 的公鑰來解密接收到的簽名。這個過程會產生一個解密出的雜湊值。

步驟 3:比較雜湊值

Alice 將她計算出的雜湊值與從簽名中解密出的雜湊值進行比較。如果兩個雜湊值匹配,則 Alice 可以確信訊息沒有被篡改,並且只能由 Bob 的私鑰所傳送。

實作細節

以下是 Alice 驗證簽名的實作細節:

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'])

    # 載入 Bob 的公鑰
    public_key = load_rsa_public_key()

    # 驗證簽名
    try:
        public_key.verify(
            signature,
            message,
            padding.PSS(
                mgf=padding.MGF1(hashes.SHA256()),
                salt_length=padding.PSS.MAX_LENGTH
            ),
            hashes.SHA256()
        )
        print("簽名驗證成功,訊息可以被信任。")
    except InvalidSignature:
        print("簽名驗證失敗,訊息可能被篡改。")

在這個實作中,Alice 使用 RSAPublicKey.verify 方法來驗證簽名。如果簽名驗證失敗,則會丟擲 InvalidSignature 例外。

數字簽名與非對稱加密

數字簽名是一種確保資料真實性和完整性的技術,使用非對稱加密演算法來實作。非對稱加密使用一對金鑰:公鑰和私鑰。公鑰用於加密資料,而私鑰用於解密資料。

RSA 數字簽名

RSA 是一種常用的非對稱加密演算法,使用大整數的因數分解問題來實作安全性。RSA 數字簽名使用私鑰對資料進行簽名,然後使用公鑰進行驗證。這個過程可以確保資料的真實性和完整性。

以下是 RSA 數字簽名的過程:

  1. 生成一對 RSA 金鑰:公鑰和私鑰。
  2. 對資料進行雜湊,生成一個雜湊值。
  3. 使用私鑰對雜湊值進行簽名,生成一個簽名值。
  4. 將簽名值和資料一起傳送給接收者。
  5. 接收者使用公鑰對簽名值進行驗證,確保資料的真實性和完整性。

橢圓曲線數字簽名

橢圓曲線數字簽名是一種比 RSA 數字簽名更快速和更安全的數字簽名方法。橢圓曲線數字簽名使用橢圓曲線的數學特性來實作安全性。

以下是橢圓曲線數字簽名的過程:

  1. 生成一對橢圓曲線金鑰:公鑰和私鑰。
  2. 對資料進行雜湊,生成一個雜湊值。
  3. 使用私鑰對雜湊值進行簽名,生成一個簽名值。
  4. 將簽名值和資料一起傳送給接收者。
  5. 接收者使用公鑰對簽名值進行驗證,確保資料的真實性和完整性。

Python 實作

以下是使用 Python 實作 RSA 和橢圓曲線數字簽名的例子:

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import rsa, ec

# 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,
    hashes.SHA256(),
    padding.PSS(
        mgf=padding.MGF1(hashes.SHA256()),
        salt_length=padding.PSS.MAX_LENGTH
    )
)

# 驗證簽名
try:
    public_key.verify(
        signature,
        message,
        hashes.SHA256(),
        padding.PSS(
            mgf=padding.MGF1(hashes.SHA256()),
            salt_length=padding.PSS.MAX_LENGTH
        )
    )
    print('簽名驗證成功')
except:
    print('簽名驗證失敗')

# 橢圓曲線數字簽名
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('簽名驗證失敗')

數字簽名驗證與大型訊息處理

在數字簽名的驗證過程中,若簽名驗證失敗,則會丟擲 InvalidSignature 例外。以下是使用 Python 進行橢圓曲線數字簽名驗證的示例:

from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec

# 取得公鑰
public_key = private_key.public_key()

try:
    # 驗證簽名
    public_key.verify(signature, message, ec.ECDSA(hashes.SHA256()))
except InvalidSignature:
    # 處理驗證失敗
    pass

在某些情況下,重新計算訊息的雜湊值可能是不理想的,尤其是在處理大型訊息或大量訊息時。為瞭解決這個問題,簽名方法(適用於 RSA 鑰匙和橢圓曲線鑰匙)提供了一個選項,允許呼叫者高效地計算訊息的雜湊值或重複使用先前計算的雜湊值。以下示例展示瞭如何使用 Prehashed 公用類別高效地簽署大型訊息:

import hashlib
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec, utils

# 大型訊息
large_msg = b'from Bob to Alice ...'

# 建立 SHA-256 雜湊物件
sha256 = hashlib.sha256()

# 更新雜湊物件
sha256.update(large_msg[:8])
sha256.update(large_msg[8:])

# 取得雜湊值
hash_value = sha256.digest()

# 生成私鑰
private_key = ec.generate_private_key(ec.SECP384R1(), default_backend())

# 簽署雜湊值
signature = private_key.sign(
    hash_value,
    ec.ECDSA(utils.Prehashed(hashes.SHA256()))
)

透過這些示例,您已經掌握了雜湊、加密和數字簽名的基礎知識。您已經學習了以下內容:

  • 雜湊確保資料完整性和資料驗證。
  • 加密確保機密性。
  • 數字簽名確保不可否認性。

本章節提供了許多低階別的示例,使用了加密套件,以達到教育目的。這些低階別的示例將為您在下一章節中學習高階別的解決方案——傳輸層安全性(TLS)做好準備。TLS是一種網路協定,它結合了您迄今為止所學的所有知識,包括雜湊、加密和數字簽名。

網路安全:抵禦中間人攻擊和使用Transport Layer Security

在網路安全中,中間人攻擊(Man-in-the-middle,MITM)是一種常見的威脅。這種攻擊方式是指攻擊者介於兩個溝通的實體之間,竊取或修改資料。為了防禦這種攻擊,Transport Layer Security(TLS)是一種被廣泛使用的安全協定。

什麼是TLS?

TLS是一種安全的網路協定,用於保護網路通訊的機密性和完整性。它是Secure Sockets Layer(SSL)的後繼者,SSL已經被認為是不安全的。TLS使用公鑰加密和數字簽名來確保資料的安全。

中間人攻擊

中間人攻擊可以分為兩種:被動攻擊和主動攻擊。被動攻擊是指攻擊者只竊取資料,而不修改它。主動攻擊是指攻擊者竊取和修改資料。

被動中間人攻擊

被動中間人攻擊是指攻擊者竊取資料,但不修改它。例如,攻擊者可以竊取使用者的密碼和個人資料。

主動中間人攻擊

主動中間人攻擊是指攻擊者竊取和修改資料。例如,攻擊者可以竊取使用者的密碼和個人資料,並修改它們。

如何防禦中間人攻擊

為了防禦中間人攻擊,需要使用TLS協定。TLS可以確保資料的機密性和完整性,防止攻擊者竊取或修改資料。

TLS的工作原理

TLS的工作原理是使用公鑰加密和數字簽名來確保資料的安全。當使用者存取一個網站時,網站會提供其公鑰給使用者。使用者可以使用這個公鑰來加密資料,並傳送給網站。網站可以使用其私鑰來解密資料。

Mermaid圖表
  flowchart TD
    A[使用者] --> B[網站]
    B --> C[提供公鑰]
    C --> D[使用者加密資料]
    D --> E[傳送加密資料]
    E --> F[網站解密資料]
    F --> G[網站處理資料]

圖表翻譯

此圖表展示了TLS的工作原理。使用者存取網站,網站提供其公鑰給使用者。使用者使用這個公鑰來加密資料,並傳送給網站。網站使用其私鑰來解密資料,並處理它們。這個過程可以確保資料的機密性和完整性,防止攻擊者竊取或修改資料。

網路安全:TLS握手過程解析

在網路安全中,TLS(Transport Layer Security)是一種廣泛使用的加密協定,用於保護網路通訊的安全性。當我們瀏覽網站或使用網路服務時,TLS協定會在客戶端和伺服器之間建立一個安全的連線,以防止第三方的竊聽和篡改。

中間人攻擊(Man-in-the-Middle Attack)

在網路通訊中,中間人攻擊是一種常見的安全威脅。攻擊者可以擷取客戶端和伺服器之間的通訊,甚至修改通訊內容。這種攻擊可以讓攻擊者冒充客戶端或伺服器,從而獲得敏感資訊或實施惡意行為。

TLS握手過程

TLS握手過程是TLS協定的一部分,用於在客戶端和伺服器之間建立一個安全的連線。這個過程包括以下三個主要步驟:

  1. 密碼套件協商(Cipher Suite Negotiation):客戶端和伺服器必須先同意使用哪種密碼套件。密碼套件是一組加密和雜湊演算法的集合。
  2. 金鑰交換(Key Exchange):客戶端和伺服器必須交換金鑰,以建立一個分享的金鑰。
  3. 伺服器認證(Server Authentication):伺服器必須向客戶端證明其身份。

密碼套件協商

在TLS 1.3中,定義了五種密碼套件:

  • TLS_AES_128_CCM_8_SHA256
  • TLS_AES_128_CCM_SHA256
  • TLS_AES_128_GCM_SHA256

客戶端和伺服器必須先同意使用哪種密碼套件,然後才能進行金鑰交換和伺服器認證。

內容解密:

在上述過程中,客戶端和伺服器使用TLS協定建立了一個安全的連線。這個過程包括密碼套件協商、金鑰交換和伺服器認證。透過這些步驟,TLS協定可以防止中間人攻擊和其他安全威脅,保護網路通訊的安全性。

圖表翻譯:

以下是TLS握手過程的Mermaid圖表:

  sequenceDiagram
    participant 客戶端
    participant 伺服器
    Note over 客戶端,伺服器: TLS握手過程
    客戶端->>伺服器: 密碼套件協商
    伺服器->>客戶端: 密碼套件協商
    客戶端->>伺服器: 金鑰交換
    伺服器->>客戶端: 金鑰交換
    伺服器->>客戶端: 伺服器認證
    Note over 客戶端,伺服器: 安全連線建立

這個圖表展示了TLS握手過程的三個主要步驟:密碼套件協商、金鑰交換和伺服器認證。透過這些步驟,TLS協定可以建立一個安全的連線,保護網路通訊的安全性。

TLS 1.3 金鑰交換機制

TLS 1.3 中的金鑰交換機制是一個安全且高效的過程,允許客戶端和伺服器之間建立分享的金鑰。這個過程使用 Diffie-Hellman 方法,該方法允許兩方在不安全的通道中安全地建立分享金鑰。

Diffie-Hellman 方法

Diffie-Hellman 方法是一種公開金鑰交換演算法,允許兩方在不安全的通道中安全地建立分享金鑰。這個方法涉及以下步驟:

  1. 雙方公開同意兩個引數:p 和 g。
  2. 雙方各自生成一個私有金鑰:a 和 b。
  3. 雙方各自從引數和私有金鑰中匯出一個公開金鑰:A 和 B。
  4. 雙方公開交換公開金鑰。
  5. 雙方各自使用對方的公開金鑰和自己的私有金鑰計算出一個分享的金鑰:K。

金鑰交換過程

在 TLS 1.3 中,客戶端和伺服器使用 Diffie-Hellman 方法進行金鑰交換。客戶端和伺服器各自生成一個私有金鑰和公開金鑰,然後公開交換公開金鑰。客戶端和伺服器各自使用對方的公開金鑰和自己的私有金鑰計算出一個分享的金鑰。

公開金鑰加密

雖然公開金鑰加密不是 TLS 1.3 中金鑰交換過程的一部分,但它仍然是一種重要的加密技術。公開金鑰加密允許一方使用另一方的公開金鑰加密資料,而只有對方的私有金鑰才能解密資料。然而,在 TLS 1.3 中,公開金鑰加密不是用於金鑰交換,而是用於其他目的,例如身份驗證。

安全性

TLS 1.3 中的金鑰交換過程是安全的,因為它使用 Diffie-Hellman 方法,這是一種安全且高效的公開金鑰交換演算法。即使攻擊者可以截獲公開金鑰和引數,也無法計算出分享的金鑰。這是因為 Diffie-Hellman 方法的安全性根據數論難題,例如大整數的因數分解。

TLS 1.3 中的金鑰交換與驗證

TLS 1.3 解決了傳統金鑰交換過程中的效率問題。Diffie-Hellman(DH)金鑰交換是一種更高效的解決方案,使用模數算術來避免公鑰加密的計算負擔。這種方法不需要直接分發金鑰,而是由雙方獨立建立。

伺服器驗證

在 TLS 中,金鑰交換和套件協商是保密性的前提。但是,如果不能驗證對方的身份,保密性就沒有意義。TLS 同時提供了身份驗證的功能,通常是伺服器被使用者端驗證。伺服器的身份驗證是透過憑證來完成的,憑證包含了伺服器的公鑰,並由憑證授權機構(CA)簽發。

公鑰憑證

公鑰憑證類似於駕駛執照,都是用來證明身份的。憑證包含了公鑰所有者的資訊和公鑰本身,並由 CA 簽發。使用者端(如瀏覽器)會檢查憑證的有效性,以確保伺服器的身份。

憑證結構

憑證的結構由 X.509 標準定義,包括了一系列的欄位,如:

  • 主體(Subject):憑證所有者的身份資訊。
  • 發行者(Issuer):簽發憑證的 CA。
  • 公鑰(Subject’s public key):憑證所有者的公鑰。
  • 憑證有效期(Certificate validity period):憑證的有效時間。
  • CA 簽名(Certificate authority signature):CA 對憑證的簽名。

這些欄位對於確保 TLS 連線的安全性至關重要。透過檢查憑證的有效性,使用者端可以確保自己正在與預期的伺服器進行通訊。

實踐中的憑證

可以使用工具如 OpenSSL 來檢視憑證的詳細資訊。例如,下面的命令可以顯示 Wikipedia 的憑證詳情:

$ openssl x509 -in wikipedia.crt -text -noout | less

這樣可以看到憑證中包含的所有重要欄位,包括主體、發行者、公鑰等。

網頁瀏覽器的憑證驗證

當網頁瀏覽器連線到一個網站時,會進行TLS(Transport Layer Security)握手,以確保連線的安全性。在這個過程中,瀏覽器會要求網站提供其公鑰憑證(public-key certificate),以驗證網站的身份。

公鑰憑證的結構

公鑰憑證包含了以下幾個重要的欄位:

  • 主體(Subject):指定憑證的所有者,例如網站的網域名稱。
  • 發行者(Issuer):指定憑證的發行者,例如Let’s Encrypt。
  • 有效期限(Validity):指定憑證的有效期限。
  • 公鑰(Public Key):指定憑證的公鑰,例如256位元的橢圓曲線公鑰。
  • 數位簽章(Digital Signature):指定憑證的數位簽章,例如由Let’s Encrypt簽署的數位簽章。

瀏覽器的憑證驗證流程

當瀏覽器收到網站的公鑰憑證時,會進行以下的驗證流程:

  1. 主體驗證:瀏覽器會驗證憑證的主體是否與網站的網域名稱相符。如果不相符,瀏覽器會拒絕憑證。
  2. 發行者驗證:瀏覽器會驗證憑證的發行者是否為合法的憑證授權機構(CA)。
  3. 有效期限驗證:瀏覽器會驗證憑證的有效期限是否在目前的時間範圍內。如果不在範圍內,瀏覽器會拒絕憑證。
  4. 公鑰驗證:瀏覽器會驗證憑證的公鑰是否有效。
  5. 數位簽章驗證:瀏覽器會驗證憑證的數位簽章是否由合法的CA簽署。

如果憑證透過以上的驗證流程,瀏覽器會接受憑證並建立安全的連線。如果憑證不透過驗證,瀏覽器會顯示錯誤訊息並拒絕連線。

內容解密:

上述的憑證驗證流程是瀏覽器確保網站身份和安全性的重要機制。憑證的主體、發行者、有效期限、公鑰和數位簽章都是憑證的重要組成部分,瀏覽器會仔細驗證每一個部分以確保憑證的有效性。

圖表翻譯:

  graph LR
    A[瀏覽器] -->|要求憑證|> B[網站]
    B -->|傳送憑證|> A
    A -->|主體驗證|> C[憑證主體]
    A -->|發行者驗證|> D[憑證發行者]
    A -->|有效期限驗證|> E[憑證有效期限]
    A -->|公鑰驗證|> F[憑證公鑰]
    A -->|數位簽章驗證|> G[憑證數位簽章]
    C -->|驗證結果|> H[驗證透過]
    D -->|驗證結果|> H
    E -->|驗證結果|> H
    F -->|驗證結果|> H
    G -->|驗證結果|> H
    H -->|建立安全連線|> B

上述的Mermaid圖表展示了瀏覽器的憑證驗證流程,包括主體驗證、發行者驗證、有效期限驗證、公鑰驗證和數位簽章驗證。圖表顯示了每個驗證步驟的結果,如果所有驗證透過,瀏覽器會建立安全的連線。

使用 Django 建立安全的 Web 應用程式

在本節中,您將學習如何使用 Django 建立、設定和執行一個 Web 應用程式伺服器。Django 是一個 Python Web 應用程式框架,提供了許多功能和工具來幫助您建立安全和可擴充套件的 Web 應用程式。

安裝 Django

首先,您需要在您的虛擬環境中安裝 Django。您可以使用 pipenv 安裝 Django:

$ pipenv install django

安裝完成後,django-admin 指令碼將被新增到您的 shell 路徑中。這個指令碼是一個管理工具,將幫助您建立 Django 專案的骨架。

建立 Django 專案

使用以下命令建立一個名為 “alice” 的 Django 專案:

$ django-admin startproject alice

這個命令將建立一個名為 “alice” 的新目錄,該目錄包含了 Django 專案的骨架。其中包括一個名為 manage.py 的指令碼,這個指令碼是一個專案特定的管理工具。稍後您將使用它來啟動您的 Django 應用程式。

Django 專案結構

在專案根目錄中,您將找到一個名為 alice 的子目錄,該子目錄具有相同的名稱。這個子目錄被稱為 Django 根目錄。Django 根目錄包含了許多重要的模組,包括 settings 模組。這個模組是專案組態值的中央位置,您將在本章中多次看到它。

非對稱加密和數字簽名技術已成為現代網路安全基本。深入剖析其核心原理,可以發現,從底層的金鑰生成、加解密過程,到上層的TLS握手、憑證驗證,每個環節都環環相扣,共同構成了安全可靠的網路通訊環境。技術限制深析顯示,儘管非對稱加密的安全性較高,但其計算成本相對較高,尤其在處理大型訊息時,效能瓶頸明顯。為此,引入雜湊演算法和高效的金鑰交換機制,例如 Diffie-Hellman 方法,以及預先計算雜湊值等策略,能有效提升系統效能。展望未來,隨著量子計算技術的發展,傳統非對稱加密演算法的安全性將面臨挑戰,探索抗量子密碼學演算法將成為重要的技術趨勢。玄貓認為,開發者應持續關注密碼學領域的最新進展,並將其整合至Web應用程式開發的最佳實務中,例如使用Django等框架構建安全的Web伺服器,才能確保網路安全防護的持續有效性。