在這裏插入圖片描述

非對稱加密是現代密碼學的基石,也是互聯網安全的支柱。我將從基礎概念到實際應用,為您詳細解析這一重要技術。

核心概念:什麼是非對稱加密?

非對稱加密,又稱公鑰密碼學,它使用一對數學上相關的密鑰:

  • 公鑰:可以公開給任何人,用於加密數據或驗證簽名
  • 私鑰:必須嚴格保密,用於解密數據或創建簽名

與對稱加密的對比

特性 對稱加密 非對稱加密
密鑰數量 1個共享密鑰 2個密鑰(公鑰+私鑰)
密鑰分發 困難且不安全 公鑰可自由分發
加密速度 慢(比對稱加密慢100-1000倍)
主要用途 批量數據加密 密鑰交換、數字簽名、身份驗證
常見算法 AES, DES, 3DES RSA, ECC, DSA

技術原理深度解析

1. 數學基礎:單向陷阱門函數

非對稱加密基於數學上的"單向函數"——正向計算容易,反向推導極其困難。

# 概念性示例:理解單向函數
def one_way_function(x):
    return (x * x) % n  # 容易計算

def reverse_one_way(y):
    # 從y找回x在計算上極其困難
    # 這就是非對稱加密的數學基礎
    pass

2. RSA 算法詳解(最經典的非對稱算法)

密鑰生成過程

import random
import math

def generate_rsa_keys(bit_length=2048):
    # 1. 選擇兩個大質數 p 和 q
    p = generate_large_prime(bit_length//2)
    q = generate_large_prime(bit_length//2)
    
    # 2. 計算模數 n
    n = p * q
    phi = (p-1) * (q-1)  # 歐拉函數
    
    # 3. 選擇公鑰指數 e(通常為 65537)
    e = 65537
    while math.gcd(e, phi) != 1:
        e += 2
    
    # 4. 計算私鑰指數 d(e 的模逆元)
    d = modular_inverse(e, phi)
    
    # 返回密鑰對
    public_key = (e, n)   # 公鑰:可以公開
    private_key = (d, n)  # 私鑰:必須保密
    return public_key, private_key

# 實際應用中我們使用現成的庫,這裏只是演示原理

加密解密過程

def rsa_encrypt(plaintext, public_key):
    """使用公鑰加密"""
    e, n = public_key
    # 將明文轉換為數字
    m = bytes_to_long(plaintext)
    # 加密:c = m^e mod n
    c = pow(m, e, n)
    return long_to_bytes(c)

def rsa_decrypt(ciphertext, private_key):
    """使用私鑰解密"""
    d, n = private_key
    # 將密文轉換為數字
    c = bytes_to_long(ciphertext)
    # 解密:m = c^d mod n
    m = pow(c, d, n)
    return long_to_bytes(m)

3. 橢圓曲線密碼學(ECC)

ECC 提供相同安全強度下更短的密鑰長度:

安全級別 RSA 密鑰長度 ECC 密鑰長度
80-bit 1024 bits 160 bits
128-bit 3072 bits 256 bits
256-bit 15360 bits 512 bits
# ECC 的概念性示例(實際實現複雜得多)
class EllipticCurve:
    def __init__(self, a, b, p):
        self.a = a
        self.b = b
        self.p = p  # 質數域
    
    def point_addition(self, P, Q):
        # 橢圓曲線上的點加法
        if P == "infinity":
            return Q
        if Q == "infinity":
            return P
        
        x1, y1 = P
        x2, y2 = Q
        
        if x1 == x2 and y1 == y2:
            # 點加倍
            s = (3 * x1 * x1 + self.a) * modular_inverse(2 * y1, self.p) % self.p
        else:
            # 點相加
            s = (y2 - y1) * modular_inverse(x2 - x1, self.p) % self.p
        
        x3 = (s * s - x1 - x2) % self.p
        y3 = (s * (x1 - x3) - y1) % self.p
        
        return (x3, y3)
    
    def scalar_multiply(self, k, P):
        # 標量乘法:k * P
        result = "infinity"
        addend = P
        
        while k:
            if k & 1:
                result = self.point_addition(result, addend)
            addend = self.point_addition(addend, addend)
            k >>= 1
        
        return result

# ECC 密鑰生成(簡化概念)
def generate_ecc_keypair(curve, base_point):
    private_key = random.randint(1, curve.p-1)  # 私鑰
    public_key = curve.scalar_multiply(private_key, base_point)  # 公鑰
    return private_key, public_key

主要應用場景

1. 安全通信(TLS/SSL)

# TLS 握手過程中的非對稱加密使用
class TLSSession:
    def handshake(self):
        # 1. 客户端生成臨時密鑰對
        client_ephemeral_private, client_ephemeral_public = generate_ecc_keypair()
        
        # 2. 客户端用服務器公鑰加密臨時公鑰
        encrypted_key = rsa_encrypt(client_ephemeral_public, server_public_key)
        
        # 3. 服務器用私鑰解密獲取客户端臨時公鑰
        client_ephemeral_public = rsa_decrypt(encrypted_key, server_private_key)
        
        # 4. 雙方使用ECDHE計算共享密鑰
        shared_secret = ecdh_compute(client_ephemeral_private, server_ephemeral_public)
        
        # 5. 基於共享密鑰生成對稱加密密鑰
        symmetric_key = derive_symmetric_key(shared_secret)

2. 數字簽名

def create_digital_signature(message, private_key):
    """創建數字簽名"""
    # 1. 計算消息的哈希
    message_hash = sha256(message)
    
    # 2. 使用私鑰"加密"哈希(實際是簽名操作)
    signature = rsa_sign(message_hash, private_key)
    
    return signature

def verify_digital_signature(message, signature, public_key):
    """驗證數字簽名"""
    # 1. 計算消息的哈希
    message_hash = sha256(message)
    
    # 2. 使用公鑰"解密"簽名(實際是驗證操作)
    expected_hash = rsa_verify(signature, public_key)
    
    # 3. 比較哈希值
    return message_hash == expected_hash

# 實際使用示例
message = "重要的合同內容"
signature = create_digital_signature(message, company_private_key)

# 驗證簽名(任何人都可以用公鑰驗證)
is_valid = verify_digital_signature(message, signature, company_public_key)
print(f"簽名有效: {is_valid}")

3. 安全電子郵件(PGP/GPG)

class SecureEmail:
    def send_encrypted_email(self, recipient_public_key, message):
        # 1. 生成隨機的對稱會話密鑰
        session_key = generate_random_aes_key()
        
        # 2. 使用會話密鑰加密郵件內容
        encrypted_message = aes_encrypt(session_key, message)
        
        # 3. 使用收件人公鑰加密會話密鑰
        encrypted_session_key = rsa_encrypt(session_key, recipient_public_key)
        
        # 4. 發送加密的會話密鑰和加密的消息
        return {
            'encrypted_session_key': encrypted_session_key,
            'encrypted_message': encrypted_message
        }
    
    def receive_encrypted_email(self, encrypted_package, recipient_private_key):
        # 1. 使用私鑰解密會話密鑰
        session_key = rsa_decrypt(encrypted_package['encrypted_session_key'], 
                                 recipient_private_key)
        
        # 2. 使用會話密鑰解密郵件內容
        message = aes_decrypt(session_key, encrypted_package['encrypted_message'])
        
        return message

4. 區塊鏈

class CryptocurrencyTransaction:
    def create_transaction(self, sender_private_key, recipient_public_key, amount):
        # 創建交易數據
        transaction_data = {
            'from': get_address_from_public_key(sender_public_key),
            'to': get_address_from_public_key(recipient_public_key),
            'amount': amount,
            'nonce': get_next_nonce(),
            'timestamp': time.now()
        }
        
        # 對交易進行簽名
        transaction_hash = sha256(json.dumps(transaction_data))
        signature = ecdsa_sign(transaction_hash, sender_private_key)
        
        # 廣播簽名後的交易
        broadcast_transaction(transaction_data, signature)
    
    def verify_transaction(self, transaction_data, signature, sender_public_key):
        # 驗證交易簽名
        transaction_hash = sha256(json.dumps(transaction_data))
        return ecdsa_verify(transaction_hash, signature, sender_public_key)

實際代碼示例:完整的 RSA 實現

import random
import math
from Crypto.Util.number import getPrime, inverse, bytes_to_long, long_to_bytes
import hashlib

class SimpleRSA:
    def __init__(self, key_size=2048):
        self.key_size = key_size
        self.public_key = None
        self.private_key = None
    
    def generate_keys(self):
        # 生成兩個大質數
        p = getPrime(self.key_size // 2)
        q = getPrime(self.key_size // 2)
        
        n = p * q
        phi = (p - 1) * (q - 1)
        
        # 選擇公鑰指數
        e = 65537
        while math.gcd(e, phi) != 1:
            e += 2
        
        # 計算私鑰指數
        d = inverse(e, phi)
        
        self.public_key = (e, n)
        self.private_key = (d, n)
        
        return self.public_key, self.private_key
    
    def encrypt(self, message):
        if not self.public_key:
            raise ValueError("公鑰未生成")
        
        e, n = self.public_key
        # 將消息轉換為整數
        m = bytes_to_long(message.encode('utf-8'))
        
        # 加密:c = m^e mod n
        if m >= n:
            raise ValueError("消息太長,需要分段加密")
        
        c = pow(m, e, n)
        return c
    
    def decrypt(self, ciphertext):
        if not self.private_key:
            raise ValueError("私鑰未生成")
        
        d, n = self.private_key
        
        # 解密:m = c^d mod n
        m = pow(ciphertext, d, n)
        
        # 將整數轉換回消息
        message = long_to_bytes(m).decode('utf-8')
        return message
    
    def sign(self, message):
        """使用私鑰對消息簽名"""
        if not self.private_key:
            raise ValueError("私鑰未生成")
        
        d, n = self.private_key
        
        # 計算消息哈希
        message_hash = hashlib.sha256(message.encode('utf-8')).digest()
        hash_int = bytes_to_long(message_hash)
        
        # 使用私鑰"加密"哈希(簽名)
        signature = pow(hash_int, d, n)
        return signature
    
    def verify(self, message, signature):
        """使用公鑰驗證簽名"""
        if not self.public_key:
            raise ValueError("公鑰未生成")
        
        e, n = self.public_key
        
        # 使用公鑰"解密"簽名
        decrypted_hash = pow(signature, e, n)
        
        # 計算消息的實際哈希
        actual_hash = hashlib.sha256(message.encode('utf-8')).digest()
        actual_hash_int = bytes_to_long(actual_hash)
        
        # 比較哈希值
        return decrypted_hash == actual_hash_int

# 使用示例
if __name__ == "__main__":
    rsa = SimpleRSA(1024)  # 使用1024位密鑰(實際應用應用2048位以上)
    public_key, private_key = rsa.generate_keys()
    
    # 加密解密演示
    original_message = "這是秘密消息!"
    print(f"原始消息: {original_message}")
    
    ciphertext = rsa.encrypt(original_message)
    print(f"加密後的密文: {ciphertext}")
    
    decrypted_message = rsa.decrypt(ciphertext)
    print(f"解密後的消息: {decrypted_message}")
    
    # 數字簽名演示
    document = "重要合同內容"
    signature = rsa.sign(document)
    print(f"文檔簽名: {signature}")
    
    is_valid = rsa.verify(document, signature)
    print(f"簽名驗證結果: {is_valid}")
    
    # 測試簽名篡改檢測
    tampered_document = "修改後的合同內容"
    is_tampered_valid = rsa.verify(tampered_document, signature)
    print(f"篡改後驗證結果: {is_tampered_valid}")

安全考慮與最佳實踐

1. 密鑰長度建議

算法 當前安全的最小長度 推薦長度 長期安全長度
RSA 2048 bits 3072 bits 15360 bits
ECC 224 bits 256 bits 512 bits

2. 常見attack與防護

# 防護措施示例
class SecureRSAPractice:
    def __init__(self):
        self.encryption_count = 0
        self.max_encryptions = 100000  # 限制加密次數
    
    def secure_encrypt(self, message, public_key):
        # 1. 使用OAEP填充而不是PKCS#1 v1.5
        padded_message = self.oaep_padding(message)
        
        # 2. 限制加密次數防止時序attack
        self.encryption_count += 1
        if self.encryption_count > self.max_encryptions:
            self.regenerate_keys()
        
        # 3. 使用恆定時間算法
        return self.constant_time_encrypt(padded_message, public_key)
    
    def oaep_padding(self, message):
        # 最優非對稱加密填充
        # 增加隨機性,防止選擇密文attack
        pass
    
    def constant_time_encrypt(self, message, public_key):
        # 恆定時間實現,防止時序attack
        pass

3. 實際部署建議

  1. 使用現成的密碼學庫:不要自己實現加密算法
  2. 定期更換密鑰:特別是用於簽名的密鑰
  3. 安全的密鑰存儲:使用HSM、TEE等安全環境
  4. 證書管理:使用PKI體系管理公鑰信任

總結

非對稱加密通過巧妙的數學原理解決了密鑰分發問題,實現了:

  • 安全通信 without 預先共享密鑰
  • 數字簽名 for 身份驗證和完整性保護
  • 密鑰協商 for 建立安全會話
  • 身份驗證 through 公鑰基礎設施

雖然計算開銷較大,但通過與對稱加密結合(如TLS),非對稱加密成為了現代數字安全的基石,支撐着從網上銀行到區塊鏈的各類關鍵應用。


結束語 Flutter是一個由Google開發的開源UI工具包,它可以讓您在不同平台上創建高質量、美觀的應用程序,而無需編寫大量平台特定的代碼。我將學習和深入研究Flutter的方方面面。從基礎知識到高級技巧,從UI設計到性能優化,歡飲關注一起討論學習,共同進入Flutter的精彩世界!