使用穩定加密逐行加密文本文件
我想以一種安全的方式儲存文件(即,沒有密鑰,任何人都不應該能夠解密文件的內容),但我還想要一個 diff 工具能夠告訴我哪些行發生了變化(假設你可以’不通過查看哪些行已更改來了解有關文件內容的任何資訊)。
這個想法是單獨加密每一行並將結果轉換為十六進製或BASE64,然後將每一行寫入一個文件。具有特定內容的行應始終返回相同的輸出,無論它在文件中的什麼位置。
具體來說,我想要一個像 Git 或 Mercurial 這樣的版本控制工具能夠有效地將文件作為文本處理。同時,(自行編寫的)UI 應該能夠顯示解密的差異,而無需解密版本控制工具內部的數據(
git diff
將顯示行號,然後我可以在我的應用程序中解密以顯示它們我)。那可能嗎?你知道我在哪裡可以找到更多資訊如何做到這一點?
是的,這是可能的。像你建議的那樣獨立加密每一行是要走的路。
您很可能希望對每一行獨立使用對稱加密算法——即每行有一個新的唯一 IV/nonce。這是最簡單的實現。但是,這意味著每行最多長 128 位。如果你不能忍受,你實際上必須犧牲一些安全性(例如使用沒有語義安全性的ECB 模式)或者對一條線路的更改也會影響附近的線路。
要考慮的一個問題是是否使用經過身份驗證的加密來防止攻擊者能夠修改文件。這通常是要走的路,但如果你有一些東西可以在你的設置中確保更高級別的完整性(比如簽名標籤/送出),你可以跳過它。
對於經過身份驗證的加密,您需要進一步決定是否要為整個文件使用一個 MAC(速度較慢,因為每次修改後都需要重新計算)還是每行一個(佔用更多空間)。
在實踐中,我會使用 AES 進行加密。(128 位或 256 位密鑰 -在實踐中並不重要。)
- 如果您可以忍受它所需的額外空間,那麼從實現的角度來看(當您有支持它的庫時)絕對最簡單的方法是在GCM 模式下使用 AES 。您可以將加密和身份驗證合二為一,IV 的唯一要求是唯一性。每行最多可長 256 位(當 IV 和 auth. 標籤都使用 128 位時)。
- 如果您已經進行了身份驗證,我會選擇 AES CTR。如果你知道文件永遠不會有更多 $ 2^k $ 在其生命週期中的行(計算每行的每個版本)你可以儲存一個 $ k $ - 每行的位值,而不是完整的 128 位 IV。您需要確保在任何情況下都不會重複使用計數器值,包括文件的不同“分支”。
- 如果您需要文件的 MAC,您可以執行上述操作並附加 HMAC。
您最好使用普通文件加密來加密文件,然後加密文件附帶的差異,除了差異中包含的行號。您還可以提前從差異中提取行號更改。否則,您將必須跟踪行,並確保用於每行的隨機數保持相同。
此外,由於加密/解密的性質,微小的變化(例如縮進)將導緻密文的巨大變化。即使您使用諸如 CTR 模式加密之類的東西,您也必須使用不同的 nonce 重新加密更改的行。
無論如何,你當然會傳達很多關於明文的資訊,但如果你想對密文進行差異分析,這或多或少是固有的。
總而言之,這可能比您乍看之下想像的要難。