加密與編碼完全指南

編碼 vs 加密 vs 雜湊:根本差異

初學者最常混淆的就是「編碼」、「加密」和「雜湊」三者的差異。它們的根本區別在於可逆性目的

技術 可逆性 需要金鑰 主要目的
編碼(Encoding) 完全可逆 不需要 資料格式轉換
加密(Encryption) 用金鑰可逆 需要 保護機密資料
雜湊(Hashing) 不可逆 不需要 驗證完整性

重要原則:編碼不是加密!Base64 編碼後的資料任何人都可以解碼,它沒有安全性可言。

編碼(Encoding)

Base64 編碼

Base64 將二進位資料轉換為 64 個可列印字元(A-Z、a-z、0-9、+、/),常用於在文字環境中傳輸二進位資料。

工作原理:每 3 個位元組(24 bits)分成 4 組 6 bits,每組對應一個 Base64 字元。

原始:Man
二進位:01001101 01100001 01101110
6-bit 分組:010011 010110 000101 101110
Base64:T     W     F     u
結果:TWFu

常見用途: - Email 附件(MIME) - JWT Token 的 header 和 payload - 在 HTML/CSS 中嵌入小圖片(data URI) - API 傳輸二進位資料

URL 編碼

URL 編碼(Percent Encoding)將 URL 中的特殊字元轉換為 %XX 格式。例如空格變成 %20,中文「你好」變成 %E4%BD%A0%E5%A5%BD

必須編碼的字元:空格、中文、&=?#% 等在 URL 中有特殊含義的字元。

HTML 實體編碼

防止 XSS 攻擊的基本手段。將 HTML 特殊字元轉換為實體:

< → &lt;
> → &gt;
& → &amp;
" → &quot;
' → &#x27;

雜湊(Hashing)

雜湊的特性

雜湊函式將任意長度的資料映射為固定長度的摘要,具備以下特性:

  1. 單向性:無法從雜湊值反推原始資料
  2. 確定性:相同輸入永遠產生相同輸出
  3. 雪崩效應:輸入改變一個 bit,輸出完全不同
  4. 抗碰撞:幾乎不可能找到兩個不同的輸入產生相同的雜湊

MD5 — 已不安全

MD5 產生 128-bit(32 字元 hex)的雜湊值。由於已發現碰撞攻擊方法,不應再用於安全用途

MD5("hello") = 5d41402abc4b2a76b9719d911017c592

仍可使用的場景:檔案完整性快速檢查(非安全用途)、資料庫分片

SHA-256 — 目前的標準

SHA-256 產生 256-bit(64 字元 hex)的雜湊值,是目前最廣泛使用的安全雜湊演算法。

SHA-256("hello") = 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824

應用場景: - 數位簽章 - 區塊鏈(Bitcoin 使用雙重 SHA-256) - 檔案完整性驗證 - TLS/SSL 憑證

密碼存儲 — bcrypt/scrypt/Argon2

絕對不要直接用 MD5 或 SHA-256 存儲密碼!應使用專門的密碼雜湊演算法:

演算法 推薦程度 特點
Argon2id 最推薦 抗 GPU/ASIC 暴力破解
bcrypt 推薦 久經考驗,廣泛支持
scrypt 推薦 高記憶體需求,抗 ASIC
PBKDF2 可接受 NIST 認可,但不如上述三者

這些演算法的特點是故意很慢(可調整的工作因子),使暴力破解在計算上不可行。

# Python bcrypt 範例
import bcrypt
password = "my_secure_password".encode()
salt = bcrypt.gensalt(rounds=12)
hashed = bcrypt.hashpw(password, salt)

# 驗證密碼
bcrypt.checkpw(password, hashed)  # True

對稱加密

AES(Advanced Encryption Standard)

AES 是目前最廣泛使用的對稱加密演算法,使用相同的金鑰進行加密和解密。

金鑰長度: - AES-128:128-bit 金鑰,適合一般用途 - AES-256:256-bit 金鑰,軍事級安全性

加密模式: - CBC:每個區塊依賴前一個區塊,需要 IV(初始向量) - GCM:帶認證的加密,同時提供機密性和完整性(推薦) - CTR:計數器模式,可平行處理

# Python AES-GCM 範例
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import os

key = AESGCM.generate_key(bit_length=256)
nonce = os.urandom(12)
aesgcm = AESGCM(key)
ciphertext = aesgcm.encrypt(nonce, b"secret data", None)
plaintext = aesgcm.decrypt(nonce, ciphertext, None)

常見錯誤

  1. ECB 模式:不要使用!相同的明文區塊會產生相同的密文,洩漏資料模式
  2. 硬編碼金鑰:金鑰絕對不能寫在程式碼中
  3. 重複使用 IV/Nonce:每次加密必須使用新的隨機 IV

非對稱加密

RSA

RSA 使用一對金鑰:公鑰加密、私鑰解密(或反過來用於簽章)。

金鑰長度建議: - 最低 2048-bit(2030 年前安全) - 推薦 4096-bit(長期安全)

應用場景: - HTTPS/TLS 握手(交換對稱金鑰) - 數位簽章(驗證身份和資料完整性) - SSH 金鑰認證 - 電子郵件加密(PGP/GPG)

ECC(橢圓曲線加密)

ECC 以更短的金鑰提供同等安全性:256-bit ECC ≈ 3072-bit RSA。

優點:金鑰更短、計算更快、頻寬更省 應用:TLS 1.3 預設使用 ECDHE、Bitcoin 使用 secp256k1

HTTPS 與 TLS

TLS 1.3 握手流程

  1. Client 發送支持的加密套件列表
  2. Server 選擇加密套件,發送公鑰
  3. 雙方用 ECDHE 產生共享秘密
  4. 派生對稱加密金鑰(AES-256-GCM)
  5. 後續通訊使用對稱加密

TLS 1.3 只需 1-RTT 握手(TLS 1.2 需要 2-RTT),效能大幅提升。

為什麼 HTTPS 同時使用對稱和非對稱加密?

非對稱加密(RSA/ECC)用於安全地交換金鑰,因為它很慢但不需要預先共享秘密。 對稱加密(AES)用於實際的資料傳輸,因為它快數千倍。

這就是所謂的混合加密,結合了兩者的優點。

實戰安全清單

密碼存儲

  • 使用 Argon2id 或 bcrypt,工作因子足夠高
  • 永遠加鹽(salt),每個密碼用不同的隨機鹽
  • 絕對不要用 MD5/SHA-256 直接存密碼

API 金鑰與 Token

  • 使用 CSPRNG(密碼學安全隨機數產生器)生成
  • 存儲在環境變數或秘密管理服務中
  • 定期輪換,設定過期時間

資料傳輸

  • 永遠使用 HTTPS(TLS 1.2+)
  • 啟用 HSTS 標頭
  • 使用 Certificate Pinning(高安全性場景)

資料存儲

  • 敏感欄位使用 AES-256-GCM 加密
  • 金鑰管理使用 KMS(AWS KMS、GCP KMS 等)
  • 備份也要加密

常見問題 FAQ

Q:Base64 是加密嗎?

A:不是。Base64 只是編碼,任何人都可以解碼。它沒有任何安全性。JWT 的 header 和 payload 就是 Base64 編碼的,不要在裡面放敏感資料。

Q:MD5 還能用嗎?

A:用於安全用途(密碼存儲、數位簽章)絕對不行。用於非安全用途(檔案校驗、快取鍵)可以接受。

Q:對稱加密和非對稱加密如何選擇?

A:需要與對方共享秘密 → 非對稱。已有共享秘密 → 對稱。通常兩者配合使用(混合加密)。

Q:免費的加密工具推薦?

A:Super Tools 提供免費的 Hash 生成器、Base64 編碼/解碼、URL 編碼/解碼等工具,所有計算都在瀏覽器端完成,資料不會上傳伺服器。

結語

理解加密與編碼的差異是每個開發者的基本功。記住核心原則:編碼不是加密、MD5 不安全、密碼用 bcrypt/Argon2、傳輸用 HTTPS、存儲用 AES-256-GCM。善用 Super Tools 的編碼和安全工具,在開發過程中隨時驗證和測試你的加密邏輯。