One-Time-Pad

如何使用相同的密鑰解密使用 XOR 加密的兩個圖像?

  • February 26, 2021

我正在嘗試解決CryptoHack的以下難題,其中涉及使用相同密鑰加密的兩個圖像:

我用相同的密鑰通過 XOR 隱藏了兩張很酷的圖片,所以你看不到它們!

如果我使用線上圖像比較工具比較這兩個圖像,我可以看到包含似乎是解決難題的新圖像的痕跡。但是,我認為這不是解決這個難題的預期方法。

所以我嘗試編寫一個程序來對兩個加密圖像進行異或運算,因為異或密鑰應該以這種方式抵消。我逐字節對這兩個文件進行異或運算,並將結果保存為 PNG 文件。但是這個新的 PNG 甚至無法打開——我的圖像查看器說它是一個有問題的文件。

這是我的 Python 程式碼:

from binascii import unhexlify

with open("lemur.png", mode='rb') as fl:
   lemur = fl.read()
   

with open("flag.png", mode='rb') as ff:
   flag = ff.read()

d = b''
for b1, b2 in zip(lemur, flag):
   d += bytes([b1^b2])

with open("new.png", mode='wb') as fn:
   fn.write(d)

我注意到的一件事是 lemur.png 文件比另一個長一個字節。上述程序在較小文件的長度處停止 XOR。我還嘗試將較大文件的最後一個字節附加到末尾。但即使這樣也無濟於事。

我的方法是否不正確,如果不正確,比較兩張圖像的正確方法是什麼?

PNG是一種壓縮圖像格式。這意味著,與BMPnetpbm等未壓縮格式不同,PNG 文件中儲存在磁碟上的字節與查看圖像時螢幕上顯示的實際圖像數據的字節不直接對應。

除了壓縮的圖像數據之外,PNG 文件還包含一個帶有獨特“簽名”字節序列的標頭,允許程序將文件辨識為 PNG 圖像而不管其名稱如何,以及幾個元數據塊儲存有關圖像的附加資訊,例如其寬度和高度,可能還有例如顏色配置文件。每個塊,包括實際的圖像數據塊,還包括一個CRC-32校驗和以驗證其正確性。

這一切意味著,如果您將一個 PNG 文件與其他東西(任何東西!)逐字節異或,或以任何其他方式直接修改其字節,結果幾乎肯定不是有效的 PNG 文件。如果修改非常小,一些圖像查看器可能仍會將文件辨識為 PNG 並嘗試顯示它,即使校驗和不匹配。但是,如果您對整個文件與另一個 PNG 文件進行 XOR 之類的操作,則結果甚至無法辨識為 PNG。

所以,鑑於:

  • 您收到的文件顯然是有效的 PNG 圖像文件,
  • 您得到的提示暗示它們在加密之前也是有效的圖像,並且
  • 提示說他們已經“用同一個鍵異或”,

這可能意味著什麼?

好吧,我只看到一種可能的可能性:必須通過使用(偽)隨機密鑰對原始 RGB 圖像數據進行異或運算來完成加密,然後才將生成的圖像保存為 PNG 格式。

因此,基本上,您需要做的是首先使用圖像載入庫將 PNG 圖像載入和解碼為 2D 像素值數組,然後將這些像素值異或在一起。然後,您要麼需要將 XORed 像素數據再次保存為 PNG(或其他圖像格式)以供查看,要麼讓您的程序直接在螢幕上顯示。

我將在 Python 中實際實現這一點作為練習。如果您對此部分有任何疑問,Stack Overflow是您的最佳選擇。

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