這是一個好的溝通方案嗎?
我正在為聊天程序編寫一個包裝器,以允許端到端加密。我正在使用 Python 和 PyCrypto 來完成此任務。我想使用一個知名的圖書館來做到這一點,但據我所知,沒有一個可以做我正在尋找的東西。
這是握手協議的設計。
Alice 和 Bob 之前已經生成了長期 RSA-2048 密鑰 $ A $ 和 $ B $ 用於簽名。Alice 通過創建一個新的會話 RSA-2048 密鑰來啟動與 Bob 的加密連接 $ S $ . 愛麗絲標誌 $ [S_{public}, \text{“Alice”}] $ 和 $ A_{private} $ 使用 PSS 填充來獲取 $ Sig_A $ .
$$ [A_{public}, S_{public}, \text{“Alice”}, Sig_A] $$ 修訂:Alice 在簽名中包含她的身份。
旁注:生成新的 RSA-2048 密鑰是為了前向安全。我意識到生成新的 RSA-2048 密鑰效率低下,但我沒有使用 ECC 或 Diffie-Hellman 的好方法。
然後 Bob 驗證 $ Sig_A $ ,如果失敗則拒絕連接。鮑勃然後匹配 $ A_{public} $ 針對已知的可信密鑰列表。然後 Bob 生成一個隨機的 512 位共享密鑰 $ Sec $ 並用 $ S_{public} $ 使用 OAEP 填充獲取 $ EncSec $ . 鮑勃標誌 $ [EncSec, A_{public}, S_{public}, \text{“Alice”}, \text{“Bob”}] $ 和 $ B_{private} $ 使用 PSS 填充來獲取 $ Sig_B $ ,然後發送以下內容:
修訂: $ A_{public} $ , $ S_{public} $ ,並且雙方的身份都包含在 SigB 中。
$$ [B_{public}, EncSec, \text{“Bob”}, Sig_B] $$ 愛麗絲驗證 $ Sig_B $ ,如果失敗則拒絕連接。愛麗絲匹配 $ B_{public} $ 根據她自己的受信任密鑰列表。愛麗絲解密 $ EncSec $ 和 $ S_{private} $ 要得到 $ Sec $ .
修訂:愛麗絲標誌 $ [EncSec, B_{public}, \text{“Alice”}, \text{“Bob”}] $ 作為 $ Sig_C $ 並將其發送給 Bob。然後 Bob 驗證 $ Sig_C $ 如果連接失敗,則拒絕連接。
此時,每個使用者都會收到一條通知,顯示他們正在與之交談的人的指紋,以及他們是否已與已知的可信密鑰列表進行匹配。指紋生成為 $ SHA256(RSAPublicKey) $ 截斷為 16 個十六進製字元,每 4 個字元添加一個冒號。這個指紋可以通過一些難以欺騙的方法來驗證,例如電話。
Alice 和 Bob 現在已經驗證了彼此的身份並共享了一個秘密值。它們都像這樣導出加密和 MAC 密鑰。
$$ EncKey = HMAC_{SHA256}(“0”, Sec) $$ $$ MACKey = HMAC_{SHA256}(“1”, Sec) $$ 請注意,“0”和“1”都是長度為 1 的字元串,而不是文字數值 0 和 1。
加密和發送消息是這樣發生的。(假設 $ M $ 是消息,並且 $ Rand(x) $ 是一個密碼隨機數生成器,它返回 $ x $ 隨機位)
$$ IV = Rand(128) $$ $$ C = AES_{CFB}(M, EncKey, IV) $$ $$ MAC = HMAC_{SHA256}(IV || C, MACKey) $$ $ IV || C || MAC $ 然後傳送。在接收端, $ MAC $ 被檢查,如果失敗則拒絕該消息。否則,消息將被解密並顯示。
這有什麼問題嗎?(除了明顯的“不要推出自己的加密貨幣”,因為我在這里相當退縮)
這並沒有向竊聽者隱藏 Bob 的身份。
(OP 在聊天中提到 OP 並沒有嘗試這樣做。)
我無法再發現密鑰交換部分的任何其他問題。
應用程序級數據的加密/解密容易受到任意重放
和反射和丟棄的影響。 公共 MAC 輸入應指示方向和
message_number 以及
$$ number of messages received $$. 應該有一種單獨的方法
來安全地指示這三件事,而無需發送任何應用程序級消息,並且應該有一種方法來關閉通知,並安全地指示這三件事。