2014-01-13 55 views
9

我最近閱讀了一篇關於password hashing and salting的文章,其中解釋了它的含義(在「SlowEquals代碼如何工作?」下),必須使用SlowEquals函數來比較輸入密碼的哈希與數據庫中密碼的哈希值。爲什麼SlowEquals函數比較散列密碼很重要?

據我所知,它使用SlowEquals函數,因爲它使用XOR而不是==,因此將檢查兩個字符串中的每個字符,而不是在第一個不匹配的字符上失敗。

有兩件事情我不明白:

  1. 爲什麼異或繼續檢查字符串達到以失敗狀態之後。
  2. 如果主要思想是在嘗試破解密碼時不給攻擊者提供任何有用的信息,那麼隨機生成的時間就不會有睡眠()函數這麼做了嗎?
+2

銥星很好的解釋了這個問題。 SlowEquals可以用來阻止*基於時間的旁道攻擊*。增加額外延遲的問題是統計信息能夠消除任何恆定時間延遲。此外,它可以用來消除任何隨時間推移而不變的延遲*(!)因此,在0到10之間添加完全隨機的延遲將平均延遲5秒。假設一個成功的比較需要.1s和一個不太成功的0.05s,那麼你可以簡單地做1000次相同的比較,如果平均需要大約5.1s,你猜對了。統計是一個婊子:) –

+3

1)SlowEquals是一個壞名字。只要時間不變,它是否緩慢並不重要。典型的實現非常快。 2)這裏不重要*。持續時間比較對於MAC驗證至關重要。 – CodesInChaos

+2

關於security.se的相關問題[bcrypt是否比較「length-constant」時間內的哈希值?](http://security.stackexchange.com/questions/46212/does-bcrypt-compare-the-hashes-in-length -constant-time) – CodesInChaos

回答

10

,該算法比較兩個哈希的所有字節僅僅是執行的結果,並沒有涉及到使用XOR的事實(即一個可以寫的所有字節,而不在破比較的算法即使使用==也不匹配)。 XOR的使用旨在避免在循環體中引入分支指令,這可能會揭示由於CPU的分支預測而導致的匹配字節數的細節(儘管這是否是一個問題將取決於特定的實現以及編譯的指令)。

使用隨機sleep()來掩蓋在第一次不匹配時返回的哈希校驗的時間並不會真正起作用,因爲它可能仍然可以通過獲取更多采樣來區分匹配與給定點處的不匹配。如果我們假設我們的睡眠時間爲均勻分佈在[0..100]範圍內的隨機數毫秒,並且某個位置的匹配需要2ms,並且該位置的不匹配只需要1ms(如同算法儘早退出)。在足夠的採樣情況下,我們可以區分匹配和不匹配的情況,因爲我們可以觀察到不匹配情況下的[1..101] ms範圍內的響應,但匹配情況下的[2..102] ms(假設我們可以完美地響應時間) 。當然,真實世界的觀察將會受到抖動和其他隨機性的影響,但是仍然可能會觀察到偏差。

那麼當然有簡單的實際考慮 - 爲什麼要引入睡眠,隨機等相對較小的修改應導致它在恆定時間運行,並消除定時攻擊?

+3

由於我們正在比較* hashes *,因此比較失敗的字符的信息有多重要?我想這取決於攻擊者是發送散列還是未加密的密碼。哦,沒關係,上面的CodeInChaos鏈接解決了這個問題! – joeytwiddle

2

TL; DR - 比較密碼哈希時,使用SlowEquals並不重要。

如果您試圖驗證非散列祕密,那麼使用「SlowEquals」對於阻止定時攻擊會很有價值。但是,如果您使用的計算密集程度足夠高(PBKDF2,50k +迭代)的正確密碼哈希,那麼這只是簡單的並不重要。爲什麼?因爲密碼哈希「假定違約」。即使攻擊者竊取/知道散列和鹽,找到一個明文密碼的過程非常耗時,因此密碼仍然受到保護。這就是密碼哈希的重點,即使被盜也不可用。當然,有人可以使用定時攻擊來計算散列,但這並不重要,因爲他們仍然無法找出密碼。

加上鎖定功能,在X無效嘗試後(3-10,請選擇)帳戶鎖定後,對散列密碼的計時攻擊從毫無價值變爲毫無價值。

1

如果沒有slowEquals

讓我們考慮計算比較兩個chararters使用2秒(真正的計算更快,但大量的測試可以工作),我們使用1234554321作爲密碼。 攻擊者使用0000000000來嘗試。因爲我們沒有使用slowEquals函數,所以比較僅需要2秒,因爲0!= 1, 因此當攻擊者知道「2秒」時,他會將「0」更改爲另一個,直到使用「1000000000」,那麼服務器需要4秒鐘。