歡迎訪問我的博客原文
不少果粉對 Apple 鐘情捌年,與它的純凈瓢娜、安全有很大關(guān)系礼预,我們發(fā)現(xiàn)在蘋果的設(shè)備上下載應(yīng)用時虏劲,不會出現(xiàn)觸發(fā)下載一系列垃圾軟件的情況褒颈,而且用戶可以明確 App 的來源——通過官方商店 AppStore 購買励堡、企業(yè)證書安裝還是 TestFlight 下載。為了防止盜版軟禁应结、病毒入侵、靜默安裝以及屏蔽其它不可控因素鹅龄,并確保每一個安裝到 iOS 設(shè)備上的應(yīng)用都是被官方允許的,蘋果設(shè)定了一套應(yīng)用簽名機制迎卤。
數(shù)字簽名
數(shù)字簽名玷坠,又稱公鑰數(shù)字簽名蜗搔,是只有信息的發(fā)送者才能產(chǎn)生的別人無法偽造的一段數(shù)字串八堡,發(fā)送者對要發(fā)送的數(shù)據(jù)打上簽名標(biāo)記,表示這份經(jīng)過認證不同,未被篡改的溶耘。
數(shù)據(jù)傳輸
下面模擬一下數(shù)據(jù)傳輸的過程:
假如發(fā)送方直接將原始數(shù)據(jù)明文傳輸給接收方時,數(shù)據(jù)非常不安全凳兵,極易被篡改;
為了提升安全性并同時簡化明文庐扫,可以對數(shù)據(jù)進行哈希算法處理,得到原始數(shù)據(jù)的摘要形庭,然后將摘要發(fā)送給接收方。但假如哈希算法被泄漏斟珊,依然存在數(shù)據(jù)被篡改的風(fēng)險富纸;
引入非對稱加密算法囤踩,對一份數(shù)據(jù)旨椒,用哈希算法計算出摘要后堵漱,再用 RSA 的私鑰加密摘要,得到原始數(shù)據(jù)的數(shù)字簽名示惊,發(fā)送方將數(shù)字簽名與原始數(shù)據(jù)一起發(fā)送給接收方愉镰。
我們將原始數(shù)據(jù)進行哈希加密涝涤、非對稱加密后的數(shù)據(jù)稱為數(shù)字簽名岛杀。
接收方拿到數(shù)據(jù)后,需要進行簽名驗證类嗤,來確保數(shù)據(jù)傳輸過程中,未被篡改货裹。
數(shù)字簽名驗證
簽名驗證的具體步驟如下:
接收方拿到數(shù)據(jù)后精偿,通過同樣的哈希加密處理原始數(shù)據(jù)弧圆,得到哈希值(摘要)笔咽;
再利用非對稱將數(shù)字簽名中的校驗哈希值(摘要)解密出來;
最后對比兩個哈希值是否一致拯田,判斷出數(shù)據(jù)是否被篡改甩十。
用一張圖還原數(shù)字簽名的完整過程:
再來看看如何利用數(shù)字簽名保證每個安裝到 iOS 上的 App 都被蘋果認證允許。
代碼簽名
代碼簽名就是對可執(zhí)行文件或腳本進行數(shù)字簽名侣监,用來確認軟件在簽名后未被修改或損壞的措施。它的原理和數(shù)字簽名類似窃爷,只不過把簽名的不是數(shù)據(jù),而是代碼吞鸭。
簡單的代碼簽名
假如 App 是只能從 App Store 上下載覆糟,那么它的驗證方式就比較簡單了。
由蘋果官方生成一對公私鑰滩字,在 iOS 系統(tǒng)中內(nèi)置一個公鑰,私鑰由蘋果后臺保存漓藕。
我們把 App 上傳到 App Store 時,蘋果后臺用私鑰對 App 數(shù)據(jù)進行簽名享钞,iOS 系統(tǒng)下載這個 App 后诀蓉,用公鑰驗證這個簽名,如果簽名正確則這個 App 肯定是由蘋果后臺認證的渠啤,并且沒有被修改或損壞。
但 iOS 設(shè)備安裝 App 并不只有 App Store 這一個渠道份名,比如開發(fā)者的真機調(diào)試妓美、TestFlight 內(nèi)測、In-House 企業(yè)證書分發(fā)等壶栋,此時簡單的代碼簽名就無法滿足對 App 的完全驗證了。
iOS 代碼簽名的復(fù)雜度需要相應(yīng)增加委刘,于是雙層代碼簽名(雙重簽名)產(chǎn)生了。
雙層代碼簽名
“雙層”意在用兩對公私鑰做加密驗證呕童,它們分別是 Mac 本地的一對和 Apple 服務(wù)提供的一對。
雙層代碼簽名的存在是為了滿足:
- App 需要經(jīng)過蘋果允許才能安裝夺饲;
- 在 Apple 后臺中注冊過的設(shè)備才能安裝,比如在 TestFlight 內(nèi)測往声、真機調(diào)試模式下;
- 限制簽名只能對應(yīng)唯一的 App贯涎。
為了猜測完整的簽名流程,我們可以解壓一個 ipa 文件塘雳,在 Payload 目錄中有一個 embedded.mobileprovision
普筹,我們稱之為描述文件,它對應(yīng)的是 Apple 后臺生成 Provisioning Profile
(簡稱 PP)文件太防。文件中包括:
- 證書(公鑰、簽名)
- App ID
- Entitlements(權(quán)限)
- 注冊設(shè)備列表
- 其它關(guān)乎 App 能否正常啟動的所有信息
所以我們猜測簽名的大概流程是這樣的:
在開發(fā)設(shè)備 Mac 上本地生成一對公私鑰盈包。
Apple 有一對公私鑰,Apple 私鑰在 Apple 后臺呢燥,Apple 公鑰在每臺 iOS 設(shè)備上寓娩。
把 Mac 公鑰上傳到 Apple 后臺,用 Apple 私鑰簽名 Mac 公鑰棘伴,可以得到一份 Mac 公鑰和簽名的組合數(shù)據(jù),我們把這份數(shù)據(jù)稱為證書焊夸。
在 Apple 后臺申請 App ID,配置好的 UDID(注冊設(shè)備) 列表以及 App 申請的權(quán)限(Entitlements)饭冬,再加上步驟3中的證書揪阶,組合起來的數(shù)據(jù)用 Apple 私鑰進行簽名,把數(shù)據(jù)和簽名一起組成 PP 文件鲁僚,下載到本地的開發(fā)設(shè)備 Mac 上裁厅。
當(dāng)我們編譯工程時侨艾,Mac 私鑰會對 App 進行簽名执虹,同時把步驟4得到的 PP 文件打包進去唠梨,文件名為
embedded.mobileprovision
,準(zhǔn)備將 App 安裝到手機上。安裝時愿棋,iOS 系統(tǒng)取得證書,通過系統(tǒng)內(nèi)置的 Apple 公鑰才睹,去驗證證書里的簽名是否正確。
繼續(xù)用 Apple 公鑰驗證描述文件是否正確琅攘。
用 Mac 公鑰驗證 App 簽名是否被篡改松邪。
上面的步驟對應(yīng)到實際操作和概念是這樣的:
第 1 步:Mac 上依次打開“鑰匙串訪問 → 證書助理 → 從證書頒發(fā)機構(gòu)請求證書...”,做了這一步剧辐,就會在本地生成了一對公私鑰,導(dǎo)出的 CSR 文件(CertificateSigningRequest.certSigningRequest
)就是 Mac 公鑰荧关,Mac 私鑰也是存儲在本地褂傀,具體是什么文件看第 3 步。
第 2 步:每臺 iOS 設(shè)備中都已經(jīng)有了 Apple 公鑰仙辟,至于 Apple 私鑰是什么,看第 3 步参萄。
第 3 步:在 Apple 后臺的 iOS Certificates 模塊煎饼,通過上傳本地導(dǎo)出的 CSR 文件校赤,生成 .cer
證書文件马篮,也就是 Apple 私鑰怜奖。將 .cer
證書下載到本地,安裝證書歪玲,在鑰匙串中找到證書,就可以導(dǎo)出 Mac 私鑰滥崩,也就是一個 .p12
文件。它和第 1 步中導(dǎo)出的 Mac 公鑰是對應(yīng)的蜂科,鑰匙串會把這兩個證書關(guān)聯(lián)起來短条。用.cer
證書去簽名 CSR 文件,拿到含有簽名的證書茸时。
第 4 步:在 Apple 后臺配置 App ID、Entitlements可都、Devices 等,然后下載 PP 文件命斧。
第 5 步:編譯 App 時嘱兼,Xcode 會通過第 3 步下載回來的證書(存著 Mac 公鑰),在本地找到對應(yīng)的 Mac 私鑰芹壕,然后用 Mac 私鑰去簽名 App,同時打包通孽,安裝包中包含 PP 文件睁壁,在 ipa 中的文件名是 embedded.mobileprovision
互捌。這里 App 的簽名數(shù)據(jù)被分為兩部分,Mach-O 可執(zhí)行文件會把簽名直接寫入描述文件里秕噪,而資源文件則會保存在 _CodeSignature
目錄下厚宰,這時準(zhǔn)備安裝 App。
第 6 步:使用 Apple 公鑰驗證描述文件簽名铲觉,對應(yīng)第 4 步,簽名通過灯荧,說明證書可用并齐,進入下一步客税。
第 7 步:使用 Apple 公鑰驗證證書簽名况褪,對應(yīng)第 3 步,簽名通過测垛,說明 Mac 公鑰合法秧均,進入下一步。
第 8 步:使用 Mac 公鑰驗證 App 簽名目胡,對應(yīng)第 4 步,上述驗證均通過后眉尸,還需要將描述文件中的內(nèi)容與 App 本身的信息做驗證對比巨双,比如驗證設(shè)備 ID 是否在 UDID 列表上噪猾,App ID 是否相同筑累,權(quán)限開關(guān)是否與 Entitlements 一致,都驗證通過坪蚁,就可以開始安裝 App。
前面說了迅细,雙層代碼簽名是針對開發(fā)測試包、In-House 企業(yè)簽名湘换、Ad-Hoc 包為例的簽名和驗證的流程统阿,只是企業(yè)簽名不限制安裝的設(shè)備數(shù),因此描述文件中不會有設(shè)備列表扶平,而是一條 <key>ProvisionsAllDevices</key><true/>
記錄。
而從 App Store 上下載的安裝包哥谷,里面是沒有描述文件的,但上架之前還是要配置證書们妥、PP 文件勉吻,因為 App ID 和權(quán)限的檢驗還是需要做的。但 App 上傳到 AppStore 以后就跟 PP 文件沒有關(guān)系了齿桃,所以我們可以理解為 App Store 上包的簽名驗證采用就是前面說的最簡單的簽名方式,Apple 后臺直接用私鑰簽名 App 就可以了带污。