具有雜湊函式的二進制韌體文件的完整性檢查
我需要提供一種機制,可以驗證在嵌入式系統上刷新的韌體映像的完整性。程序應該是,如果有人懷疑韌體的完整性,他可以通過調試埠 (JTAG) 讀取二進制映像,然後將其與公共可用的雜湊碼進行比較。
要求來自這樣一個事實,即該產品用於貿易交接應用,因此必須防止篡改(只有篡改檢測就足夠了)。應該有一種簡單的方法來驗證韌體,例如通過比較雜湊碼,列印在手冊中,並將其與計算的比較,從單個設備載入……
我的第一種方法是為此採用常用的 MD5 散列函式,也使其對客戶更方便(只有 16 個字節或分別為 32 個十六進製字元)。但後來我想起了過去幾年關於碰撞的一些新聞,MD5 甚至 SHA-1 (至少幾乎)被破壞了。因此,我想選擇具有最佳未來可行性的最新雜湊算法,因此我傾向於 SHA3-224(它包含 28 個字節或 56 個十六進製字元)。
我公司的一些同事對我說,MD5應該足以滿足我們的需求。但我不認為這是正確的,因為我們有一個 128 KiB 的韌體映像,只有大約 100 KiB 被使用,另外 28 KiB 可以包含“隨機數據”。因此,我想說,這足以創建至少一個具有相同程式功能的單一沖突。
出於此目的,SHA3-224 是過度殺傷還是就未來的可行性而言是否合理?
這似乎是xy 問題的一個範例。
目標是確保韌體不被修改。這個問題的標準解決方案是使用數字簽名。引用上一個連結的內容:
(數字)簽名使用私鑰創建,並使用非對稱密鑰對的相應公鑰進行驗證。只有私鑰的持有者可以創建這個簽名,通常任何知道公鑰的人都可以驗證它。
使用數字簽名,您的公司(並且只有您的公司)可以為韌體創建任何人都可以驗證的簽名。如果韌體被修改,那麼您創建的簽名將無法通過驗證程序。
應該有一種簡單的方法來驗證韌體,例如通過比較雜湊碼,列印在手冊中,並將其與計算的比較,從單個設備載入……
這並不是一種真正“簡單”的驗證方式——大多數使用者將無法/願意通過 JTAG 讀取二進製文件。
即使他們願意這樣做,仍然存在一個可能的攻擊向量:使用者可能只檢查是否 $ n $ 兩個雜湊的字元是匹配的,然後自然假設其餘的所有字元也是。在這種情況下,對手只需產生部分碰撞,這可能是一項更容易的任務。
最好不要依賴手動驗證。
您可以在設備中儲存您的公共驗證密鑰並將簽名儲存在韌體旁邊。當您的設備啟動時,它應該被設計為在繼續使用韌體之前自動驗證簽名。如果簽名沒有被驗證,那麼操作應該被中止。
RSA 在簽名方面很受歡迎*,因為驗證速度非常快(相對而言)。創建簽名並不是非常快,但由於很少需要完成,因此花費多長時間並不重要。
您可以使用SSL等程序來創建數字簽名,這可以在任何電腦上完成。
驗證常式必須在您的設備上執行,因此您的開發人員必須以某種方式整合該功能。可以重用現有庫的一部分,而不是從頭開始編寫驗證常式*。*如果可能的話,我建議使用/移植來自Bearssl的程式碼。
理想情況下,貴公司會將這部分開發工作外包給經驗豐富的密碼學工程師。如果可能的話,確保它正確完成是值得的。
*在大約十年內,由於量子計算和 NIST 的後量子密碼學競爭,您可能需要/想要更新您使用的簽名方案。