我應該使用什麼來進行後續的 AES 密鑰派生?
我正在編寫一個小型聊天程序來探索密碼學中的一些方法和概念,目前我正在使用與 RSA 建立隧道的共享 AES 密鑰,進一步閱讀後發現模式選擇和概念本身存在許多缺陷。因此,在看了更多影片、文章和文章之後,我決定實現 2 個 ECDH 對,它們將用於派生 2 個不同的 AES-GCM 密鑰,這些密鑰將用於雙向消息加密。最重要的是,我想為每個請求實現一個密鑰派生,以便每條消息都使用從前一個派生而來的自己的密鑰進行加密。(同步問題將由協議處理)
由於初始 AES 密鑰不是人類密碼,而是一個高熵字元串(它消除了暴力破解),因此只需使用 SHA-256 對其進行散列並獲得新 AES 密鑰的種子的前 128 位以提高效率和易用性就足夠了利用?如果密鑰被洩露,這將阻止對先前消息的解密,這與每隔一段時間重新建立 ECDH 對的組合將在兩個時間方向上將洩露密鑰的威脅限制在最低限度。
編輯:
只是為了說清楚,因為我在這個問題上添加了太多上下文:我在問一個像 SHA-256 這樣的簡單雜湊函式是否會在雙棘輪中發揮 KDF 的足夠作用?
這是我將要使用的概念證明:https ://netnix.org/2015/04/19/aes-encryption-with-hmac-integrity-in-java
是的,通常您可以將雜湊用作“窮人的 KDF”。例如,看看關於 KDF1 和 KDF2 的 Q/A,它們只不過是美化的雜湊函式。當然,正如 e-sushi 所指出的,KDF 的理論要求比散列的要求要高一點。
一些區別:
- KDF 不只有一個輸入。除了輸入鍵控材料之外,它還可能具有諸如資訊之類的輸入,其中包含例如鍵的標籤、鹽和要生成的輸出材料的長度;
- KDF 的輸入應該是規範編碼的,否則可能對輸入參數有限制,使得不同的輸入組合永遠不會產生相同的輸出;
- 許多 KDF 的輸出是可配置的,並且可以擴展底層散列函式或分組密碼的輸出大小(取決於 KDF 是否支持擴展);
- KDF 的輸出通常是明確定義的,通常如果你想從 256 位散列中獲取 128 位,你會獲取最左邊的位,但是 KDF 會正式確定應該採用什麼輸出(是的,我見過奇怪的 /愚蠢的);
- KDF 的輸出應該是完全隨機的,理論上這不是散列函式的要求。
現在,例如 SHA-256 或 SHA-512 將具有與隨機無法區分的輸出,因此最後一點本質上主要是理論上的。所有其他差異都可以忽略或在您自己的雜湊函式中實現。所以是的,可以定義自己的 KDF。
但是,我建議您使用 KDF1,這樣您至少要符合所有這些設計選擇都已完成的現有 KDF。KDF1非常基本,似乎不提供規範編碼,因此您可能需要確保它
OtherInfo
具有靜態大小。最後,您仍然需要對雜湊進行一次呼叫。當然,基於 HMAC 的 KDF(例如 HKDF)會被認為更安全,因為在彈性方面幾乎沒有與 PRF(例如 HMAC)相匹配的原語。