Symmetric

HMAC 是 HKDF 的合適替代品嗎?

  • April 17, 2018

我的PHP版本不包含該hash_hkdf()功能,升級版本對我的項目來說不值得麻煩(這是為了個人樂趣,而不是為了保護重要的私人數據)。鑑於沒有此功能,是否適合將hash_hkdf()功能替換為hash_hmac(),如下所示:

$k = hash_pbkdf2($ha, $pw, $s, $it, $kl, true);
$ek = hash_hmac($ha, "e", $k, true);`
$ak = hash_hmac($ha, "a", $k, true);`
$c = openssl_encrypt($pt, $cm, $ek, OPENSSL_RAW_DATA, $iv);`
$h = hash_hmac($ha, $iv.$s.$c, $ak, true);`
return base64_encode($iv.$s.$h.$c);`

HKDF 本身是由 HMAC 建構的,所以你的問題讓我覺得是一個錯誤的困境。如果你有 HMAC,HKDF 只是少數幾個 HMAC 呼叫;你可以實現你自己的。是的,我知道“不要自己動手”是最重要的密碼學建議,但與您在問題中說明的已經提議做的事情相比,自己實施 HKDF 只會略微增加風險. 閱讀 RFC應該可以幫助您說服自己。或者你可以考慮這個已經為你實現 HKDF 的第三方庫

並不是說您使用 HMAC 的方式有任何明顯錯誤,但我只是認為某些 PHP 版本中缺少 HKDF 不足以成為做出該決定的障礙。


一個更有趣的觀察是,您正在做的計算幾乎$ek$akHKDF-expand 的單塊應用程序相同(HKDF 的後半部分,實際上是兩個函式 - 閱讀 RFC)。您所做的與此不同,只是因為 HKDF-expand 在其info參數中附加了一個塊計數器字節。如果您更改子密鑰派生行以附加計數器字節:

$ek = hash_hmac($ha, "e\x01", $k, true);
$ak = hash_hmac($ha, "a\x01", $k, true);

…然後根據定義此相同(虛擬碼,因為 PHP 似乎沒有實際hkdf_expand功能):

$ek = hkdf_expand($ha, $k, $ha_output_size, "e");
$ak = hkdf_expand($ha, $k, $ha_output_size, "a");

…其中是所引用$ha_output_size的散列函式的輸出大小。$ha

HKDF 的另一個前半部分是 HKDF-extract 函式,其目的是獲取直接適合直接用作加密密鑰的隨機輸入,因為它們是有偏差的,並輸出一個主偽隨機密鑰(RFC 中的“PRK”術語),適用於直接使用或進一步派生。但是 PBKDF2 已經打算生成適合用作偽隨機密鑰的輸出,因此可以說您不需要 HKDF 提取步驟。

因此,總體而言,您所做的已經與您對 HKDF 所做的幾乎相同。這是一個論點,可用於繼續按您的方式進行操作(與 HKDF-expand 相比,缺少計數器字節不會破壞您的應用程序)或實際保留額外的字節,因此您實際上正在使用 HKDF。

只要您始終為每個鍵和目的傳遞不同的輸入,那麼是的,HMAC 的這種使用就可以了。HKDF 只是為一組結構化目的生成任意長度輸出的一種更方便的方法。對於底層雜湊函式的合理選擇,兩者都被推測為 PRF,並且在內部,HKDF 是由 HMAC 建構的,其結構化參數具有不同的編碼。

警告:我只是在解決您似乎正在呼叫的 HMAC 的使用問題,而不是解決有關您的 PHP 程式碼的任何其他問題。

也就是說:考慮使用更簡單的crypto_secretbox 身份驗證加密,如有必要,使用sodium_compat,而不是使用 PHP 中 OpenSSL 原語的鋒利邊緣來製作自己的方案?

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