加密這個主題很容易讓工程師陷入「我不是密碼學家,不需要懂」的迴避,然後在實作裡犯下「用 MD5 存密碼」或「HTTPS 下還在 base64 encode 敏感資料當加密」這類錯誤。

不需要懂數學,但要知道四種基本機制各解什麼問題。


對稱加密(Symmetric Encryption)

同一把 key,加密和解密都用它。

明文 + Key → [AES-256] → 密文
密文 + Key → [AES-256] → 明文

優點:速度快,適合加密大量資料。
缺點:key 要怎麼安全地傳給對方?在傳輸過程中如果 key 被截走就全完了。

常見算法:AES-128 / AES-256(現代標準),DES / 3DES(過時,不用)。

用途:加密靜態資料(database encryption、disk encryption)、TLS 建立連線後的資料傳輸。


非對稱加密(Asymmetric Encryption)

公鑰加密,私鑰解密(或反向用來 signing)。

明文 + 公鑰 → [RSA] → 密文    (任何人都能加密)
密文 + 私鑰 → [RSA] → 明文    (只有私鑰持有者能解密)

優點:解決金鑰分發問題——公鑰可以公開,不怕被截。
缺點:慢,不適合加密大量資料。

常見算法:RSA-2048 / RSA-4096、ECC(Elliptic Curve Cryptography,同等安全性但 key 更短,適合資源受限環境)。

用途:TLS 握手時交換 session key、SSH key authentication、憑證體系(PKI)。

TLS 的組合:TLS 不是純粹用非對稱加密傳資料(太慢),而是用非對稱加密安全地交換一個對稱加密的 session key,之後資料傳輸用對稱加密——兩種的優點都用到。


Hash(雜湊)

單向函式,輸入任意長度資料,輸出固定長度的摘要。無法從摘要反推輸入。

"password123" → [SHA-256] → "ef92b778..."
"password124" → [SHA-256] → "c15f3b12..."   (完全不同)

特性:確定性(同樣輸入永遠同樣輸出)、雪崩效應(輸入微小改動,輸出完全不同)、不可逆。

常見算法:

  • SHA-256 / SHA-3:現代標準,完整性驗證用
  • bcrypt / Argon2 / scrypt:密碼 hash 專用,內建 salt + 計算成本(慢是特性,防暴力破解)
  • MD5 / SHA-1:已被破解(碰撞攻擊),只有在非安全場景(checksum)才勉強用

密碼儲存的正確做法

# 錯誤:MD5 或 SHA-256 直接 hash
hash = md5(password)          # 彩虹表直接破
 
# 正確:bcrypt 或 Argon2(有 salt、有 cost factor)
hash = bcrypt.hashpw(password, bcrypt.gensalt(rounds=12))

用途:密碼存儲、資料完整性驗證(Git commit hash、下載檔案 checksum)、blockchain。


Digital Signature(數位簽名)

私鑰簽名,公鑰驗證——證明「這個訊息確實來自私鑰持有者,且未被篡改」。

訊息 + 私鑰 → [Sign] → 簽名
訊息 + 簽名 + 公鑰 → [Verify] → 有效 / 無效

實際上簽的是訊息的 hash,不是訊息本身(訊息可能很大):

hash = SHA-256(訊息)
簽名 = RSA_encrypt(hash, 私鑰)

用途

  • TLS 憑證:CA 用私鑰簽發憑證,瀏覽器用 CA 的公鑰驗證
  • JWT:server 用私鑰簽發 token,API 服務用公鑰驗 token
  • Git commit signing:GPG 簽 commit,驗作者身份
  • Docker image signing:Cosign / Notary 確認 image 來自可信來源

HMAC:對稱版的 Signing

Hash-based Message Authentication Code。用共享 secret key 對訊息做 hash——驗完整性 + 驗來源,但雙方都持有同一把 key。

HMAC = Hash(key + 訊息)

比非對稱 signing 快,但無法做到「non-repudiation」(雙方都有 key,都能偽造)。

用途:webhook signature(GitHub、Stripe 都用 HMAC-SHA256)、API request 簽名(AWS Signature V4)、JWT HS256 variant(單服務自用,不跨服務驗)。


選型速查

需求用什麼
加密大量資料(靜態 / 傳輸中)AES-256
安全分發 session keyRSA / ECDH
存用戶密碼bcrypt / Argon2
驗資料完整性(非密碼)SHA-256
webhook / API 簽名(雙方共享 secret)HMAC-SHA256
JWT(跨服務驗身份)RS256(非對稱)優於 HS256(對稱)
憑證 / 身份驗證X.509 + RSA/ECC

不要自己實作加密算法。 使用現有的加密庫(OpenSSL、libsodium、Python cryptography、Node.js crypto),即使你懂數學,密碼學實作有太多微小的 timing attack / padding oracle attack 陷阱。