反轉已知加密算法(4 字節重複密鑰 XOR)
我一直在為即將到來的 CTF 比賽練習,我終於達到了密碼學階段。我是這個領域的新手(我的知識本質上是 bcrypt 很棒,md5 很爛哈哈)。
這是挑戰:
This is my cipher algorithm: mysecretvalue = ???; mysecretmessage = ???; for (i=0;i<strlen(mysecretmessage);i++) { mysecretmessage[i] ^= ((mysecretvalue>>(8*(i%4)))&255); } echo strhex(mysecretmessage); and my output: e971de14d87fc406c67fc41ac570c3528a4ec216da7fc2168a78df018a70d50bde3ed31bcb72dc16c479d500863ee71ad07fc2178b3ee012d96dc71cd87a9007c53ec41bcf3ec31ade7b901ad93edd0ad97bd301cf6ac612c66bd553c3709017cf7dd91ecb729e53ed71df178a49df01c13f Decode it! ;)
我對解決此類挑戰的一般方法更感興趣,但是,如果您想以解決此問題為例,也將不勝感激!
PS 這是挑戰提供的所有資訊。我找不到名為 strhex 的函式,所以我認為它是虛擬碼,儘管它看起來與 Javascript 非常相似。
實際的“加密”是在這一行完成的:
mysecretmessage[i] ^= ((mysecretvalue>>(8*(i%4)))&255);
顯然,這條線對每個字節(或至少每個元素;但假設這確實是一個字節數組)與從字節計數器
mysecretmessage
派生的某個值進行異或。mysecretvalue``i
那麼表達式
((mysecretvalue>>(8*(i%4)))&255)
實際上返回了什麼?計數器
i
只出現在子表達式i%4
中,它將它除以 4 並返回餘數。所以從這裡我們已經可以看出,無論表達式可能在做什麼,它的值將每 4 個字節重複一次。所以我們正在尋找一個重複的 4 字節密鑰,當與下面以十六進制給出的字節序列進行異或運算時,將產生一個有意義的(因此可能是原始的)消息。(事實上,表達式的其餘部分
((mysecretvalue>>(8*(i%4)))&255)
所做的只是取一個 32 位整數mysecretvalue
並從中提取第i%4
-th 8 位字節。它通過mysecretvalue
逐8*(i%4)
位移動位來實現這一點,然後取按位與255 = 2 8 −1 = 11111111 2的二進制結果中提取其最低 8 位。)所以這基本上是使用 4 字節重複密鑰的 XOR 加密。如果您的消息正好是 4 個字節長,並且密鑰是隨機選擇的,那麼這將是一個牢不可破的一次性密碼。然而,由於消息比密鑰長,它變成了一個“多次填充”,很容易被破解。
有許多標準技術甚至自動化工具可以破解這種類型的重複密鑰加密。一種簡單的方法是將消息分成 4 個字節的段,獲取每個段的第一個字節,然後搜尋一個字節,當與這些字節中的每個字節進行異或時,產生大部分可列印的 ASCII 字元,頻率接近英文文本. 然後重複每個段的第二個字節,依此類推。
另一種方法是“嬰兒床拖”。基本上,你猜一個 $ n $ - 可能出現在明文消息中的字節序列(“嬰兒床”),並嘗試與每個連續的字節序列進行異或 $ n $ - 密文的字節子串。可能的英文文本包括最常見的用空格包圍的英文單詞,如“
the
”(5 個字節)、“and
”(5 個字節)、“that
”(6 個字節)等。每個位置的每個嬰兒床都會產生一個候選密鑰(或部分密鑰),然後您可以使用它來嘗試解密消息並查看結果是否有意義。(如果嬰兒床比預期的鑰匙長度長,您可以通過檢查候選鑰匙是否按預期重複來立即排除大多數位置。)這個過程也可以使用統計分析工具完全或部分自動化。
一旦你有了消息和重複的 4 字節密鑰,只需從右到左(因為加密程式碼從最低字節開始)以十六進制寫出密鑰字節,然後
mysecretvalue
如果你想要它,就會給你十六進制。