在討論關于iOS應用簽名之前,我們需要先了解一個東西,叫做數(shù)字簽名
數(shù)字簽名
名詞解釋:因為老外喜歡用支票,支票上面的簽名能夠證明這玩意是你的。那么數(shù)字簽名顧名思義,就是用于鑒別數(shù)字信息的方法。
接下來我們思考一下.想要證明數(shù)字信息(也就是二進制數(shù)據(jù),計算機里面的任意數(shù)據(jù))的有效性,那么使用什么方式最合適呢?
我們可以想到有"信息指紋"之稱的HASH算法,在之前的文章中有講到HASH算法專門用來做文件數(shù)據(jù)的識別.那么在網(wǎng)絡數(shù)據(jù)傳遞的過程中,我們可以將明文數(shù)據(jù),和數(shù)據(jù)的HASH值一起傳遞給對方.對方可以拿出HASH值來進行驗證.
[圖片上傳中...(image.png-2d917e-1646570440545-0)]
但是在這個過程中,如何做到數(shù)據(jù)的保護呢?明文數(shù)據(jù)和HASH值如果直接傳遞就有都被篡改的風險.所以這里我們要對數(shù)據(jù)進行加密.明文數(shù)據(jù)有時會比較大,不適合使用RSA非對稱加密算法,那么數(shù)據(jù)的HASH值是比較小的.這個數(shù)據(jù)是用于校驗的,它完全可以使用RSA來加密.所以在數(shù)據(jù)傳遞的時候,我們將明文數(shù)據(jù)加上通過RSA加密的校驗數(shù)據(jù)一并傳遞給對方.那么這個通過RSA加密的校驗數(shù)據(jù),我們稱之為簽名.

數(shù)字簽名的驗證過程
當對方拿到數(shù)據(jù)之后,如何進行驗證呢?
首先傳遞數(shù)據(jù)時會將原始的數(shù)據(jù)和數(shù)字簽名一起發(fā)送
對方拿到數(shù)據(jù)后,先進行校驗.拿到原始數(shù)據(jù),通過同樣的HASH算法得到數(shù)據(jù)的HASH值.
然后通過非對稱加密,將數(shù)字簽名中的校驗HASH值解密出來.
最后對比兩個HASH值是否一致.這樣可以很好的判斷數(shù)據(jù)是否被篡改!

代碼簽名
代碼簽名是對可執(zhí)行文件或腳本進行數(shù)字簽名。用來確認軟件在簽名后未被修改或損壞的措施。和數(shù)字簽名原理一樣,只不過簽名的數(shù)據(jù)是代碼而已
在iOS出來之前,以前的主流操作系統(tǒng)(Mac/Windows)軟件隨便從哪里下載都能運行,系統(tǒng)存在安全隱患、盜版軟件、病毒入侵、靜默安裝等等。那么蘋果公司希望解決這樣的問題,要保證每一個安裝到iOS上的APP都是經(jīng)過蘋果官方允許的,那么怎么保證呢?就是通過代碼簽名。
如果要實現(xiàn)驗證,其實最簡單的方式就是通過蘋果官方生成的非對稱加密的一對公私鑰。在iOS系統(tǒng)中內(nèi)置一個公鑰,私鑰由蘋果服務器保存,我們傳App到App Store時,蘋果服務器用私鑰對App數(shù)據(jù)進行簽名,iOS系統(tǒng)下載這個App后,用公鑰驗證這個簽名,若簽名正確,這個App肯定是由蘋果服務器認證的,并且沒有被修改過,也就達到了蘋果的需求,保證了每個App都是經(jīng)過蘋果官方允許的。
如果我們的iOS設備安裝App只從App Store這一個入口安裝的話,那么這件事就很簡單的解決了,沒有任何復雜的東西,一個數(shù)字簽名搞定。
但是實際上iOS安裝還有其他的渠道,比如對于我們開發(fā)者iOSER而言,我們是需要在開發(fā)App時直接進行真機調(diào)試的,而且蘋果還開放了企業(yè)內(nèi)部分發(fā)的渠道,企業(yè)證書簽名的App也是需要順利安裝的。
蘋果需要開放這些方式安裝App,這些就無法通過簡單的代碼簽名來辦到了。
為了實現(xiàn)這些需求,iOS簽名的復雜度也就開始增加了,蘋果這里給出的方案是雙層簽名。
雙層代碼簽名
??iOS的雙層代碼簽名流程這里簡單梳理一下,這也不是最終的iOS簽名原理。iOS的最終簽名在這個基礎上還要稍微加點東西。
??首先這里有兩個角色。一個是iOS系統(tǒng),還有一個就是我們的Mac系統(tǒng)。因為iOS的APP開發(fā)環(huán)境在Mac系統(tǒng)下,所以這個依賴關系成為了蘋果雙層簽名的基礎。
雙向簽名的過程如下:
1、在Mac系統(tǒng)中生成一對公鑰和私鑰,這里稱為公鑰M和私鑰M。(M=Mac)

2、蘋果自己有固定的一對公鑰和私鑰,跟之前App Store原理一樣,私鑰在蘋果后臺,公鑰在每個iOS系統(tǒng)中。這里稱為公鑰A和私鑰A。(A=Apple)

3、把公鑰M以及一些開發(fā)者的信息,傳到蘋果后臺(這個就是CSR文件),用蘋果后臺里的私鑰A去簽名公鑰M。 得到一份數(shù)據(jù)包含了公鑰M以及其簽名,把這份數(shù)據(jù)稱為證書。

4、在開發(fā)時,編譯完一個App后,用本地的私鑰M(P12)對這個App進行簽名,同時把第三步得到的證書一起打包進App里,安裝到手機上。

5、安裝時,iOS系統(tǒng)進行2次簽名驗證:
- 通過系統(tǒng)內(nèi)置的公鑰A解密證書私鑰A獲取證書摘要,再驗證證書是否被篡改。
- 驗證證書后確保了公鑰M是蘋果認證過的,再用公鑰M去驗證App的簽名。

有了上面的過程,已經(jīng)可以保證開發(fā)者的認證,和程序的安全性了。 但是,iOS程序一般是通過App Store分發(fā)到用戶設備的。如果只有上述的過程,那豈不是只要申請了一個證書,就可以安裝到所有 iOS設備了?
蘋果這里給出的方案是授權文件。
描述文件
蘋果為了解決應用濫用的問題,又加上了一些限制:
- 蘋果后臺注冊過的設備才可以安裝。
- 簽名只能針對某一個具體的App。
- 蘋果還想控制App里面的iCloud、Push、后臺運行、調(diào)試器附加這些權限,所以蘋果把這些權限開關統(tǒng)一稱為Entitlements(授權文件)。將這個文件放在了一個叫做Provisioning Profile(描述文件)文件中,Xcode運行時會打包進入App內(nèi)。

在開發(fā)時,編譯完一個 App后,用本地的私鑰M對這個App進行簽名,同時把從蘋果服務器得到的描述文件打包進APP里,文件名為embedded.mobileprovision。App安裝到手機上后,系統(tǒng)將完成驗證工作。

我們可以利用$security cms -D -i embedded.mobileprovision命令查看Provisioning profile內(nèi)容,這些Xcode創(chuàng)建的Profile文件都存放在~/Library/MobileDevice/Provisioning Profiles/目錄下:

注意:每次我們新建項目其實會生成一個描述文件,選擇運行到手機上!我們只需要編譯一下,在APP包里面就可以看到。
整體的流程
首先我們總結一下剛才的一些名詞
-
證書:內(nèi)容是公鑰或者私鑰,由認證機構對其簽名組成的數(shù)據(jù)包!我們開發(fā)可以使用鑰匙串訪問看到
image P12:就是本地私鑰,可以導入到其他電腦
Entitlements:權限文件,包含了APP一些權限的plist文件
CertificateSigningRequest:CSR文件包含了本地公鑰的數(shù)據(jù)文件
Provisioning Profile:描述文件,包含了證書/Entitlements等數(shù)據(jù),并由蘋果后臺私鑰簽名的數(shù)據(jù)包.
流程如下:
第 1 步對應的是 keychain 里的 “從證書頒發(fā)機構請求證書”,這里就本地生成了一對公私鑰,保存的 CertificateSigningRequest 里面就包含公鑰,私鑰保存在本地電腦里.
第 2 步向蘋果申請對應把 CSR 傳到蘋果后臺生成證書.
-
第 3 步證書下載到本地.這時本地有兩個證書.一個是第 1 步生成的私鑰,一個是這里下載回來的證書,keychain 會把這兩個證書關聯(lián)起來,因為他們公私鑰是對應的,在XCode選擇下載回來的證書時,實際上會找到 keychain 里對應的私鑰去簽名.這里私鑰只有生成它的這臺 Mac 有,如果別的 Mac 也要編譯簽名這個 App 怎么辦?答案是把私鑰導出給其他 Mac 用,在 keychain 里導出私鑰,就會存成 .p12 文件,其他 Mac 打開后就導入了這個私鑰.
image 第 4 步都是在蘋果網(wǎng)站上操作,配置 AppID / 權限 / 設備等,最后下載 Provisioning Profile 文件。
第 5 步 XCode 會通過第 3 步下載回來的證書(存著公鑰),在本地找到對應的私鑰(第一步生成的),用本地私鑰去簽名 App,并把 Provisioning Profile 文件命名為 embedded.mobileprovision 一起打包進去。所以任何本地調(diào)試的APP,都會有一個embedded.mobileprovision(描述文件)從App Store下載的沒有.

APP簽名的數(shù)據(jù)
這里對 App 的簽名數(shù)據(jù)保存分兩部分
-
1.Mach-O 可執(zhí)行文件會把簽名直接寫入文件里
image 2.其他資源文件則會保存在 _CodeSignature 目錄下在APP包里。

至此關于iOS應用簽名的原理就介紹完了.下篇文章將介紹iOS應用重簽名技術.


