正確使用密鑰和隨機數
我一直在研究 AES、GCM、CBC、HMAC 和許多其他原語,並且對它們有點(也許有點)熟悉,但是我仍然對密鑰和 nonce 的使用有點厭倦。
背景:
我有多個(嵌入式)設備(有時數百個),所有這些設備都連接到伺服器。這些設備將與 AES-CBC HMAC 或 AES-GCM 進行通信。使用 HMAC 時,我知道首先加密然後 MAC。此外,這些設備上還預裝了密鑰。
以下是我認為我知道的:
您可以擁有 1 個主密鑰,但 AES 和 HMAC 從不直接使用主密鑰
您應該使用 PBKDF2 之類的 KDF 來創建會話
您應該經常更改主密鑰
現在假設我們開始將設備連接到伺服器。設備和伺服器都具有相同的主密鑰,但它們必須就會話密鑰達成一致。除了使用 Diffie hellman 之外,我不能以任何其他方式做到這一點?簡單地為 PBKDF2 發送鹽是行不通的,因為攻擊者可能會改變它。
然後,當使用 CBC 時,我們創建一個隨機數作為 IV,我們加密消息,添加 IV,然後使用帶有會話密鑰的 HMAC,附加結果並將其發送過來。
使用 GCM 時,我們創建一個隨機數,加密文本,將隨機數附加到密文並發送過去,我們要麼繼續發送隨機數,要麼在兩邊都保留一個計數器,無論哪種方式,我們總是 +1 隨機數。
所以我的問題
**是:diffie hellman 是必須的嗎?**還是有其他方法可以做?請記住,我的處理器能力和記憶體非常有限,因此不能選擇使用帶有 RSA 的 PKI。
我描述的其他一切都正確嗎?
1 最後的評論,人們常說最好使用 2 個單獨的密鑰(1 個用於加密,1 個用於 HMAC)這只是意味著使用 DH 兩次
- 好吧,PBKDF 用於從密碼中獲取密鑰,如果您的主密鑰已經安全,則不需要它,只需使用類似 HKDF 的東西。(快點)
- ECDH 和 DH 無疑是協商會話密鑰時最安全的選項。當然,由於您確實有一個預先共享的主密鑰,因此您有一些有趣的新選擇。
- 您對 HMAC 的使用聽起來很安全。按照慣例,您可能希望將密文附加到 IV (-> $ IV||C $ 代替 $ C||IV $ ) 因為 IV 是 $ -1. $ 堵塞。
- 您對 nonce 的使用聽起來很安全。只要您不為同一個密鑰重複使用隨機數(您不這樣做),您就是安全的。
- 使用單獨的鍵意味著使用不共享已知關係的鍵(散列不計算在內)。所以你可以推導出 $ K_{MAC}=KDF(MS,“MAC”) $ 和 $ K_{Enc}=KDF(MS,“ENCRYPTION”) $ ,這將是非常安全的,您不必重新執行 DH。
現在解決您的會話密鑰問題:
它是一個非標準的對稱密鑰協商協議:
符號:
$ r_A,r_B,n_A,n_B $ 都是 64 字節的隨機數。$ E_K(X) $ 使用從預共享的主密鑰派生的密鑰表示 X 的經過身份驗證的加密。
- $ A $ 發送 $ B $ $ n_A $ . $ n_A $ 是一個隨機數,用於保證執行的新鮮度。
- $ B $ 回應 $ A $ 和 $ E_K(n_A||n_B||r_B) $ . $ A $ 驗證 $ n_A $ 是正確的並保存 $ r_B $ .
- $ A $ 最後回應 $ E_K(n_B||n_A||r_A) $ . $ B $ 驗證 $ n_A $ 和 $ n_B $ 是正確的。
現在雙方共享 $ r_A $ 和 $ r_B $ 因此可以使用這些值來生成會話密鑰(無需前向保密),使用標準 KDF。