為了確保 iOS 平臺對 App 擁有絕對的控制權,不至出現盜版軟件盛行的局面,Apple 采取了簽名機制。
預備知識
1.非對稱加密算法
討論 iOS App 簽名機制之前,必須先了解一下非對稱加密機制。顧名思義,非對稱加密是相對對稱加密來說的,前者需要兩個密鑰,即私鑰和與之匹配的公鑰,用其中之一加密,必須用另一個解密;而后者只有一個密鑰,如下圖:
2.數字簽名
說完了非對稱加密,我們再來看看簽名是什么東東吧。簽名就表示認可,它的作用是對一份數據做一個標記,然后將這份數據發給接收方,接收方通過上邊的標記就可以確認這份數據是否曾被篡改過的?;镜暮灻膀炞C簽名過程如下:
首先,生成一對非對稱加密使用的密鑰 (公鑰+私鑰),私鑰留在服務端,公鑰發布出去;
然后,使用 HASH 算法 (最常用如 MD5) 得到原始數據的一個摘要,然后用私鑰加密這個摘要,加密后的數據即稱為原始數據的簽名,把它和原始數據一起發送給用戶;
最后,用戶接收到原始數據和簽名后,使用服務端發布出來的公鑰解密簽名,得到一個摘要 A。同時,用戶使用同樣的 HASH 算法生成原始數據的摘要 B,然后比較摘要 A 和 摘要 B,如果相等,說明數據未被篡改,否則,數據就被改動過。
補充:HASH 算法的特點是:①不可逆,即不能通過結果得到原始數據;②運算結果的長度固定,且比較短。
iOS App 的簽名機制
iOS App 目前有以下幾種安裝方式:
1.AppStore 下載的 App可以在手機上安裝。
2.開發過程中,可以直接 App 安裝進手機進行調試。
3.In-House 企業內部分發,可以直接安裝企業證書簽名后的 APP。
4.AD-Hoc 相當于企業分發的限制版,它限制了安裝設備的數量。
下面以前 2 種情況為例,討論一下 iOS App 的簽名機制。
1.AppStore
這種方式的實現比較簡單,由蘋果官方生成一對密鑰(public-key/private-key),公鑰 (public-key)內置到 iOS 設備里,私鑰(private-key)由蘋果服務器保存。
當我們往 AppStore 上傳 App 時,蘋果服務器會用私鑰(private-key)對 App 數據進行簽名,iOS 系統下載這個 App 后,用設備自帶的公鑰(public-key)驗證這個簽名,若簽名正確,說明這個 App 肯定是由蘋果認證的,并且沒有被修改過,這樣就保證了安裝的每一個 App 都是經過蘋果官方允許的。
補充:把 App 上傳 AppStore 后,蘋果還會對 App 進行加密。
2.開發階段
當開發 App 的時候,需要頻繁的安裝 App 到手機上,如果每次都先將 App 包傳給蘋果服務器,得到授權后才可以安裝,那對開發者來說簡直是災難,而事實上,蘋果也確實沒有這么做,而是可以直接安裝在手機上。
不過,蘋果依然要求對 App 的安裝有控制權,即:
① 必須經過蘋果允許才可以安裝;
② 權利不能被濫用,非開發狀態的 App 不允許安裝。
為了實現這些苛刻的要求,iOS 簽名的復雜度也就增加了,蘋果給出的解決方案是使用雙重簽名,大概流程見下圖:
在開發機器(如 iMac、MacBook Pro 及 Mac mini)上創建一個密鑰對 (公鑰 local / 私鑰 local)。即 通過 keychain 里邊的 “從證書頒發機構請求證書” 創建,私鑰存在本機,公鑰就是得到的 CertificateSigningRequest。
蘋果自己有固定的一個密鑰對 (公鑰 Apple / 私鑰 Apple),跟上面 AppStore 例子一樣,私鑰在蘋果服務端,公鑰在每個 iOS 設備上。
把公鑰 local 傳到蘋果服務端,用蘋果服務端的私鑰 Apple 去簽名公鑰 local,得到一份證書,其中包含了公鑰 local 及其簽名。
在蘋果后臺申請 AppID,配置好設備 ID 列表和 App 可使用的權限,然后將這些數據連同上一步獲得的證書一起用私鑰 A 簽名,把數據和簽名合成一個 Provisioning Profile 文件,即通常所說的 xxx.mobileprovision 文件,下載到本地的開發機器。
在開發時,編譯完一個 App 后,用私鑰 local 對這個 App 進行簽名,同時把上一步得到的? xxx.mobileprovision 打包進 App 里,文件更名為 embedded.mobileprovision,然后把 App 安裝到手機上。
在安裝時,iOS 系統取得證書,通過 iOS 設備內置的公鑰 Apple,去驗證 embedded.mobileprovision 的數字簽名是否正確。
如果上一步驗證簽名成功,就可以取出 embedded.mobileprovision 里面的數據,做各種驗證,具體包括:用公鑰 local 驗證 App 簽名,驗證當前 iOS 設備的 ID 是否在 設備 IDs 上,AppID 與當前 App 的 ID 是否對應得上,權限是否跟 App 里 Entitlements 的描述一致。
In-House 企業內部分發和 AD-Hoc 原理相似,只是企業內部分發不限制安裝的設備數量,另外需要用戶在 iOS 系統設置里邊手動點擊信任這個企業才能通過驗證。
以上就是我所了解的 iOS App 的簽名機制,其實只是個大概,還有許多細節可以深挖,以后再加吧!