Aes

如何處理大文件的經過身份驗證的加密?

  • October 23, 2016

首先我需要提一下,我不能使用 BouncyCastle 來實現這個解決方案。

我必須將文件加密到文件系​​統中。這些文件不會通過網路傳輸到任何其他位置。它們只會儲存在伺服器中,供安裝在那裡的應用程序以後使用。文件系統可能會或可能不會在作業系統級別加密,但這是我不能指望的。

我的文件將是大文件(例如從幾百兆到幾 GB)。它們將定期創建,因此我可以預期它們的數量會越來越多。此外,有時這些文件中的一些將被刪除,因為它們可能不再需要,而其他一些時候文件將保留多年。

我已經使用 256 位密鑰和 I/O 密碼流使用 AES/CBC/PKCS5Padding 進行了加密。我沒有認證的想法。

我認為我不能假設只加密而不使用身份驗證是安全的因為我猜伺服器可能被黑客入侵並且文件被盜。

此外,通過閱讀幾個 問題,很明顯沒有身份驗證只是我不應該想到的事情。

那麼我在這裡有什麼選擇呢?我看到 2 有一些利弊分析:

選項 1:AES/CBC + MAC(比如 SHA-256)

優點

  • 已經有加密部分工作
  • 由 Java 支持,無需額外的庫

缺點

  • 我必須處理 MAC 的計算
  • 我必須處理將mac附加到文件並稍後提取它
  • 我將不得不自己處理驗證。
  • 很多空間讓我無法做到這一點,我很害怕。

選項 2:使用 GCM 操作模式

優點

  • 忘記處理標籤計算/消息認證
  • 受 Java 支持(我使用的是 1.8,所以預設提供程序支持它)

缺點

  • 我發現有人不推薦它
  • 此外,這篇文章似乎暗示 Java8 的性能有點問題,但這是我尚未驗證的(更新: @archie 指出這里這裡確認了性能問題)。
  • 在 Java 1.7 中被嚴重破壞。我還沒有驗證它在 Java 1.8 中是否可以正常工作(更新: 此執行緒驗證 Java 8 中仍然存在問題)
  • 我正在使用單個對稱密鑰進行加密。我擔心如何管理隨機數,所以我不會破壞算法的安全屬性(我目前的實現在 Cipher 初始化後從cipher.getIV()獲取 IV 。我不確定這是否足夠好對於 GCM 或如果我需要採取其他特殊考慮。)

我提到的那些選項有效嗎?利弊分析呢?您還有其他建議嗎?你會選擇哪種方法?

如果您絕對不能使用其他庫,例如 Bouncy Castle,那麼您最好的選擇可能是添加一個 HMAC 身份驗證標籤(編寫 MacInputStream/MacOutputStream 將其連結到現有管道應該很容易)。

主要原因是 JDK 8(至少到 1.8.0_25)GCM 實現存在兩個問題,這使得它對於大文件不切實際:

  • 該實現在解密時緩衝整個明文(這是為了防止釋放未經身份驗證的明文,但會削弱密碼實現以供在安全協議中處理更高級別的使用)
  • 由於簡單的乘法器實現和 GCM 計算沒有硬體加速(JDK 8 中的 AES 是 AES-NI 加速且非常快,但 AES/GCM 完全由破碎的GCM 性能)。有實現硬體加速的意圖,並且已經有第三方送出來提高性能,但這些還沒有發布。

如果您使用 AES/CBC + HMAC 選項,您還需要確保您有獨立的加密密鑰和 Mac(例如,使用 HKDF 之類的東西從單個主密鑰生成兩個密鑰)。

如果您可以使用 Bouncy Castle(如果您的限制是不能使用其他 JCE 提供程序,即使使用輕量級 API),那麼其中的 OCB、GCM 和 EAX 實現將為您提供更好的性能(並帶走一堆手冊擺弄你將不得不使用 HMAC 方法)。

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