One-Time-Password

驗證電話號碼所有權的行業標準是什麼?

  • November 10, 2016

生成驗證電話號碼所有權的一次性 SMS 程式碼的行業標準是什麼?

我目前正在評估兩種主要的替代方案,它們都基於通過 SMS 向該電話號碼發送驗證碼。如何正確生成這樣的程式碼?

  1. 獲取作業系統生成的隨機 GUID 並以某種方式將其縮短為對人類友好的程式碼,例如 6 位數字。
  2. 使用遞增的儲存序列並將其確定性地混淆為人類友好的程式碼。

對於選項 1,我主要關心的是如何將 GUID 縮短為對人類友好的東西,同時仍然保持良好的熵。

如果最大序列值明顯大於預期的程式碼計數,則選項 2 允許唯一性,但它是完全確定的,並且可能允許基於多個後續程式碼的知識進行攻擊。

SMS 程式碼僅用於驗證電話號碼的所有權。這不是 2 因素身份驗證方案,也幾乎不是身份驗證,因為任何擁有工作電話號碼的人都有權訪問其背後的服務。這樣做的唯一原因是防止人們輸入他們不擁有的號碼,並可能讓我們的服務垃圾郵件與我們的服務無關,不知情的人發送簡訊。

更新

最初的問題並未反映實際問題,即驗證匿名提供的電話號碼實際上屬於實際供應商。

感謝所有回复,我相信從 CSPRNG mod 10^n 獲取幾個字節是合適的方法。

我不認為有任何書面的“行業標準”,就像在任何情況下生成隨機數時一樣:只需使用正確播種的 CSPRNG。我們最接近的是 TOTP/HOTP。

從 TOTP/HOTP 大致所做的事情來看,您的兩個想法要復雜得多:採用 CSPRNG,輸出 4 字節,截斷為 31 位,並取模 1000000(請注意,TOTP/HOTP 實際上還有更多內容,請參閱根據RFC 了解詳情)。這會產生非常小的偏差,這不是問題。

正如SEJPM 在他的評論中指出的那樣,SMS 可以被擷取,尤其是最近,一些使用“最佳推薦”的方被通過 SMS 重置密碼進行了黑客攻擊。因此,您應該考慮 TOTP/HOTP,並且 SMS 可以作為 HOTP 的一種變體來實現(這將允許您檢查以前的令牌是否被重用)。

簡而言之:1 和 2 都不是。使用正確播種的 CSPRNG(可以使用 /dev/urandom 或 CryptGenRandom),然後取 31 位並將它們取模為 1000000。更好的是,允許使用 HOTP/TOTP(其作用基本相同)事情,而不依賴於通道安全)。

引用自:https://crypto.stackexchange.com/questions/41347