Password-Hashing

如果我們使用好的散列算法,為什麼需要好的密碼?

  • December 20, 2019

我們一次又一次地被建議製作好的密碼:至少 12 個字元、數字、符號、大小寫。

但為什麼真的需要呢?

如果系統使用可以在 ASIC 中實現的散列算法,我可以看到這種需求,攻擊者可以每秒測試數万億個組合。

但是使用scrypt,Argon2和類似的技術,我們應該能夠使攻擊者的成本如此之高,以至於僅測試數十億個密碼是不可行的。兩者都可以調整為需要大量 RAM,在這種配置中,它們根本無法與 MD5、SHA-1 或 SHA-2 相提並論。例如,如果我們讓散列耗時 3 秒並使用 1 GB RAM,那麼僅測試 10 億個組合將需要 100 個 CPU 年和 100 GB*年。

交易計算 + RAM 資源以允許更簡單(儘管不是完全微不足道)的密碼不是相對容易嗎?

首先,諸如“至少 12 個字元、數字、符號、大小寫”之類的密碼強度規則實際上會適得其反——它們會導緻密碼稍微難以猜測,但更難記住,更糟糕的是,它們還經常以結尾up 還禁止使用Diceware等實際安全方法生成的密碼。

他們的一個有爭議的優點是他們不允許使用非常常見的弱密碼,如“password”、“abc123”或“letmein”。唉,阻止使用者選擇這些弱但易於記憶的密碼通常只會導致他們選擇系統可以接受的最簡單的密碼,例如“Password123!”,任何半體面的密碼破解工具仍然可以輕鬆猜測(但現在使用者更容易忘記他們使用的標點符號以及他們是放在數字之前還是之後)。

(此類規則的另一個有爭議的歷史理由是,使用多種字元可以從短密碼中擠出一點額外的熵,這可能與嚴格限制密碼長度的系統相關,例如舊的 Unix DES-crypt 方案從 1970 年代起,將密碼截斷為最多 8 個字元。但是這種古老的密碼散列方案無論如何從根本上講是不安全的,在密碼中混入一些標點符號不會使它們安全。不過,這可能是最初制定此類規則的原因之一首先介紹和普及。)


無論如何,就目前而言,你的數學在我看來或多或少是合理的:30 億秒大約是 95 年,所以如果在快速 CPU 上測試單個密碼需要 3 秒,那麼熵大約為 30 位的密碼(即從其中均勻隨機選擇 $ 2^{30} \approx $ 10 億種可能性)將花費 95 個 CPU 年,大多數攻擊者可能認為這太費力了。話雖如此:

  • 密碼破解是一項令人尷尬的並行任務,因此願意為其投入 95 個 CPU 核心的攻擊者會將時間縮短至僅一年。使用 5000 個核心(即使是相當小的殭屍網路或伺服器場也很容易達到),它可以縮短為一周。

還要記住,處理器仍在繼續變得更快(和/或更多並行),並且 RAM 價格仍在繼續下降。這不僅意味著破解任何特定密碼雜湊的時間成本會隨著時間的推移而下降,而且您也不能假設您的所有使用者都擁有最新和最好的 CPU,而任何積極主動的攻擊者可能確實可以訪問這些 CPU,或者在至少到相當接近的東西。您的一些使用者可能(至少偶爾)使用 10 或 20 年的舊設備,但 CPU 速度較慢且記憶體有限,他們希望能夠使用這些設備登錄;擁有殭屍網路的攻擊者將擁有大量更新的設備供他們使用。

  • 三秒鐘等待您的密碼被接受已經是相當尷尬的時間。對於不經常使用的情況,它可能沒問題,但是您真的想在每次登錄網站或從浴室休息返回工作站時等待那麼長時間嗎?我已經看到一秒被列為大多數使用者可能會接受的最大延遲,這可能有點推動它。就個人而言,我的目標不會超過 0.3 到 0.5 秒。

如果您想快速嘗試一下,請計算您每天需要輸入密碼(甚至是預填密碼)或 PIN 碼的次數。然後嘗試慢慢數(“1 密西西比,2 密西西比,3 密西西比”)到三,然後每次按輸入鍵。看看你需要多長時間才能厭倦這些停頓。

  • 在任何情況下,對於遠端伺服器(例如網站)的身份驗證,即使每次登錄 0.3 秒的密鑰拉伸也只有在您可以在客戶端上完成工作時才真正可行。如果您嘗試在伺服器端執行您建議的那種緩慢且記憶體密集型的散列,任何人都可以通過簡單的拒絕服務攻擊讓您的伺服器癱瘓,只需讓機器人嘗試使用隨機使用者名登錄和密碼每秒幾次。哎呀,即使沒有機器人,您也可以通過反复點擊登錄按鈕來做到這一點。

通過在現代瀏覽器中實現Web Crypto API和/或WebAssembly ,網站可以在客戶端進行密鑰拉伸。不過,我還沒有看到任何標准或廣泛使用的實現,雖然原則上可行,但它有一些重要的安全性和可用性缺陷,任何自定義實現都需要小心避免。此外,它基本上使無法或不會執行 JavaScript 的使用者無法登錄,因為任何替代的回退機制也可能被攻擊者濫用。所以,至少有一段時間,我們仍然主要停留在伺服器端密碼散列。

首先,使用 Argon 之類的東西或類似的實現來進行密碼管理當然是個好主意。但是您的提議必須考慮一些問題:

  1. **複雜性:**實施密碼策略的主要原因是防止使用者選擇過於簡單的密碼。如果您忽略密碼策略,您可以確定很大一部分使用者會使用簡單密碼。這就是攻擊者可以使用其他攻擊而不是簡單的暴力破解的地方,例如字典攻擊。如果不使用至少一些合理的密碼策略,您會通過嘗試最常用的密碼來找到相當多的密碼。使用資源密集型算法不會阻止它在攻擊者可管理的時間空間內發生。
  2. **性能:**根據您的資源,讓伺服器執行如此密集的計算可能不是一個好主意。在不影響伺服器的其他功能的情況下,將迭代次數設置得合理是可以接受的。但是您可以通過客戶端散列來防止性能問題。

一般來說,您必須為這個問題找到一個合理的折衷方案:使用者想要簡單並希望快速登錄。負責系統安全的人希望使用者使用非常複雜和安全的密碼,並且希望登錄需要一些時間。

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