Passwords

使用基於密碼的密鑰派生函式生成密碼

  • July 21, 2016

我正在考慮為不同的網站使用不同且獨立的密碼,但不將它們儲存在某些密碼管理器中,因此我不需要備份密碼。我想我可以使用一些加密技術來做到這一點,我想出了一個執行以下操作的腳本:

  • 使用者在腳本中輸入主密碼。
  • 使用者在腳本中輸入名稱或域 - 為site name.
  • 該腳本使用帶有 HMAC(在 Python 中)的PBKDF2hashlib.pbkdf2_hmac生成密鑰,使用主密碼作為密碼輸入,使用site namesalt250000作為迭代次數,使用 8 個字節作為密鑰長度。

目前在我的電腦上執行此操作大約需要 1 秒。

  • 結果鍵被視為一個數字,並轉換為基數 75。然後使用以下數組將每個結果數字映射到一個字元:
0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz
  • 該腳本輸出結果字元串,該字元串用作該站點的密碼。

我想用這個腳本實現三個目標:

  1. 給定相同的主密碼和相同site name的,腳本應該輸出相同的字元串,這是在網站上使用的一個很好的安全密碼。
  2. 僅給定生成的密碼 和site name,攻擊者應該不可能計算出主密碼(如果主密碼很強的話,至少需要很長時間)。
  3. 僅給定生成的密碼 和site name,攻擊者也應該不可能計算出其他 的密碼site name

我的問題是:這是一個安全的密碼生成器嗎?我使用的主密碼基本上就像這個腳本將輸出的密碼一樣。

我的實現可以在這裡找到

就像我在評論中寫的那樣,這裡的方法非常相似。區別:

  1. 我建議不要直接從密碼派生每個站點密碼,而是使用密碼雜湊派生單個主密鑰,然後使用另一個 KDF 從中派生站點密碼。
  2. 您正在將 PBKDF2 輸出截斷為 64 位。
  3. 您明確定義將散列轉換為密碼的方法。

關於第一個,使用單個主密碼可以讓您派生一次,然後快速派生多個特定於站點的密碼。(它還使用了一種已知的唯一鹽,這很好。)這不是必需的,但確實意味著在某些情況下您可能可以使用更多的迭代。

截斷到 64 位應該沒問題,但如果您可以複製粘貼更強的位,則沒有必要。(如果您的密碼足夠複雜,強制使用 64 位雜湊或派生密碼將比攻擊主密碼更快。)

最後一個是有問題的。正如我在上面連結的問題的評論中所討論的那樣,每個站點對密碼都有自己的要求,因此任何像這樣的靜態算法都不太可能適用於所有人。然而,這不是一個安全問題:只要您不進一步從散列中刪除資訊,任何將其編碼為密碼的方法都可以。


但是我不確定是否可以使用這種簡單的鹽。就像我曾經聽說鹽應該是不可預測的……

不,鹽只必須是唯一的。但是,如果您需要更改站點密碼(例如,他們的數據庫被盜並且他們需要新的),您可能需要在站點名稱中添加一些內容。此外,理論上使用相同方法的其他人可能會使用相同的鹽,從而實現更快的攻擊。(添加例如您的電子郵件地址可以解決這個問題。)


除了我在另一個問題(下面引用)中提到的缺點之外,還有使用哪個密碼雜湊的問題。PBKDF2 並不完全是最先進的,使案例如 scrypt 可能會給您帶來比潛在對手更大的優勢。

如果你走這條路,你就是把所有的雞蛋放在一個籃子裡。如果您忘記了主密碼,您將失去所有派生密碼。如果有人猜到了,他們可以推導出所有其他的。

最好使用防止猜測攻擊的密碼管理器。不然師父一定很強。密碼管理器生成隨機站點密碼,不會洩露有關主伺服器的資訊。

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