Hash

我可以用 HMAC 和安全雜湊算法構造一個可行的流密碼嗎?

  • December 16, 2017

我已經從安全雜湊算法和 HMAC 構造了一個流密碼。以下是該算法的簡要說明:

讓:(實際上是 Objective-C 風格的虛擬碼)

  • [data SHA512Hash]: 的 SHA-512 雜湊data
  • [data SHA512HMAC:key]: SHA-512 HMAC data,key
  • [data xor:another]:兩個具有相同長度的按位異或dataanother
  • [data bytesTo:index]: 的第一個index字節data
  • [data removeFirstBytes:count]: 從,中刪除第一個count字節data
  • [data length]: 長度data
  • [data concat:other]: 連接otherdata
  • [Data new]: 分配一個空緩衝區。

虛擬碼:(或實際的 Objective-C 程式碼?)

Data hkey = [key SHA512]; // Hash to make lengths match.
Data segKey = [IV SHA512];

Data dest = [Data new]; // This will be the output
Data last = (Some constant)

do {
   // Cut off hash-sized chunks of source data
   Data segment = [data bytesTo:[hkey length]];
   [data removeFirstBytes:[hkey length]];

   // Derive a new segment key
   segKey = [segKey SHA512HMAC:hkey]; // or [segKey SHA512HMAC:[hkey concat:last]]? If so, how to decrypt?

   // XOR
   last = [segment xor:[segKey bytesTo:[segment length]]] // Truncates to make length match
   dest = [dest concat:last];
} while ([data length] > 0)

從其他一些問題中,我建議這是在 OFB 模式下執行的 SHA-512 HMAC,但是程式碼註釋的變化呢?

當給定相同的密鑰時,此程式碼似乎會自行破譯。

這是公式形式的算法,對於非客觀 C 專家來說可能更容易理解:

加密:

  • $ P_1 \mathbin\Vert P_2 \mathbin\Vert \dots \mathbin\Vert P_n := P $ (將明文分成塊,大小與雜湊輸出相同,除了最後一個)
  • $ K := \operatorname{SHA256}(\mathit{key}) $
  • $ O_0 := \mathit{IV} (= K) $
  • $ O_i := \operatorname{HMAC}{\operatorname{SHA256}}(K, O{i-1}) $ 對全部 $ i \in { 1, \dots, n} $ (密鑰流)
  • $ C_i := P_i \oplus O_i $ 對全部 $ i \in { 1, \dots, n} $ (通常的流密碼 XOR)
  • $ C := C_1 \mathbin\Vert \dots \mathbin\Vert C_n $

(最後一個塊在哪裡 $ O_n $ 被截斷以匹配 $ P_n $ )

解密:相同,但有 $ C_i $ 和 $ P_i $ 交換了。

  • $ P_i := C_i \oplus O_i $ 對全部 $ i \in { 1, \dots, n} $

如您所說,這是帶有 HMAC-SHA-512 的輸出回饋模式 (OFB),其密鑰被用作 IV。(您命名的值IV- $ K $ 這裡 - 實際上是有效密鑰,由原始密鑰通過 SHA-256 派生,IV 是你的第一個segkey,初始化為相同的值)。

如果您使用帶註釋的變體

  • $ O_i := \operatorname{HMAC}{\operatorname{SHA256}}(K \mathbin\Vert C{i-1}, O_{i-1}) $ ,

你有一些新模式,就像密碼回饋模式和輸出回饋模式的混合,它使用密碼回饋作為密鑰的一部分(?)。它不再是同步流密碼,因為密鑰流取決於先前的密文。你仍然可以解密它,你只需要在解密函式中使用之前版本的segment而不是之前版本的last作為輸入(即你的程序中需要一個變數)。

如果你想保持既定的操作模式,這裡是密碼回饋模式(CFB)

  • $ O_i := \operatorname{HMAC}{\operatorname{SHA256}}(K, C{i-1}) $

這是計數器模式(CTR)

  • $ O_i := \operatorname{HMAC}_{\operatorname{SHA256}}(K, i) $

ECB、CBC、PCBC 的類似物不適用於 MAC(或其他 PRF,如密鑰散列),因為解密不需要逆向。

此外,正如 Ivella 所說,您的流密碼比專用流密碼慢得多,或者與應用於分組密碼的模式相同。

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