賽題介紹:
實現一個Linux下的二進制簽名和驗證程序,用於在國產Linux操作系統進行應用的標識和管理,提升應用程序的可追溯性和安全性鑑別能力。
場景:
流程要求開發者需對自己開發的應用進行簽名,以保證二進制的安全性(非篡改),因此需要一款可以對二進制進行簽名和驗證的程序。
需求分析:
對於Linux下給定的ELF可執行程序、自行開發簽名工具對程序的代碼段(Load Segment)首先進行散列,然後對散列值進行簽名,簽名數據應作為單獨的節(Section)附加到原ELF可執行程序的尾部。同時,應開發驗證軟件並加入操作系統,在運行任何ELF可執行程序前對ELF文件進行驗證,若ELF可執行程序沒有被簽名或者簽名驗證失敗則應停止運行本程序,若簽名驗證成功則可以正常運行。
簽名後的ELF可執行程序可正常運行在帶有簽名驗證的Linux操作系統上,以及不帶有簽名驗證機制的Linux操作系統上;
簽名後的ELF可執行程序中的簽名數據節應可通過readelf與objdump等程序解析得到正確的值;
運行ELF可執行程序的方式應保持不變,不得通過其他程序運行ELF可執行程序的方式驗證簽名;
簽名驗證所需要的公鑰、證書以及驗證程序可以預先設置在操作系統中;
本題不考察選手對加密算法的實現,因此選手可以選擇開源的加密軟件庫進行加密,但是對應強度應不低於RSA2048;
實現程序主要涉及對ELF可執行格式的理解、Linux操作系統下程序運行的機制的理解,以及對加密算法的運用。
原型設計:
①完成基於公私玥的簽名程序,能對任意ELF程序進行簽名,並能通過readelf等程序讀取添加的節,且不影響程序的正常運行。
②完成基於公私玥的驗證程序,能透明地對任意ELF程序在運行前進行簽名驗證。
③簽名驗證通過的可以正常運行,未通過的不允許運行,對比未實施簽名驗證前的程序啓動時間延遲不超過10%。
知識儲備:
ELF可執行文件:
ELF(Executable and Linking Format)是一種對象文件的格式,用於定義不同類型的對象文件(object files)中都放了什麼東西、以及都以什麼樣的格式去放這些東西。
目標文件在不同的系統或平台上具有不同的命名格式,在Unix和X86-64 Linux上稱為ELF(Executable and Linkable Format)。
ELF文件格式提供了兩種不同的視角,在彙編器和鏈接器看來,ELF文件是由Section Header Table描述的一系列Section的集合,而執行一個ELF文件時,在加載器(Loader)看來它是由Program Header Table描述的一系列Segment的集合。
.text就是其代碼段。
散列:
哈希表是根據設定的哈希函數H(key)和處理衝突方法將一組關鍵字映射到一個有限的地址區間上,並以關鍵字在地址區間中的象作為記錄在表中的存儲位置,這種表稱為哈希表或散列,所得存儲位置稱為哈希地址或散列地址。作為線性數據結構與表格和隊列等相比,哈希表無疑是查找速度比較快的一種。
通過將單向數學函數(有時稱為“哈希算法”)應用到任意數量的數據所得到的固定大小的結果。如果輸入數據中有變化,則哈希也會發生變化。哈希可用於許多操作,包括身份驗證和數字簽名。也稱為“消息摘要”。
簡單解釋:哈希(Hash)算法,即散列函數。它是一種單向密碼體制,即它是一個從明文到密文的不可逆的映射,只有加密過程,沒有解密過程。同時,哈希函數可以將任意長度的輸入經過變化以後得到固定長度的輸出。哈希函數的這種單向特徵和輸出數據長度固定的特徵使得它可以生成消息或者數據。
對消息的散列值進行簽名:
我們可以不必對整個消息進行加密(即對消息簽名),而是先用單向散列函數求出消息的散列值,然後在將散列值進行加密(對散列值簽名)就可以了。無論消息有多長,散列值永遠都是這麼短,因此對其進行加密(簽名)就非常輕鬆了。