Vibe Coder

資料加密與傳輸安全:HTTPS 與靜態加密缺一不可

資料保護要同時做到傳輸加密與靜態加密兩層:傳輸加密靠 HTTPS(TLS)保護資料在網路上的安全,靜態加密則保護資料存在資料庫時的安全,包含密碼 hash、欄位層 AES 加密與 Supabase 的磁碟加密。只做其中一層都不夠,兩層都要顧到。
資料加密與傳輸安全:HTTPS 與靜態加密缺一不可

資料加密與傳輸安全:HTTPS 與靜態加密缺一不可

就算攻擊者拿到你的資料庫備份,加密過的資料能讓他們什麼都看不到,這是縱深防禦的最後一層,但它不是唯一一層。沒有 HTTPS,使用者的密碼和 Token 在傳輸途中就是明文,任何中間人都能看到。

這篇拆解加密的兩個層次:傳輸加密和靜態加密,帶你看懂 HTTPS 怎麼運作、敏感欄位該怎麼加密,以及五個大家常有的加密誤解。

你將學到什麼

加密的兩個層次

傳輸加密與靜態加密保護的對象不同,兩個都要做。

HTTPS 怎麼運作

TLS 憑證、強制重定向、HSTS 三件事。

敏感欄位怎麼加密

密碼、API Key、信用卡號、一般個資各自的正確做法。

常見的加密誤解

Base64 不是加密、MD5 不安全、金鑰管理才是關鍵。

加密的兩個層次

傳輸加密In Transit使用者伺服器HTTPS / TLS靜態加密At Rest伺服器資料庫加密後寫入兩者要同時做,缺一不可
傳輸加密顧路上,靜態加密顧硬碟,兩個都要做。
層次保護什麼怎麼做
傳輸加密(in transit)資料在網路上傳輸時的安全HTTPS(TLS),現代平台自動提供
靜態加密(at rest)資料存在資料庫或磁碟時的安全資料庫層加密、欄位層加密、密碼 hash
兩個都要做只有 HTTPS 沒有靜態加密:傳輸安全,但資料庫洩漏就完了。只有靜態加密沒有 HTTPS:傳輸途中被截,加密也無用。兩層都要。

傳輸加密:HTTPS 怎麼運作

HTTPS 等於 HTTP 加上 TLS,TLS 在傳輸前加密、接收後解密,中間人只能看到亂碼。

  1. TLS 憑證:證明「這個網站是它說的那個網站」,由憑證機構(CA)簽發。Let's Encrypt 提供免費憑證,現代部署平台(Railway、Render、Vercel)自動配置。
  2. 強制 HTTPS 重定向:有了 HTTPS 還要確保 HTTP 的請求被強制重定向到 HTTPS,不讓使用者有機會走不加密的連線。
  3. HSTS:告訴瀏覽器「這個網站只接受 HTTPS」,之後的連線瀏覽器直接用 HTTPS,不需要重定向。
from fastapi.middleware.httpsredirect import HTTPSRedirectMiddleware
from fastapi import FastAPI

app = FastAPI()
app.add_middleware(HTTPSRedirectMiddleware)

# 或手動加 HSTS header
@app.middleware("http")
async def add_hsts(request, call_next):
    response = await call_next(request)
    response.headers["Strict-Transport-Security"] = "max-age=31536000"
    return response

靜態加密:敏感資料怎麼存

資料類型加密方式說明
密碼bcrypt hash(單向)不可還原,只能驗證,永遠不存明文
API Key(使用者的)bcrypt hash 或 AES 加密需要顯示給使用者就用 AES,只需驗證就用 hash
信用卡號不要自己存,用 StripePCI DSS 合規成本極高,交給支付服務商
一般個資資料庫層加密(Supabase 內建)磁碟層加密,整個 DB 都保護
特別敏感欄位欄位層 AES 加密即使 DB 洩漏,該欄位還是密文
from cryptography.fernet import Fernet
import os

# 用環境變數存加密金鑰,不要寫死
key = os.getenv("FIELD_ENCRYPT_KEY").encode()
f = Fernet(key)

def encrypt(data: str) -> str:
    return f.encrypt(data.encode()).decode()

def decrypt(token: str) -> str:
    return f.decrypt(token.encode()).decode()

Supabase 的加密設定

功能預設說明
磁碟加密自動啟用所有 Supabase 專案的儲存都有 AES-256 磁碟加密
傳輸加密 HTTPS自動所有 API 連線強制 HTTPS
Row Level Security需手動啟用每個 table 都要執行 ALTER TABLE ... ENABLE ROW LEVEL SECURITY
欄位層加密需自己實作使用 pgsodium 或應用層加密,特別敏感欄位才需要

加密常見誤解

誤解事實
HTTPS 就夠了HTTPS 只保護傳輸,資料庫洩漏了 HTTPS 沒用
我 App 很小,沒人想攻擊攻擊是自動化的,大小不影響被掃到的機率
用 Base64 就是加密Base64 是編碼不是加密,任何人都能解碼
MD5 hash 就安全MD5 有彩虹表可以反查,只適合校驗和,不能用於密碼
加密了就不怕洩漏加密金鑰管理不好,加密跟沒加密一樣
加密金鑰的保管加密金鑰比它保護的資料更重要。金鑰要存在環境變數或 Secret Manager,定期輪換,絕對不能和加密的資料存在同一個地方。

延伸學習

把這篇文章分享給需要的人FacebookLINEThreadsX

常見問答

只做 HTTPS 夠嗎?
不夠。HTTPS 只保護資料在網路上傳輸時的安全,如果資料庫本身洩漏了,HTTPS 完全幫不上忙,還需要靜態加密(資料庫層加密、欄位層加密、密碼 hash)來保護存放中的資料。
Base64 編碼可以當加密用嗎?
不行。Base64 是編碼不是加密,任何人都能用標準工具解碼還原,完全沒有防護力,千萬不要把它當成保護敏感資料的手段。
Supabase 的資料預設是加密的嗎?
磁碟加密和傳輸 HTTPS 是自動啟用的,但 Row Level Security 需要手動對每個 table 開啟並設定 policy,欄位層加密也要自己用 pgsodium 或應用層加密實作,這兩項不是預設就有。
Fernet 適合用在什麼地方?
Fernet 是 Python 的對稱加密工具,適合用來加密資料庫裡特別敏感的欄位,例如使用者備註,寫入前加密、讀出後解密,即使資料庫外洩,該欄位還是密文,是 Vibe Coder 做欄位層加密最簡單的選擇。