保護有限嵌入式系統之間的通信
我目前正在嘗試通過嵌入式系統上有限的物理通信通道加強通信。
情景
我認為該系統對於小型嵌入式應用程序來說是相當典型的:
- 所涉及的嵌入式系統是沒有任何作業系統的小型微控制器,可以假設它處於安全的物理環境中。攻擊者可以物理訪問連接通道,它們可以根據需要干擾消息。
- 可以使用不同的通信通道:例如 RS485 或 RS232。有一個粗略的協議可以處理諸如定址和粗略完整性(例如用於 bitflips 的 CRC16)之類的東西,我們可以在其上建構。把它想像成一個慢速 TCP。
- 每個通信夥伴都知道一個可以充當 CA 的根證書,並擁有一個由它簽名的自己的唯一證書(+密鑰)。證書是自簽名的,橢圓曲線 prime256v1
- mbedTLS 庫可用於這些系統(使用 DH、AES、..)。
- 大多數時候沒有可用的網際網路。
- 系統可以保持時間並可以創建足夠的隨機數
我想達到隱私、真實性和完整性。
如何解決
加密協議中的一條規則是永遠不要自己實現它們。不幸的是,我沒有找到與此案例匹配的任何內容。
我還瀏覽了現有問題,但沒有提供我正在尋找的完整解決方案。
最後,在這個答案中,實現自己的協議是最後一個選項。
這就是我想出下面描述的解決方案的原因——但我對此並不完全確定。我針對如何驗證 Diffie-Hellmann Key Exchange的這個答案,關於如何檢查完整性的這個答案和這個執行緒給了我一些關於如何實現這樣一個協議的想法。
安全通信協議
首先要做的是隨機生成一個對稱密鑰 K。首先發送的是握手消息。它具有以下欄位:
兩個設備都發送(和接收)這樣的消息。
收到消息後,將完成以下操作:
- 檢查證書是否由預期的 CA 簽名(必須在鏈中)
- 檢查 msg 是否使用 cert 及其密鑰正確簽名
當這些檢查成功時,發送和接收的 DH g K消息用於計算對稱密鑰。
從此時起,應用程序可以發送使用 AES-CBC 加密的消息。由於消息可能相對經常失去,IV 總是在消息中。
這是消息格式:
要接受一條消息,它必須
- 具有預期的 MsgIdNonce(最後收到的 1 或 2 個) - 防止重放攻擊,允許失去 1 條消息
- 擁有有效的 CMAC - 防止對完整性的攻擊
- 最多收到 最後一條消息後 T 秒 - 防止延遲攻擊
如果有任何不符合預期的情況,則再次發送握手,然後使用新交換的參數再次發送消息。
問題
我是在正確的道路上還是應該嘗試完全不同的東西?
這是否提供了我的安全目標,還是我在這裡錯過了任何明顯的漏洞?
這能行嗎?
希望您能幫助我和其他面臨類似問題的嵌入式工程師!
加密協議中的一條規則是永遠不要自己實現它們。不幸的是,我沒有找到與此案例匹配的任何內容。
你考慮過DTLS嗎?這試圖解決相同的問題(時間戳除外;可以通過在數據報中插入時間戳來添加),並且已經考慮了一些事情。另一種可能性是 IPsec。但是 DTLS 看起來更接近於解決您遇到的問題(除非您要保護的數據流量是 IP 流量)。
也就是說,以下是對您概述的協議的一些想法:
- 如果兩個連續的消息被丟棄(例如接收錯誤)會發生什麼?雙方會意識到發生了什麼,還是會繼續丟棄所有後續消息(因為’nonce 必須增加不超過 2’ 規則)?
- 假設他們嘗試重新生成密鑰,這是如何協調的?如果一方認為他們還沒有更新密鑰,而另一方認為他們是,那麼用舊密鑰加密的消息會發生什麼?我們發現在密文中包含“在哪個密鑰下加密”標籤通常很有用(在 DTLS 中,這是“紀元”)。
- 您的通信渠道可以重新排序消息嗎?我懷疑在您的情況下不能,但是如果可以,您應該考慮如何處理。
- 如果有人注入先前的(有效的)握手消息會發生什麼?這將如何混淆事情?
- 在數據加密路徑中,您使用 CBC 加密和 CMAC 完整性。雖然這是一個可行的解決方案,但如果沒有正確集成,很容易受到各種填充攻擊。目前的時尚是使用 AEAD 模式(例如 GCM 或 Chacha20/Poly1305),兩者兼而有之。
- 加密流量是單向的還是雙向的?如果流量是雙向的,您是否使用同一組密鑰來保護兩組流量?
- “如果有什麼不符合預期,再次發送握手,然後使用新交換的參數再次發送消息。” - 這是如何運作的?如果接收者決定它不喜歡該消息,那麼發送者如何知道要重新發送它?