如果令牌在數據庫中散列,我如何驗證重置令牌?
我一直在網上搜尋有關安全密碼重置系統(帶有重置 url 的電子郵件)的最佳實踐方法,以及在數據庫中散列令牌的想法,我一開始沒有實現,似乎是儲存令牌的最安全方式。
我目前正在關注本指南,但他沒有提及(為什麼?)
我已經使用 bcrypts 進行密碼散列,所以這也是我使用的。
然而,驗證的語法是這樣的: Bcrypt.verify(non-hash, hash);
所以我的問題是: 如果重置連結只包含令牌(不在數據庫中,雜湊是) - 我如何在數據庫中找到使用者?
將電子郵件/使用者 ID 附加到重置連結是否安全?我見過的其他服務都沒有這樣做(afaik),只有令牌(他們不在數據庫中散列令牌嗎?)。
我不想制定會產生安全問題的自己的方案,那麼我該如何進行呢?
使用 asp.net 網頁表單和 c#
我也在思考這個問題,很難找到答案。
我的解決方案:不要用 bcrypt 散列令牌。而是使用不加鹽的例如 SHA256 對其進行散列。如果令牌是真正的隨機數據並且足夠長,它將足夠安全。
那麼雜湊值將始終相同,因此您可以輕鬆地在數據庫中找到它。無需遍歷數據庫中的所有使用者或令牌——那太瘋狂了。
驗證我的解決方案的一些資源:
您的令牌需要一個屬性,雜湊需要一個屬性。重置令牌必須是不可預測的。令牌的散列必須是抗原像的。
要製作不可預測的令牌,您可以從**/dev/urandom 之類的文件中獲取 16 個字節。**或任何具有同等安全屬性的 RNG。(Java 的 SecureRandom、Python 的 os.urandom、.NET 的 RNGCryptoServiceProvider 等)如果攻擊者可以猜到下一個令牌,她就可以更改一個人的密碼,而無需閱讀帳戶所有者的電子郵件。
令牌的散列需要原像抗性。否則,對重置令牌列表具有讀取權限的人(管理員或黑客)可以計算自己的與雜湊匹配的令牌。當您不對密碼等內容進行雜湊處理時,您應該將 BCrypt 替換為 SHA-2。
BCrypt 的目的是拉伸低熵密碼。(意思是相對可預測的。)如果密碼總是具有高熵,那麼您可以使用任何抗原像散列。BCrypt 的目標是減慢每個人對密碼和散列的猜測和檢查速度……但是正常的加密散列函式可能比 SHA-2 快幾個數量級,並且如果輸入仍然是非暴力破解的熵很高。(這就是為什麼你生成一個長的不可預測的令牌。來自 urandom 的 16 個字節應該給出相當於 128 位熵的不可預測性。)
**不要根據客戶提供的數據重置哪個帳戶的電子郵件!**將令牌、過期時間和使用者 ID 都放在同一個數據庫條目中。
**請使用為您實施密碼管理的庫。**如果您了解更多資訊,您可以使用您對密碼學的了解來判斷庫是否安全,但您需要對安全和密碼學主題有更深入的了解,然後才能正確實現自己的系統。