跳到主要內容

TOTP vs HOTP 深度解析:時間與計數器驅動的一次性密碼機制比較

在多因素驗證(MFA)的世界裡,TOTP 與 HOTP 是兩種最主流的一次性密碼規範。兩者同樣基於 HMAC 雜湊與共享對稱金鑰,卻因動態因子的不同,在安全特性與應用場景上各有取捨。

HOTP:計數器驅動的一次性密碼

HOTP(HMAC-Based OTP,RFC 4226) 以一個遞增計數器作為動態因子。每次產生 OTP,計數器加一;伺服器驗證成功後,同步更新自身計數器。由於不依賴時間,無需裝置與伺服器的時鐘同步,離線環境也能正常運作。然而,若使用者多次產生 OTP 卻未驗證,則客戶端與伺服器計數器將產生失步(Desynchronization)。規範允許伺服器在一定容差窗口(Look-ahead Window)內向前比對,以補救失步問題。此外,已使用的 OTP 若未被伺服器及時消費,存在重放攻擊風險。

TOTP:時間驅動的一次性密碼

TOTP(Time-Based OTP,RFC 6238) 是 HOTP 的延伸,以當前 Unix 時間戳除以時間步長(預設 30 秒)作為計數器。兩端各自獨立計算,毋須通訊即可對齊。時間步長結束後 OTP 自動失效,抗重放攻擊能力顯著優於 HOTP。代價是要求客戶端與伺服器的時鐘誤差不超過一個步長;實務上伺服器通常允許前後各一個窗口的容差(±30 秒)。Google Authenticator、Microsoft Authenticator 等主流應用均採用此規範。

import pyotp

secret = pyotp.random_base32()
totp = pyotp.TOTP(secret)   # TOTP(時間驅動)
hotp = pyotp.HOTP(secret)   # HOTP(計數器驅動)

print(totp.now())            # 當前 30 秒內有效的 OTP
print(hotp.at(0))            # 計數器為 0 時的 OTP

💡 重點整理:TOTP vs HOTP

  • 動態因子:TOTP 用時間步長,HOTP 用遞增計數器。
  • 抗重放攻擊:TOTP 的 OTP 30 秒後自動失效,安全性更高。
  • 同步需求:TOTP 需時鐘對齊;HOTP 需管理計數器失步問題。
  • 適用場景:TOTP 適合互動式登入;HOTP 適合無網路的實體 Token。

大多數現代系統應優先選擇 TOTP,其自動過期機制大幅降低重放風險。若應用場景無法保證時鐘同步,HOTP 仍是可靠的備選方案,但必須妥善設計計數器管理邏輯。

📚 參考文獻

  1. M'Raihi et al., RFC 4226 – HOTP: An HMAC-Based One-Time Password Algorithm,IETF,2005。https://datatracker.ietf.org/doc/html/rfc4226
  2. M'Raihi et al., RFC 6238 – TOTP: Time-Based One-Time Password Algorithm,IETF,2011。https://datatracker.ietf.org/doc/html/rfc6238
  3. PyOTP 官方文件,Python One-Time Password Library