非對稱加密是現代密碼學的基石,也是互聯網安全的支柱。我將從基礎概念到實際應用,為您詳細解析這一重要技術。
核心概念:什麼是非對稱加密?
非對稱加密,又稱公鑰密碼學,它使用一對數學上相關的密鑰:
- 公鑰:可以公開給任何人,用於加密數據或驗證簽名
- 私鑰:必須嚴格保密,用於解密數據或創建簽名
與對稱加密的對比
| 特性 | 對稱加密 | 非對稱加密 |
|---|---|---|
| 密鑰數量 | 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. 實際部署建議
- 使用現成的密碼學庫:不要自己實現加密算法
- 定期更換密鑰:特別是用於簽名的密鑰
- 安全的密鑰存儲:使用HSM、TEE等安全環境
- 證書管理:使用PKI體系管理公鑰信任
總結
非對稱加密通過巧妙的數學原理解決了密鑰分發問題,實現了:
- ✅ 安全通信 without 預先共享密鑰
- ✅ 數字簽名 for 身份驗證和完整性保護
- ✅ 密鑰協商 for 建立安全會話
- ✅ 身份驗證 through 公鑰基礎設施
雖然計算開銷較大,但通過與對稱加密結合(如TLS),非對稱加密成為了現代數字安全的基石,支撐着從網上銀行到區塊鏈的各類關鍵應用。
結束語 Flutter是一個由Google開發的開源UI工具包,它可以讓您在不同平台上創建高質量、美觀的應用程序,而無需編寫大量平台特定的代碼。我將學習和深入研究Flutter的方方面面。從基礎知識到高級技巧,從UI設計到性能優化,歡飲關注一起討論學習,共同進入Flutter的精彩世界!