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 78 24°C PM2.5 18
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 05

認證與多因素驗證

密碼、一次性密碼、通行金鑰與釣魚
Interaction 35 minute(s)

Learning Objectives

  • 區分認證的三類因素,說明暴力破解與撞庫的差別
  • 依 RFC 6238 計算 TOTP,並說明時間範圍的取捨
  • 比較密碼、TOTP 與通行金鑰面對釣魚網站的結果,說明通行金鑰綁定來源的作用
  • 為登入程式加上速率限制與一致的錯誤訊息,並確認正常功能仍可使用

認證因素與密碼攻擊

另一個網站的資料外洩後,外洩的帳號密碼會被拿來嘗試登入其他網站。即使校園系統本身沒有被入侵,重複使用密碼的學生帳號也可能因此被盜。

認證(authentication)是確認使用者身分的過程。依據可分成三類因素:

因素 例子
所知(something you know) 密碼、PIN
所有(something you have) 手機上的驗證器、硬體金鑰
所是(something you are) 指紋、臉部

多因素驗證要求兩類以上的因素。同一類的兩個祕密(密碼加上安全提示問題)不算多因素。

針對密碼的自動化攻擊,OWASP 區分為三種:

攻擊 作法 主要的防護
暴力破解(brute force) 對單一帳號嘗試多個密碼 依帳號限制失敗次數
撞庫(credential stuffing) 以其他網站外洩的帳號密碼組合逐一嘗試 多因素驗證、封鎖已外洩的密碼
密碼噴灑(password spraying) 以少數常見密碼嘗試大量帳號 封鎖常見密碼、多因素驗證

撞庫與噴灑對每個帳號只嘗試很少的次數,單靠依帳號的失敗計數不易察覺;攻擊者也可以透過代理網路分散來源,所以 OWASP 不建議把 IP 限制作為主要防護。

TOTP 的原理與限制

TOTP(Time-based One-Time Password,RFC 6238)是驗證器 App 常用的一次性密碼。註冊時,伺服器與裝置共有一組種子(常以 QR Code 傳遞),之後雙方各自依目前時間計算:

T    = ⌊(目前的 Unix 時間 − T0) ÷ X⌋      預設 T0 = 0、X = 30 秒
TOTP = HOTP(種子, T)                       以 HMAC 計算後做動態截斷

代碼不需要經由網路傳送就能產生,也會隨時間改變。RFC 6238 建議為網路延遲至多容許一個時步的誤差,時鐘漂移則可記錄各裝置的偏差後調整(第 6 節),並且要求同一組代碼不可使用第二次。容許範圍越大,對使用者越方便,但攻擊者可以利用的時間也越長。

種子是共用的祕密,伺服器必須妥善保存。若種子外洩,攻擊者可以計算出所有代碼。

簡訊驗證碼也是常見的第二因素,但有更多限制:攻擊者可以說服電信業者把門號轉移到另一張 SIM 卡(SIM 卡調換),NIST SP 800-63B-4 也將透過公用電話網路傳送的驗證方式列為受限制的驗證方式,要求另外提供不受限制的選擇,並告知使用者相關風險。下方練習真正計算 TOTP,並模擬伺服器的驗證。

互動練習:TOTP 的計算與驗證

種子使用 RFC 6238 測試向量的值(SHA-1 為 ASCII 字串 12345678901234567890),不是任何真實帳號的種子。HMAC 由瀏覽器的 crypto.subtle 計算。

釣魚與通行金鑰

釣魚是誘導使用者在假網站上輸入帳號密碼。假網站可以把畫面做得與真網站相同,密碼與 TOTP 都是使用者手動輸入的文字,假網站可以取得後即時轉送給真網站。NIST SP 800-63B-4 明確指出,需要手動輸入輸出值的方式不具抗釣魚性。

通行金鑰(passkey)以 WebAuthn 標準為基礎,使用公鑰密碼學。註冊時,裝置產生一對金鑰,伺服器只保存公鑰。這組金鑰與相關資訊在 WebAuthn 中稱為 credential,本課稱為通行金鑰憑據,與第 4 課的 TLS 憑證不同。登入時,裝置以私鑰對伺服器的挑戰值簽章。它能抵抗釣魚,關鍵在於通行金鑰憑據綁定來源:

  • 每個通行金鑰憑據都綁定一個 RP ID(信賴方識別碼),通常是網站的網域
  • 瀏覽器依實際連線的網域檢查:RP ID 必須等於這個網域,或是它的上層可註冊網域。例如 login.campus.example 可以使用 campus.example,campus.example.other.example 則不可以
  • 簽章的內容包含 RP ID 的雜湊值,以及瀏覽器填入的實際來源,所以伺服器也能驗證這次簽章來自哪裡

判斷由瀏覽器依網址進行,與頁面外觀無關。帳號若仍保留密碼登入,假網站可以直接要求輸入密碼,使用者依然可能受騙;要得到完整的保護,較弱的登入方式也要一併限制。通行金鑰也有不解決的問題:工作階段被竊取(第 6 課)、惡意程式、以及較弱的帳號復原流程,都需要另外處理。

本課的模擬環境。 下方的假網站與攻擊者都由程式模擬,只使用保留網域,不會連線到任何系統,也不包含任何真實機構的頁面。實際製作或使用釣魚頁面可能觸犯法律(第 1 課)。

互動練習:三種認證方式面對假網站的結果

選擇認證方式與連到的網站,按「登入」查看流程。TOTP 的代碼由程式計算;通行金鑰以瀏覽器的 ECDSA P-256 實際產生金鑰與簽章,RP ID 的判斷依 WebAuthn 的規則計算;為了容易觀察,簽章內容比實際的資料格式簡化。

速率限制與帳號列舉

登入程式本身也會洩漏資訊。若「查無此帳號」與「密碼錯誤」顯示不同的訊息,攻擊者不需要知道密碼就能確認哪些信箱已經註冊,這稱為帳號列舉。OWASP 建議對兩種情況回應相同的內容與狀態碼;回應時間的差異也可能洩漏帳號是否存在,所以應該讓兩種情況都執行相同的雜湊比對。

速率限制限制一段時間內的嘗試次數。常見的選擇有下列取捨:

作法 優點 限制
依帳號計數並暫時鎖定 直接阻止對單一帳號的暴力破解 攻擊者可以故意鎖定他人帳號,造成阻斷服務;需要提供重設或解鎖的途徑
依 IP 計數 不會鎖定帳號 攻擊者可分散來源;校園或公司共用同一 IP,容易影響到正常使用者
逐步增加等待時間 對正常使用者的影響較小 實作較複雜,仍要搭配其他防護

OWASP 建議把失敗計數綁定帳號而不是來源 IP,並留意鎖定被用於阻斷服務的情形。NIST SP 800-63B-4 要求連續失敗不得超過 100 次,並容許組織訂定更嚴格的限制。多因素驗證對大多數與密碼相關的攻擊都是較好的防護,速率限制與它互補,不能相互取代。

本課的模擬環境。 下方的「模擬連續嘗試」只對程式裡的虛構帳號呼叫函式,不會連線到任何系統。對真實網站進行連續嘗試可能觸犯法律(第 1 課)。

互動練習:一致的錯誤訊息與速率限制

按「啟動伺服器」後依任務操作。修補時只需要修改 attempt()。計數請寫在程式已有的 failures 字典,時間使用 time.time(),「自動檢查」頁會實際呼叫這個函式驗證行為(這個頁面與「模擬連續嘗試」由唯讀的 lab_check.py 提供)。一種可行的寫法如下,其中 DUMMY 讓不存在的帳號也執行相同的雜湊比對:

GENERIC = '信箱或密碼不正確'
DUMMY = generate_password_hash('placeholder', method=FAST)


def attempt(email, password):
    count, last = failures.get(email, (0, 0))
    if time.time() - last >= LOCK_SECONDS:
        count = 0                # 鎖定期滿後重新計數
    if count >= MAX_FAILURES:
        return False, GENERIC
    ok = check_password_hash(USERS.get(email, DUMMY), password) and email in USERS
    if not ok:
        failures[email] = (count + 1, time.time())
        return False, GENERIC
    failures.pop(email, None)
    return True, ''

鎖定期滿後要重新計數,否則本人打錯一次就會立刻再被鎖定,攻擊者也能藉此讓對方一直無法登入。真實系統的計數應放在資料庫或 Redis,並限制記憶體用量,才能在多個程序之間共用。

重點整理

  • 認證因素分為所知、所有、所是;多因素驗證要求兩類以上
  • 暴力破解、撞庫與密碼噴灑的作法不同,防護也不同;單靠 IP 限制不足
  • TOTP 由共用種子與時間計算,容許範圍要小,代碼不可重複使用;簡訊驗證碼有 SIM 卡調換等限制
  • 密碼與 TOTP 都能被假網站取得後轉送;通行金鑰的抗釣魚性來自綁定來源,前提是帳號不再接受較弱的登入方式
  • 登入錯誤應顯示一致的訊息,回應時間也要接近,以避免帳號列舉
  • 依帳號鎖定可能被用來影響他人,要限制鎖定時間、提供重設途徑,也不能影響其他帳號

下一課討論登入之後如何維持狀態:工作階段與 Cookie。

小測驗

1.

下列何者屬於真正的多因素驗證?

2.

外洩的帳號密碼組合被用來嘗試登入其他網站,這稱為什麼?最主要的防護方向是什麼?

3.

使用者在假網站輸入了密碼與當下的 TOTP 代碼。攻擊者立即轉送給真網站,會發生什麼事?

4.

通行金鑰的公鑰存放在伺服器。若伺服器的資料庫外洩,攻擊者能否以此登入?

5.

為防止暴力破解,登入程式在失敗 5 次後永久鎖定帳號,直到管理員處理。這個設計的問題是什麼?

6.

登入失敗時,頁面顯示相同的訊息,但不存在的帳號回應特別快。這代表什麼?

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