National Central University
Uedu Main Site
Explore Uedu
Student Console
Register as Member/Login
Research Informed Consent Center
Survey Center
Educational Big Data Challenge
Claim or create a course
Try an AI Scenario Task
Support & Messages
Uptime Data

UeduGPTs

--

Jupyters

3

Local AI

--

Uedu Code

--

中央大學 AQI 72 24°C PM2.5 13
AI Reply Desktop Notifications

Show a desktop notification when the AI TA finishes replying

Chat Message Notifications

Notify me when classmates post messages in the forum

Sound notification

Play an alert sound whenever there is a new notification

Unit 02

雜湊與密碼儲存

加鹽、慢速雜湊與密碼外洩後的影響
Interaction 35 minute(s)

Learning Objectives

  • 區分雜湊與加密,說明密碼為什麼只存雜湊值
  • 比較明文、未加鹽、加鹽與慢速雜湊在資料外洩後的差異
  • 說明字典攻擊與彩虹表的原理,以及加鹽與迭代次數各自的作用
  • 以 werkzeug.security 修補註冊與登入程式,並確認舊的儲存方式已不再使用

密碼儲存與資料外洩

網站的資料庫可能因為注入漏洞、外流的備份或內部人員而落入他人之手。資料庫內容一旦外流,密碼欄位如何儲存,決定了後續的損害範圍。使用者常在不同網站使用相同的密碼,所以外洩的明文密碼也會影響其他網站。這正是撞庫攻擊(第 5 課)的來源。

雜湊(hash)把任意長度的輸入轉成固定長度的輸出,可以由輸入算出輸出,但無法由輸出直接還原輸入。加密則是可逆的:持有金鑰就能解回原文。兩者用途不同:

雜湊 加密
可否還原 設計上不能 持有金鑰即可解密
是否需要金鑰 不需要 需要
用途 比對是否相同、驗證完整性 保護之後還要讀取的資料

驗證密碼時,網站不需要知道原文,只要比對雜湊值是否相同。如果網站事後能寄回你原本的密碼,代表它保存了明文或可還原的形式,這是不安全的設計。

雜湊無法還原,不代表密碼安全。 攻擊者可以把候選密碼逐一雜湊,再與外洩的值比對,這稱為字典攻擊。候選密碼可以來自常見密碼清單與其變化形式。對一般用途的雜湊函數而言,一台電腦每秒能算很多次,所以單純以 SHA-256 儲存密碼並不足夠。

本課的模擬環境。 比對只針對虛構的外洩資料,在你的瀏覽器內執行,不連線到任何系統。對未獲授權的真實資料進行比對可能觸犯法律(第 1 課)。

互動練習:加鹽與迭代次數

所有雜湊值都由瀏覽器的 crypto.subtle 實際計算。加鹽時的輸入是「鹽字串+密碼」。

彩虹表與慢速雜湊

未加鹽時,同一個字典對所有網站都適用,攻擊者可以預先算好「雜湊值對應密碼」的大型對照表。彩虹表(rainbow table)是這類預先計算對照表的一種。加鹽讓每個帳號的雜湊輸入都不同,預先計算的表便失去作用;它也讓相同密碼的帳號不再一眼可辨。

加鹽解決了預先計算與重複的問題,但沒有讓單次計算變慢。慢速雜湊刻意提高每次計算的成本。使用者登入時多花不易察覺的時間,攻擊者要嘗試大量候選密碼時,這個成本會乘上候選密碼的數量。

下列參數取自 OWASP Password Storage Cheat Sheet,為建議的最低設定,應依伺服器能力再往上調整:

演算法 建議參數 說明
Argon2id 記憶體 46 MiB、t=1、p=1(另有相當的組合,例如 19 MiB、t=2) OWASP 的首選,同時消耗記憶體與時間
scrypt N=2^17、r=8、p=1(另有相當的組合) 無法使用 Argon2id 時的選擇,同樣消耗記憶體
bcrypt 工作因子至少 10 用於既有系統;多數實作的輸入上限為 72 位元組,應限制密碼長度
PBKDF2 HMAC-SHA256 迭代 600,000 次 需要符合 FIPS-140 時使用;不具記憶體成本

消耗記憶體的演算法,能提高以專用硬體平行運算的成本。胡椒(pepper)是全站共用、與資料庫分開保存的祕密值,屬於額外的防線,不能取代鹽。

密碼學函式庫通常會自動產生鹽,並將演算法、參數、鹽與結果存成一個字串,不需要手動處理。Flask 使用的 Werkzeug 預設採用 scrypt,產生的字串依序包含 scrypt:32768:8:1、鹽與雜湊值,以錢字號分隔。這組預設值 N=2^15、r=8、p=1 低於 OWASP 列出的組合(N=2^15 時 OWASP 列的是 p=3),正式環境可以自行指定參數,例如 method='scrypt:131072:8:1'。

互動練習:外洩資料的字典比對

這份虛構的外洩資料中有 6 個帳號。字典由常見字詞及其首字大寫、數字與符號結尾的形式組成,由程式產生。請依序完成任務。

密碼規則的建議

網站對使用者設定密碼的要求,也會影響字典攻擊的成效。NIST SP 800-63B-4(2025 年定稿)對驗證者的要求包括:

項目 NIST SP 800-63B-4
最小長度 單獨作為一個因素時至少 15 個字元;只用於多因素驗證時至少 8 個字元
最大長度 應至少允許 64 個字元
組成規則 不得要求混合大小寫、數字、符號之類的組成規則
定期更換 不得要求定期更換;有證據顯示外洩時必須強制更換
封鎖清單 必須比對常見、預期或已外洩的密碼清單,並向使用者說明拒絕的原因
密碼管理工具 必須允許密碼管理工具與自動填入,應允許貼上

這些建議的方向是鼓勵較長且不常見的密碼,同時減少促使使用者選擇簡單密碼的規定。下方練習將所學應用到程式上。

互動練習:修補註冊與登入程式

按「啟動伺服器」後依任務操作。「模擬資料外洩」頁面列出資料庫內容,只用於教學,真實網站不應該有這個頁面。這個頁面與「自動檢查」由唯讀的 lab_check.py 提供。

修補時請使用 werkzeug.security(兩個檢查頁面只辨識它的輸出格式):

from werkzeug.security import generate_password_hash, check_password_hash

stored = generate_password_hash(password)      # 註冊時儲存這個值
check_password_hash(stored, password)          # 登入時比對,回傳 True 或 False

修補前註冊的帳號是明文,比對不會成功。請在外洩頁按「清空練習資料」,再以修補後的程式重新註冊。

重點整理

  • 雜湊不是加密:雜湊設計上無法還原,加密持有金鑰就能解密。密碼不需要還原,只需要比對
  • 雜湊無法還原,不代表密碼安全;攻擊者可以將候選密碼逐一雜湊比對
  • 每個帳號都要有自己的鹽。鹽不需要保密,它使預先計算失效,並讓相同密碼的雜湊值不同
  • 慢速雜湊(Argon2id、scrypt、bcrypt、PBKDF2)提高每次嘗試的成本,參數依 OWASP 建議並隨硬體調整
  • 這些防護提高的是攻擊成本,弱密碼依然可能被猜中;NIST 建議以長度與封鎖清單取代組成規則與定期更換
  • 實作時使用經過檢驗的函式庫,不要自行組合雜湊函數與鹽

下一課討論加密:如何保護之後還需要讀取的資料,以及雙方如何取得同一把金鑰。

小測驗

1.

網站提供「寄回原本的密碼」功能。由此可以推斷什麼?

2.

資料庫外洩後,攻擊者發現其中兩個帳號的未加鹽 SHA-256 值相同。這代表什麼?

3.

為什麼 OWASP 不建議以「加鹽的 SHA-256」儲存密碼?

4.

下列關於鹽的敘述,何者正確?

5.

依 NIST SP 800-63B-4,下列哪一項是對驗證者的要求?

第 1 次作答
這一課完成了!
Next lesson:對稱與非對稱加密
你目前沒有登入,學習進度只存在這個瀏覽器。 Login 後,進度會跟著帳號,換電腦也看得到。