TOTP 生成器
根據 base32 金鑰生成並校驗基於時間的一次性密碼(TOTP),相容 Google 身份驗證器與 RFC 6238。
一次性密碼,RFC 6238。 根據 base32 金鑰生成當前 TOTP,並校驗你收到的驗證碼。計數器由當前時間推導,因此每 30 或 60 秒重新整理一次。全部在瀏覽器內完成。
根據 base32 金鑰生成並校驗基於時間的一次性密碼(TOTP),相容 Google 身份驗證器與 RFC 6238。
一次性密碼,RFC 6238。 根據 base32 金鑰生成當前 TOTP,並校驗你收到的驗證碼。計數器由當前時間推導,因此每 30 或 60 秒重新整理一次。全部在瀏覽器內完成。
TOTP 由 RFC 6238 定義,本質上是 HOTP 之上的一層薄封裝。雙方持有同一個金鑰,通常在開通時以二維碼形式交付一次,並儲存在驗證器應用中。生成驗證碼時,兩側各自取當前 Unix 時間,除以步長(預設 30 秒)得到計數器,用金鑰對該計數器做 HMAC-SHA1,再把結果截斷成所需位數。
由於計數器來自時鐘而非某條訊息,開通之後兩方之間無需再傳輸任何資料。服務端不必下發挑戰值,應用也不需要網路連線——這正是驗證器應用在飛航模式下依然可用的原因。
HMAC 輸出 20 位元組,遠多於一個 6 位驗證碼所需。動態截斷的做法是:取最後一個位元組的低四位作為偏移量,從該位置讀取 4 個位元組,遮蔽最高位以避免符號問題,再對 10^位數 取模。使用可變偏移而非固定偏移,意味著攻擊者無法把分析集中在摘要中某個已知片段上。
6 位幾乎是通用預設值。多數應用也支援 8 位,能多提供約兩位十進位制的抗猜測能力,但這遠不如限流重要——6 位驗證碼單次猜中的機率是百萬分之一,真正的防線是連續失敗幾次後鎖定。
裝置時鐘會漂移。服務端通常除當前視窗外,還接受前一個和後一個視窗的驗證碼,從而提供約 ±30 秒的容差。把視窗放寬到一兩分鐘以上,攻擊面就會明顯增大,而且這通常說明該修的是裝置時鐘。
部署時有兩點值得記牢。一是驗證碼在整個視窗內都有效,因此被截獲的驗證碼可以在該視窗內重放,除非服務端把用過的計數器標記為已消費。二是金鑰是對稱的:任何拿到服務端副本的人都能永久生成有效驗證碼,所以它需要與密碼資料庫同等級別的保護——靜態加密、絕不寫日誌、絕不進 git 倉庫。