代碼簽名
什么是代碼簽名
????代碼簽名是對可執行文件或腳本進行數字簽名,用來確認軟件的來源并保證在簽名后未被修改或損壞的措施。和數字簽名原理一樣,只不過簽名的數據是代碼而已.數字簽名使用非對稱加密和哈希函數來確保數據的完整性,可以用于識別和驗證簽名者。
代碼簽名的好處
- 確保一段代碼自簽名后未被更改。系統甚至可以檢測到最小的更改,無論是有意的(例如惡意攻擊者)還是意外的(例如文件損壞時)。當代碼簽名完好無損時,系統可以確定代碼與簽名者的預期相符。
- 將代碼標識為來自特定來源(開發人員或簽名者)。代碼簽名包括明確指向特定作者的密碼信息。
- 確定代碼對于特定目的是否值得信賴。除此之外,開發人員可以使用代碼簽名來聲明應用程序的更新版本應被系統視為與先前版本相同的應用程序。
蘋果簽名過程
證書和密鑰
-
CSR
文件
????通常,在開發使用的機器上應該已經有一個開發者證書,一個公鑰,以及一個私鑰。 這些是代碼簽名機制的核心。像 SSL 一樣,代碼簽名也依賴于采用 X.509 標準的公開密鑰加密。開發者通過 Key Chain 生成 CertificateSigningRequest(證書請求文件) 文件,這個文件里面包含了開發者的個人信息和公鑰,并且在申請時私鑰保存在本地。
CSR文件 -
CER
文件
????開發者將 CSR 文件上傳至蘋果網站提交給 Apple Worldwide Developer Relations Certification Authority(Apple WWDRCA)。Apple WWDRCA 會使用其根證書私鑰簽名生成了.cer
證書文件,這個證書里面包含了開發者的信息和公鑰,以及數字簽名。????在 OS X 上,X.509 的基本組成部分(例如證書等)都是由一個叫Key chain(鑰匙串訪問)的工具來進行管理。當下載 CER 文件安裝至鑰匙串時,鑰匙串會將這兩個證書進行關聯,要用一個證書設置代碼簽名,必須擁有私鑰,所有證書的私鑰都會被列在這里。 還有一種可以用來快速地顯示出系統中能用來對代碼進行簽名的認證的方法,那就是利用用途廣泛的命令行工具 security:
security find-identity -v -p codesigning
P12
文件
????當 CER 安裝到鑰匙串中,開發者將其導出為.P12
格式的文件,這個文件中不僅包含了公鑰信息,還有私鑰信息,以及數字簽名。
授權機制(Entitlements) 和 配置文件 (Provisioning)
????蘋果對 App 的 部分功能設定了權限開關,把這些權限開關統一稱為 Entitlements(授權文件),并且對安裝的設備(Device)做了限制,需要注冊的設備才可以 安裝,將AppId
、Device
、Entitlements
以及其他信息保存到了 Provisioning Profile(描述文件)文件中。
????當開發者下載 .mobileprovision
文件后雙擊運行,Xcode 通常會將其存放在 ~/Library/MobileDevice/Provisioning Profiles/
目錄中。開發者可以前往該目錄或者安裝 ProfilesManager.app
進行查看當前電腦下的描述文件。 可以通過下面命令查看下載后的描述文件信息:
security cms -D -i <mobileprovision文件路徑>
????通過查看后,我們可以發現 Provisioning Profile 文件其實是 plist 文件, 當然,Provisioning Profile文件也是經過服務器數字簽名的,所以它是防篡改的。
codesign
????蘋果對 App 簽名過程本身是由命令行工具 codesign
來完成的。通常,Xcode 會處理大多數代碼簽名任務,幫助管理代碼簽名身份,并將代碼簽名應用于構建和分發的應用程序。需要注意的是 Xcode 只允許在有限的選項中進行選擇,這些選項都是既擁有公鑰也擁有私鑰的證書。當然了,開發者也可以使用 codesign 工具進行手動簽名:
-
手動代碼簽名
codesign -s <身份> -v <代碼路徑>
-
檢查代碼簽名
codesign -v <代碼路徑>
-
獲取有關代碼簽名信息
codesign -d -r- <代碼路徑>
那么在簽名過程中,codeSign 做了什么呢?
????codesign 將 App 內的資源(包括可執行文件、資源、文件、嵌套代碼(Framework)等)在進行一次數字簽名,通過單向散列函數獲得哈希值,并用開發者的私鑰 M 對其進行加密,并將蘋果服務器生成的數字證書一起保存至 App 內。在 App 內可能包含不同的數字簽名:
- 如果代碼是通用的,則每個切片(架構)的目標代碼都是單獨簽名的。此簽名存儲在二進制文件 Mach-O 本身中。
- 應用程序包的各種數據組件(例如Info.plist文件,如果有的話)也被簽名。這些簽名存儲在
_CodeSignature/CodeResources
捆綁包中調用的文件中。 - 嵌入在應用程序中的嵌套代碼(例如Framework)本身是經過簽名的,并且它們的簽名也存儲在
_CodeSignature/CodeResources
包中。
App 安裝
????蘋果系統原本就持有 WWDRCA 的公鑰A,系統通過公鑰 A,對 App 內存放的蘋果服務器簽名過的數字證書進行驗證,查看是否經過蘋果官方許可,并對比 UUID 等信息,這里只驗證安裝行為是否正確。在通過證書內的開發者公鑰對代碼簽名進行驗證,這里驗證代碼的完整性。