2015-10-25 76 views
2

防止哈希字符串比較計時攻擊的一種方法是執行額外的HMAC簽名以隨機化驗證過程(請參閱https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/february/double-hmac-verification/)。PHP雙隨機hmac驗證以防止計時攻擊

除了每個散列的第二次HMAC散列之外,爲了使散列定時/過程更不可預測,隨機長度的隨機鹽被添加到兩者中。

我的這種實現是這樣的:

function hmac_verify ($hash_original, $message, $key) { 

    $hmac_salt = '...'; // was added at the original HMAC signing 
    $random_salt = openssl_random_pseudo_bytes (rand(16,96)); 

    $raw_hash = hash_hmac('sha512', $message . $hmac_salt, $key, true); 
    $hash_compare = base64_encode ($raw_hash); // $hash_original is in base64 
    $hash_compare_safe = hash_hmac('sha512', $hash_compare, $random_salt, true); 
    $hash_original_safe = hash_hmac('sha512', $hash_original, $random_salt, true); 

    if ($hash_compare_safe === $hash_original_safe) return true; 
     else return false; 

} 

的函數被調用此方法,以驗證解密結果解密加密的文本之後:

if (!hmac_verify ($hmac_hash, $plaintext . $cipher_text, $key . $iv)) return "HASH ERROR"; 

這是否會成功地預防定時攻擊?我做了什麼不必要的事情?有什麼可以改進?

第二個問題是,對明文,密文還是兩者(如我的示例中)進行HMAC驗證以及爲什麼更明智。

+2

這個問題更適合[codereview.se],因爲這個代碼可能有效(沒有問題需要解決),CodeReview特別歡迎有關安全問題的問題。 –

+0

關於這一點的安全性,你可能會更好[crypto.se],從他們的幫助中心引用:「然而,你可能想把你的問題分解成細節,比如」在這些條件下,X結構期望的安全屬性Y?「,這對我們來說非常合適。」 – Vogel612

+0

@ Vogel612問題在於[crypto.se]通常不會處理有代碼的問題,因此可能會出現問題。這也是[security.se]也可能不是問這個問題的理由。 –

回答

1

我在閱讀您的功能時留下了一些內置評論。在閱讀整篇文章後,這不是一個分析,而是我在閱讀時立即想到的。

function hmac_verify ($hash_original, $message, $key) { 
    ## 
    # Nitpick: A variable named $hash_original will prime people who read 
    # your code to think of simple hash functions rather than HMAC 
    ## 

    $hmac_salt = '...'; // was added at the original HMAC signing 
    ## 
    # What is this? $hmac_salt? Looks like a hard coded-salt (a.k.a. pepper). 
    # I wouldn't trust this with my life. 
    ## 

    $random_salt = openssl_random_pseudo_bytes (rand(16,96)); 
    ## 
    # Why are you bothering to randomize this? Just use a static value 
    # approximating the output size of the hash function (i.e. 64). 
    ## 

    $raw_hash = hash_hmac('sha512', $message . $hmac_salt, $key, true); 
    $hash_compare = base64_encode ($raw_hash); // $hash_original is in base64 
    $hash_compare_safe = hash_hmac('sha512', $hash_compare, $random_salt, true); 
    ## 
    # Ah, yeah, don't pepper. HMAC is secure. 
    ## 
    $hash_original_safe = hash_hmac('sha512', $hash_original, $random_salt, true); 

    if ($hash_compare_safe === $hash_original_safe) return true; 
     else return false; 
    ## 
    # Why not just do this? 
    # return $hash_compare_safe === $hash_original_safe; 
    ## 

} 

所以,我會極力推薦了分離成兩個獨立的機制是:一,計算的MAC和比較字符串在固定時間內(如PHP 5.6的hash_equals()一樣)其他。

function hmac_verify ($hmac, $message, $key) 
{ 
    $calc = hash_hmac('sha512', $message, $key, true); 
    return hmac_equals($hmac, $calc); 
} 

function hmac_equals($hmac, $calc) 
{ 
    $random = openssl_random_pseudo_bytes(64); 
    return (
     hash_hmac('sha512', $hmac, $random) 
      === 
     hash_hmac('sha512', $calc, $random) 
    ); 
} 
+0

謝謝,這真的很有幫助。你不認爲胡椒粉對HMAC哈希值有用嗎? – az2014

+0

http://blog.ircmaxell.com/2015/03/security-issue-combining-bcrypt-with.html - Peppering通常被認爲是無用的。 –