HMAC 是 HKDF 的合適替代品嗎?
我的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
與$ak
HKDF-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 原語的鋒利邊緣來製作自己的方案?