Initialization-Vector

使用 AES GCM 進行確定性加密 - 如何選擇 IV(隨機數)

  • October 31, 2017

我在密碼學方面沒有很大的背景,所以我希望這些問題不是很愚蠢。我不想重新發明輪子,我只是在尋找有關如何建構以下內容的最佳實踐的建議。

我已經尋找和閱讀了幾個小時,但沒有找到任何滿足我擔憂的答案。因此,我提出了一個解決方案,我希望得到一些回饋。

問題

我想為敏感資訊的確定性加密提供無狀態的微服務。其中一些資訊(即:個人辨識號)可能會用作數據庫中的主鍵,這就是密文需要確定性的原因。

該微服務將具有 oauth2 模式,因此它將是加密和解密的唯一點。根本不會有密鑰共享。

不同的應用程序將呼叫此服務來加密敏感資訊,在其他人之間共享它,並且在某些時候,另一個具有正確憑據的應用程序會要求對其進行解密。

API虛擬碼:

encrypt (sensitiveInfo: String): String
decrypt (ciptherTextStruct: String): String

注意事項

  1. 使用 AES-GCM,IV 必須是唯一的
  2. IV 必須與密文一起返回
  3. IV 不應該是明文的散列,因為它們不提供機密性。
  4. 密文將在一個結構中返回(其中將包含一個用於密鑰輪換的密鑰“版本”)

建議的解決方案

基本上,我認為 IV 是另一個密文:

mail (input) +--> hash() --> IV        \
            +--> mail   --> PlainText |-> Cipher text 1 (C1)
password (secret) ---------> Key       /

然後:

Cipher text 1 (C1) --> IV        \
mail ----------------> PlainText |-> Cipher text 2 (C2)
password (secret)  --> Key       /

最後,該方法encrypt (sensitiveInfo: String): String會返回一個C1+C2的結構體(可能是一個json結構體),該方法decrypt (ciptherTextStruct: String): StringC1從該結構體中取出,用作IV,C2以及秘鑰,並按預期返回明文。

回饋

我擔心在這張照片中沒有看到關於玩 C1 和 C2 的任何資訊披露。

**編輯:**我也可以使用第二個 IV 作為 的散列C1,這樣就不可能在 C1 和 C2 之間播放。

我很確定我是在重新發明輪子,所以我非常感謝一些幫助,了解哪種方法是最好的。

謝謝!

您提出的解決方案大部分都會起作用。您唯一需要更改的是,在計算時使用不同的鍵 $ C1 $ 和 $ C2 $ . 兩個密鑰都可以從一個共同的主密鑰派生,但它們不能相同。

不過,您的解決方案有點複雜。將確定性 IV 計算為純文字的 MAC(以及附加數據,如果有的話)會容易得多。

把這些放在一起,我的建議是:

加密

輸入值: $ S $ (密碼), $ M $ (資訊)

$ MK = scrypt(password), K_1 = HKDF(MK, “IV Key”), K_2 = HKDF(MK, “Enc Key”) $

$ IV = MSB_{96}(HMAC(K_1, M)), C=ENC(K_2, IV, M) $

返回值: $ IV, C $

解密

輸入值: $ S $ (密碼), $ C $ , $ IV $

$ MK = scrypt(password), K = HKDF(MK, “Enc Key”) $

$ M = DEC(K, IV, C) $

返回值: $ M $

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