iOS-代碼簽名--蘋果代碼簽名的格式

1,代碼簽名

驗證代碼的“正確性”是計算機科學中最難的問題之一,目前沒有“完美”辦法能夠分析任意一段代碼,確定它是否是惡意的,而目前通常對代碼驗證的方法是數字簽名。

目前數字簽名用於驗證

驗證代碼來源:由簽名者的私鑰進行簽名,其他使用者可以用公鑰進行驗證。

驗證代碼的真實性:對代碼的任何修改都有可能破壞數字簽名。

代碼簽名不是蘋果獨創的,其他開發語言都在使用它,比如java。但是蘋果對於整個代碼簽名的解決方案在許多方面是相當具有創新性的,其中最重要的是與授權的整合、對額外的資源的簽名和確保在整個應用的生命週期中保持代碼的完整性

2,代碼塊中籤名

蘋果公司代碼塊格式是Mach-O,首先說明的是目前做數字簽名的算法是我們熟知的算法,主要是sha1,sha256等摘要算法。這些算法做摘要運算,算出散列值。

如果是要計算的代碼塊比較小,則會很快計算出簽名值。但是如果代碼塊超級大,這時候對整個二進制文件計算散列值來驗證代碼簽名,可能很耗費性能的操作。而且實際上整個代碼塊在運行時,並不是一起映射到內存中的,而可能是隻映射一部分。蘋果在代碼塊目前採取分頁處理(因爲分頁,所以也就有着管理這些分頁的代碼目錄),所以此時計算散列值是以每一個二進制頁來計算的。

如何計算--->使用sha1等摘要算法計算出散列值,然後再對散列值求散列值

如何存儲--->計算出的散列值一般位於文件的末尾,更進一步散列值由代碼目錄pagesize字段指定,並放置在代碼插槽中

如何驗證--->蘋果定義LC_CODE_SIGNATURE的加載命令,該加載命令遵循_LINKEDIT加載命令架構體,該結構體僅僅指向代碼簽名的位置和大小

codesign -d -vvvvv /xxx

可以用這個命令來查看代碼簽名,/xxx表示你要查看的代碼塊Mach-O文件

從macOS10.12/iOS11開始,蘋果是用sha256算法,取代了之前的sha1

3,其他資源的簽名

蘋果除了保護代碼塊外,其他plist、nib等資源也做了保護。

首先可以思考總結的是,姑且不管每個代碼頁計算出的散列值具體怎樣存儲在一個代碼插槽中的,但是基礎的原理咱們可以明曉。這個散列值大小加位置的結構體,肯定存放在代碼頁中的,按照蘋果4096的代碼分頁最起碼插槽是存在這4096個字節中的。

但是其他資源不同於代碼塊,比如一個nib資源,它本質不是代碼資源,也就是說上面那一套代碼插槽存儲散列值是不行的。是以蘋果爲了做這些資源文件的保護,設計出了特殊插槽。

特殊插槽:資源文件用了本身不具有的代碼插槽。

特殊插槽具體的特殊性:

1,特殊插槽的索引都是負數的,正常的代碼插槽索引都是正數的。這是蘋果爲了資源文件設計一種主動“溢出”的特殊索引,解決非代碼插槽的問題。

2,特殊插槽的數量是限定的,5個。正常的代碼插槽數量不固定,理論上沒有上限。但是特殊插槽不是,數量只有5個。而且這5個索引,每一個都有固定意義,比如-1索引綁定的是資源文件信息plist,-3是資源文件的散列值,-5嵌入在代碼簽名中的授權。

在特殊插槽中任何未使用的索引,都會用NULL進行填充

4,僞簽名ad-hot

如上面所說,蘋果可以完全控制iOS中每一個二進制文件,因此完全可以編譯一個封閉的各個二進制文件的散列值列表,並將其硬編碼到內核中,特別是AppleMobileFileIntegrity.kext的“信任緩存”中。而這種簽名被稱爲“ad-hot”簽名.

ad-hot簽名對持有證書的CMS二進制塊做了留空,通俗地說就是沒有證書了。因爲上述的代碼簽名的散列值存儲在緩存的內核擴展中,消除了對證書的需求,因此這些二進制驗證只需要找散列值就行。

ldid工具在tweak開發中通過用戶僞簽名。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章