iOS中的Code Signing體系非常復(fù)雜,對新手非常不友好,雖然目前網(wǎng)上已經(jīng)存在大量文章對此進(jìn)行比較透徹的分析,最核心的部分已經(jīng)講解得非常清楚,我閱讀了這些文章后,確實(shí)從中學(xué)習(xí)到不少知識,但我始終還是對Code Signing體系中很多相關(guān)的地方有著疑惑,于是決定認(rèn)真地探究一番。本文會引用一些比較好的文章中的內(nèi)容和圖片,加上一些我個人的理解進(jìn)行分析,有些內(nèi)容本文不再重復(fù),有需要的請閱讀本文最后的參考文章。
概念
公開密鑰加密、數(shù)字簽名、證書這些通用的基本概念這里不再多說,主要提一下iOS上特有的東西
.certSigningRequest
點(diǎn)擊mac OS的鑰匙串訪問里的 證書助理 -> 從證書頒發(fā)機(jī)構(gòu)請求證書,最后會創(chuàng)建出一個.certSigningRequest文件,其實(shí)這個過程就是創(chuàng)建了一對公私鑰
- 其中
.certSigningRequest文件保存著- 申請者信息申請者的公鑰
- 摘要算法
- 公鑰加密算法
- 私鑰保存在
keychain中
證書
AppleWWDRCA
iOS 以及 mac OS(在安裝 Xcode 時(shí))將自動安裝 AppleWWDRCA.cer 這個中間證書(Intermediate Certificates),它實(shí)際上就是 iOS(開發(fā))證書的證書,即根證書(Apple Root Certificate)。
iOS App Development
iOS的開發(fā)證書,在開發(fā)階段進(jìn)行真機(jī)測試時(shí)需要用到的證書??梢栽谔O果開發(fā)網(wǎng)站上手動創(chuàng)建,需要上傳.certSigningRequest文件;或者使用Xcode自動創(chuàng)建。
iOS Distribution
iOS的發(fā)布證書,可以用于進(jìn)行 Ad Hoc 測試、打包上傳到 App Store 或者打包成 Enterprisee(In-House) 類型供企業(yè)內(nèi)部使用。可以在蘋果開發(fā)網(wǎng)站上手動創(chuàng)建,需要上傳.certSigningRequest文件;或者使用Xcode自動創(chuàng)建。
.p12
在mac OS的鑰匙串訪問里選擇一張證書,右擊該證書,選擇導(dǎo)出"xxxxx",然后設(shè)置密碼,可以導(dǎo)出該證書對應(yīng)的.p12文件。.p12文件包含個人信息、公鑰和私鑰,也就是證書 + 私鑰。iOS類型的每種證書同時(shí)存在數(shù)量有限制,而證書是依靠mac OS上的.certSigningRequest文件創(chuàng)建的,所以正常情況下,每種類型的證書只能在有限的Mac電腦上使用,如果需要在更多不同的Mac電腦上進(jìn)行App開發(fā)、測試、簽名,可以導(dǎo)出對應(yīng).p12文件代替證書來使用。
Provisioning Profile
Provisioning Profile的文件格式為.mobileprovision,里面包含著
- 可以使用的證書
- App ID,由 TeamID 和 BundleID 組合而成,類似于
A1B2C3D4.com.domain.appName形式 - 可安裝該App的設(shè)備列表的UDID
- Entitlements,授權(quán)文件,列出了App可以進(jìn)行哪些行為
- 以上信息的簽名
在蘋果開發(fā)網(wǎng)站上手動創(chuàng)建,或者使用Xcode自動創(chuàng)建。
.ipa
.ipa文件是iOS上的App安裝文件,其實(shí)它只是一個壓縮包,等同于.zip格式,用mac OS自帶的歸檔實(shí)用工具可以直接對它解壓,可以看到里面的內(nèi)容
用于上傳App Store的.ipa文件
App Store下載的.ipa文件
對比兩種情況的.ipa文件,可以看出它里面最主要的是Payload文件夾,而Payload文件夾里面放的就是該App對應(yīng)的.app文件
.app
右擊.app文件,選擇顯示包內(nèi)容,可以看到里面的內(nèi)容
用于上傳App Store的.app文件
從App Store下載的.app文件
可以看出.app文件主要包含四個部分:
-
Mach-O格式的二進(jìn)制可執(zhí)行文件,這個是一個App最重要的文件,我們編寫的Objective-C、Swift代碼都被編譯在里面 - 資源文件,包括:
.bundle文件,.framework文件,.dylib文件,.nib文件,圖片文件,音視頻文件,字體文件等所有項(xiàng)目用到的文件 -
CodeResources,簽名信息 -
embedded.mobileprovision文件,或者entitlements文件- 對于沒有上傳App Store的
.app文件,里面會包含embedded.mobileprovision文件,沒有entitlements文件 - App Store下載的
.app文件,里面會包含.entitlements文件,沒有embedded.mobileprovision文件
- 對于沒有上傳App Store的
Code Signing
正常情況下(非越獄),所有App想要安裝到iOS設(shè)備上,只有以下幾種方法
- 非App Store
- 真機(jī)調(diào)試
- Ad-Hoc
- In-House
- App Store
無論是哪一種方法,都需要先把iOS項(xiàng)目編譯成.app文件,然后進(jìn)行簽名。按照慣例,需要分析一下Code Signing
非App Store
對于非App Store獲得的.ipa文件,需要嚴(yán)格復(fù)雜的簽名和驗(yàn)證流程
創(chuàng)建
.certSigningRequest文件,這時(shí)候會生成一對公私鑰,這里稱為公鑰L(L:Local),私鑰L。.certSigningRequest文件保存著公鑰LiOS以及mac OS上的AppleWWDRCA.cer證書保存的就是蘋果的公鑰A(A:Apple),而對應(yīng)的私鑰A則在蘋果的后臺在蘋果開發(fā)者網(wǎng)站上創(chuàng)建證書的時(shí)候,上傳
.certSigningRequest文件其實(shí)就是把公鑰L傳到蘋果后臺,用蘋果后臺里的私鑰A去簽名公鑰L,得到對應(yīng)的證書,把證書下載回來雙擊安裝,會跟對應(yīng)的私鑰L綁定一起保存在keychain中-
除了證書,還需要對應(yīng)的
Provisioning Profile。在蘋果開發(fā)者網(wǎng)站上:- 設(shè)置App的Bundle ID
- 設(shè)置可安裝該App的設(shè)備UDID
- 設(shè)置該App的權(quán)限
- 設(shè)置可以使用的證書
- 最后會使用
私鑰A把以上這些數(shù)據(jù)進(jìn)行簽名,組成一個Provisioning Profile,格式為.mobileprovision,下載回來雙擊安裝,會保存在~/Library/MobileDevice/Provisioning Profiles中,文件名為它的UUID
-
當(dāng)需要把一個App安裝在iOS設(shè)備上時(shí),都會先把iOS項(xiàng)目編譯打包成
.app文件,而打包成可安裝在iOS設(shè)備上的.app文件的前提是,設(shè)置該App的Provisioning Profile,最后使用合法的證書對源代碼編譯后的各種文件進(jìn)行簽名,步驟如下:- 用
mac OS里的公鑰A驗(yàn)證Provisioning Profile,獲取里面的信息 - 用
Provisioning Profile里面的信息驗(yàn)證App的Bundle ID是否對應(yīng),App的權(quán)限是否對應(yīng) - 用
公鑰A驗(yàn)證Provisioning Profile里面的證書,再判斷是否有其中一張證書在這臺Mac電腦里 - 如果上面的驗(yàn)證都通過了,則會從
mac OS的keychain中取出符合條件且最新創(chuàng)建的證書,拿到對應(yīng)的私鑰L- 如果有
.framework文件、.dylib文件、插件、watch目錄下的extension,對它們分別進(jìn)行簽名 - 把
Provisioning Profile改名為embedded.mobileprovision放在.app文件里面 - 使用
私鑰L對整個.app文件進(jìn)行簽名,得到簽名信息CodeResources也放會在.app文件里面
- 如果有
- 如果需要生成
.ipa文件,則會把.app文件放在Payload文件夾里,把Payload文件夾和一些其他信息文件(非必要),一起壓縮形成一個.ipa文件
- 用
-
把
.ipa文件或者.app文件安裝在iOS設(shè)備上時(shí)- 先使用iOS設(shè)備上的
公鑰A對.app文件里面的embedded.mobileprovision文件進(jìn)行驗(yàn)證,獲取里面的證書 - 再使用
公鑰A對embedded.mobileprovision文件里面存在的證書進(jìn)行驗(yàn)證,取出一張對應(yīng)的證書,得到公鑰L - 使用
公鑰L對.app里面所有簽名信息進(jìn)行驗(yàn)證,如果驗(yàn)證通過,證明該.app文件是完整合法,沒有被篡改的 - 獲取
embedded.mobileprovision文件里面的可安裝該App的設(shè)備UDID列表,判斷該iOS設(shè)備是否可以安裝 - 如果前面的驗(yàn)證都通過,則App會安裝在iOS設(shè)備上
- 先使用iOS設(shè)備上的
App Store
當(dāng)需要在App Store發(fā)布App時(shí),則先需要把.ipa文件上傳到App Store。蘋果會用一種非常簡單的方式進(jìn)行重新簽名,這是因?yàn)樵诎?code>.ipa文件上傳到App Store之前,會先進(jìn)行類似于上面步驟的一系列驗(yàn)證,只有通過驗(yàn)證才會上傳成功,所以這已經(jīng)進(jìn)行過一次復(fù)雜的驗(yàn)證,代表蘋果已經(jīng)認(rèn)同了這個.ipa文件,而用戶又是從App Store下載的,所以也保證了.ipa文件來源是權(quán)威的,最后只需要在用戶設(shè)備上進(jìn)行簡單的驗(yàn)證就可以
- 蘋果用
私鑰A對.app文件里面需要簽名的文件進(jìn)行重新簽名 - 用戶下載App Store上面的
.ipa文件進(jìn)行安裝時(shí),用iOS設(shè)備上的公鑰A對.app文件里所有簽名信息進(jìn)行驗(yàn)證,如果驗(yàn)證通過,則會安裝在iOS設(shè)備上
更多相關(guān)
以上就是Code Signing最核心的內(nèi)容,但在iOS開發(fā)中其實(shí)還有很多相關(guān)的概念,很多需要注意的地方,接下來會講解一下我個人的觀察和分析
蘋果開發(fā)者帳號體系
Apple Developer:直接在Apple Developer登錄,同意Apple Developer協(xié)議后的賬號,免費(fèi),只可以使用Xcode進(jìn)行真機(jī)調(diào)試,Xcode 7之后蘋果推出的功能
Apple Developer Program:分個人和組織類型,費(fèi)用都是每年 99 美元,可以使用Xcode進(jìn)行真機(jī)調(diào)試,打包Ad-Hoc測試,在App Store發(fā)布App
Apple Developer Enterprise Program:企業(yè)賬號,費(fèi)用是每年 299 美元,可以使用Xcode進(jìn)行真機(jī)調(diào)試,打包Ad-Hoc測試,打包In-House App,但不能在App Store發(fā)布App
不同安裝方式對應(yīng)的證書類型
- 非App Store
- Development(真機(jī)調(diào)試):iOS App Development
- Ad Hoc:iOS Distribution (App Store and Ad Hoc)
- Enterprise:iOS Distribution (In-House and Ad Hoc)
- App Store:iOS Distribution (App Store and Ad Hoc)
在iOS的項(xiàng)目中,只要不是運(yùn)行在模擬器上,都會涉及到開發(fā)者帳號、證書、Provisioning Profile這些概念。
免費(fèi)賬號的限制:
- 創(chuàng)建的
Provisioning Profile有效期只有7天 - 在7天內(nèi)最多注冊10個Bundle Id
- 只能同時(shí)注冊3臺iOS設(shè)備
- 在同一臺iOS設(shè)備上,只能同時(shí)安裝3個使用免費(fèi)賬號簽名的App。當(dāng)該設(shè)備上已經(jīng)存在3個App,則無法安裝任何免費(fèi)賬號簽名的任何App,就算是那3個App其中一個也不行,只能先把其中一個刪除
Automatic signing
在Xcode 7之前,只有加入到Apple Developer Program(即付費(fèi))才能進(jìn)行真機(jī)調(diào)試,Xcode 7之后蘋果推出了Automatic signing功能,只要在Xcode上登陸Apple ID,就會自動管理證書和Provisioning Profile,同時(shí)沒有加入Apple Developer Program的賬號也能進(jìn)行真機(jī)調(diào)試。
在使用Xcode的Automatic signing功能的時(shí)候,無論是什么類型的賬號,無論是直接Run進(jìn)行真機(jī)調(diào)試,還是Archive,Code Signing Identity只能選用iOS Developer,只會使用iOS App Development類型的證書簽名
如果不使用Automatic signing功能,則可以選擇使用的是iOS App Development或者iOS Distribution證書進(jìn)行簽名
勾選Xcode中的AutoMatically manager signing,選擇對應(yīng)的Team后,無論是加入Apple Developer Program的賬號(即付費(fèi)賬號)還是Apple Developer的賬號(即免費(fèi)賬號):
- 如果Xcode沒有幫該賬號自動生成過
iOS App Development類型的證書, 無論在蘋果后臺是否已經(jīng)存在其他iOS App Development類型的證書,都會生成一張新的iOS App Development類型證書,證書名稱的格式是:開發(fā)者賬號名稱(當(dāng)前Mac電腦名稱), 如:Brian Hui (Daniels的MacBook Pro),同時(shí)會保存在當(dāng)前Mac電腦的keychain中 - 免費(fèi)賬號無法進(jìn)入蘋果的管理證書后臺,但可以猜測出在蘋果后臺也會存在該證書
- 如果Xcode沒有幫該App的Bundle ID自動生成過對應(yīng)的
Provisioning Profile,就會使用上面那張證書生成一個Provisioning Profile,保存在~/Library/MobileDevice/Provisioning Profiles,但在蘋果后臺則不會存在這個Provisioning Profile - 如果在
鑰匙串訪問中刪除了那張證書,Xcode會提示你的賬號有iOS App Development類型的證書,但這臺電腦沒有安裝,需要先把那張證書Revoke,Revoke后會再次重復(fù)前面的步驟,生成新的證書和Provisioning Profile - 如果在
~/Library/MobileDevice/Provisioning Profiles里面,刪除了該Provisioning Profile文件,Xcode會馬上重新生成Provisioning Profile
在使用Xcode的Automatic signing功能的前提下,進(jìn)行Archive,然后Distribute App的時(shí)候,選擇非Development的選項(xiàng),再選擇AutoMatically manager signing
如果本地存在
iOS Distribution類型的證書,則會直接進(jìn)行重簽名如果沒有存在
iOS Distribution類型的證書,而蘋果的后臺有,則會告訴你,該賬號存在iOS Distribution類型的證書,但這臺電腦沒有安裝,請聯(lián)系創(chuàng)建人拿到備份(.p12文件)進(jìn)行安裝,當(dāng)你安裝了該證書(或者.p12文件),則會直接進(jìn)行重簽名如果沒有存在
iOS Distribution類型的證書,而蘋果的后臺也沒有,則Xcode會詢問你是否需要生成iOS Distribution類型的證書,如果選擇需要,則會自動生成iOS Distribution類型的證書,并且建議你保存在本地,證書名稱的格式是:Team Name, 如:Hutchison Telephone (Macau) Company Limited,同時(shí)使用這張證書生成一個Provisioning Profile,保存在~/Library/MobileDevice/Provisioning Profiles,但在蘋果后臺則不會存在這個Provisioning Profile
Xcode對Provisioning Profile的驗(yàn)證
Xcode怎么把App和證書、Provisioning Profile綁定在一起呢?什么時(shí)候需要一張新的證書,什么時(shí)候需要一個新的Provisioning Profile?
Bundle ID是App的唯一標(biāo)識,App和證書、Provisioning Profile綁定在一起,其實(shí)就是Bundle ID和證書、Provisioning Profile綁定在一起,兩種情況:
Automatic signing
Bundle ID與開發(fā)者賬號綁定。使用Automatic signing時(shí),選擇開發(fā)者賬號(Team)后,Xcode會根據(jù)開發(fā)者賬號去本地檢索是否存在該賬號對應(yīng)的Provisioning Profile,再驗(yàn)證是否存在與該Bundle ID匹配的Provisioning Profile,再根據(jù)Provisioning Profile去本地檢索是否存在對應(yīng)的證書,都驗(yàn)證通過,則會設(shè)置成功。如果不存在Provisioning Profile,則會判斷該Bundle ID是否已經(jīng)被其他賬號注冊,如果已經(jīng)被其他賬號注冊,則整個流程失敗,需要選擇對應(yīng)的賬號。如果該Bundle ID沒有被其他賬號注冊或者賬號已經(jīng)對應(yīng)上,則按照文章前面所說的步驟,最后生成Provisioning Profile。
沒有使用Automatic signing
需要手動選擇Provisioning Profile,當(dāng)選擇了其中一個Provisioning Profile時(shí),則會分別驗(yàn)證Bundle ID是否對應(yīng)、Provisioning Profile是否過期、是否存在對應(yīng)的證書、App的權(quán)限是否對應(yīng)、證書的類型和Code Signing Identity設(shè)置是否對應(yīng),如果都通過驗(yàn)證,則會設(shè)置成功。
結(jié)論
當(dāng)你使用一臺新的Mac電腦,進(jìn)行開發(fā)、調(diào)試、發(fā)布某個開發(fā)者賬號注冊的App時(shí),就需要一張新的證書(或者.p12文件);當(dāng)你使用新的證書或者新的App,就需要一張新的Provisioning Profile。一張證書對應(yīng)一臺Mac電腦,和一個開發(fā)者賬號里面所有App,而一個Provisioning Profile則是只能對應(yīng)一個App。
檢驗(yàn)Provisioning Profile是簽名的第一步,那如果Provisioning Profile通過檢驗(yàn),而Provisioning Profile里面又存在證書,為什么還需要單獨(dú)安裝證書呢?
答案是:Provisioning Profile里面證書的作用是驗(yàn)證本地是否有符合條件證書,并且在安裝App的時(shí)候使用其中一張證書里面的公鑰L來驗(yàn)證App的完整性和合法性。因?yàn)?code>Provisioning Profile里面是有多張證書的,所以無法確定用哪張證書對應(yīng)的私鑰L用來簽名,所以這些證書只能用于判斷Mac電腦里有沒有符合條件的證書,如果Mac電腦里有多張符合條件的證書,則默認(rèn)用其中最新的證書里面的私鑰L進(jìn)行簽名,這樣就可以限制了只有獲得符合條件的證書的Mac電腦,才能進(jìn)行簽名。
Mac電腦中證書的作用:1. 證明這臺電腦是合法的;2. 找到對應(yīng)的私鑰L來對.app文件進(jìn)行簽名
Provisioning Profile中證書的作用:1. 判斷這臺電腦是否可以進(jìn)行簽名,也就是判斷這個臺電腦的合法性;2. 安裝App時(shí)檢驗(yàn).app文件
Xcode的Build Configuration和Code Signing Identity
Xcode有Run、Archive、Test等幾種項(xiàng)目構(gòu)建方式,每一種可以指定不同的Build Configuration(默認(rèn)有Debug和Release),而在Code Signing Identity又需要指定每種Build Configuration對應(yīng)的配置,分別為iOS Developer和iOS Distribution,其實(shí)就是在設(shè)置Provisioning Profile的類型是開發(fā)的還是發(fā)布的
在使用Xcode的Automatic signing功能的時(shí)候,Code Signing Identity只能選擇iOS Developer,否則會報(bào)錯
Xcode的Run、Archive和Distribute App
Run和Archive的時(shí)候已經(jīng)對App完成簽名。如果設(shè)置的Provisioning Profile不是用于發(fā)布到App Store的,這時(shí)候把里面的.app文件打包成.ipa文件,可以利用Xcode或者其他工具直接安裝到指定的iOS設(shè)備上。而點(diǎn)擊Archives界面中Distribute App后,會再給你一次機(jī)會,選擇其他證書和Provisioning Profile進(jìn)行重簽名,用于將App發(fā)布到不同的渠道
iOS設(shè)備上打開App時(shí)的驗(yàn)證
把App安裝到iOS設(shè)備時(shí),需要經(jīng)過本文前面所說的驗(yàn)證,而打開App的時(shí)候,也需要驗(yàn)證:
使用付費(fèi)賬號生成的
Development和AD-Hoc類型的.ipa文件,安裝后打開對應(yīng)的App時(shí),不需要在iOS設(shè)備上進(jìn)行信任開發(fā)者操作,每次打開都會驗(yàn)證證書和Provisioning Profile是否被Revoke或者過期,如果驗(yàn)證不通過,則無法打開使用免費(fèi)賬號生成的
Development和企業(yè)賬號生成的Enterprise類型的.ipa文件,安裝后第一次打開App時(shí),需要在iOS設(shè)備上做額外的信任開發(fā)者操作,每次打開都會驗(yàn)證證書和Provisioning Profile是否被Revoke或者過期,如果驗(yàn)證不通過,則無法打開App Store下載的
.ipa文件,安裝后第一次打開App時(shí),會驗(yàn)證當(dāng)前登錄的App ID是否已經(jīng)購買該App,如果驗(yàn)證通過,則以后都可以正常打開,如果驗(yàn)證不通過則無法打開
重簽名
在完全了解iOS中的Code Signing體系后,除了可以讓你在日常開發(fā)中遇到證書、簽名等問題的時(shí)候解決起來得心應(yīng)手,還有一個重要的應(yīng)用就是重簽名。網(wǎng)上也有一大堆關(guān)于重簽名的文章,大多數(shù)都只是說了怎么操作,但是很少會解釋為什么要這樣操作。接下來我會結(jié)合本文前面的內(nèi)容詳細(xì)分析重簽名的原理。
原理
重簽名顧名思義,就是把
.ipa文件也就是.app文件進(jìn)行重新簽名。經(jīng)過前面的分析,iOS的Code Signing體系是依靠兩個文件來進(jìn)行簽名:證書和Provisioning Profile,它們是由蘋果后臺生成的,并且用私鑰A進(jìn)行簽名,所以重簽名的第一步就是需要準(zhǔn)備有效合法、由蘋果后臺生成的證書和Provisioning Profile,它們必須是相對應(yīng)并且沒有被修改過的。需要注意的是,如果這證書不是由你的Mac電腦去請求生成的,是它無法跟它里面公鑰L對應(yīng)的私鑰L綁定在一起,因?yàn)槟愕腗ac電腦里根本沒有對應(yīng)的私鑰L,所以這時(shí)候是需要它對應(yīng)的.p12文件,安裝.p12文件就會得到證書和對應(yīng)的私鑰L簽名的時(shí)候,會拿到
Provisioning Profile里面的信息驗(yàn)證App的Bundle ID是否對應(yīng),App的權(quán)限是否對應(yīng),所以要把進(jìn)行重簽名的App的Bundle ID改成跟Provisioning Profile記錄的一致。而App的權(quán)限則需要直接從Provisioning Profile中導(dǎo)出entitlements.plist文件,最后在重簽名的時(shí)候使用既然是對
.app文件進(jìn)行重簽名,那么最后就是需要準(zhǔn)備一個沒有被加密的.app文件。在App Store下載.ipa文件里面的.app文件都是被加密,被加密的.app文件無法進(jìn)行重簽名準(zhǔn)備工作已經(jīng)完成,現(xiàn)在就可以開始重簽名,步驟其實(shí)是跟初次簽名一樣的。首先把準(zhǔn)備好的
Provisioning Profile改名為embedded.mobileprovision放在.app文件中或者進(jìn)行覆蓋。使用準(zhǔn)備好的證書,對.framework文件、.dylib文件、插件、watch目錄下的extension分別進(jìn)行簽名,最后用證書和導(dǎo)出entitlements.plist文件再對整個.app文件簽名關(guān)于證書的類型和App的安裝限制:既然進(jìn)行了重簽名,那么這個App可以安裝的iOS設(shè)備就會受到使用的證書和
Provisioning Profile的限制,所以一般會使用企業(yè)賬號的發(fā)布證書和In House類型Provisioning Profile進(jìn)行重簽名,這樣就可以使App安裝在任何iOS設(shè)備上
步驟
- 準(zhǔn)備合法完整的證書(或者.p12文件)和
Provisioning Profile - 準(zhǔn)備一個已經(jīng)脫殼的
.app或者.ipa文件,其中Bundle ID要跟Provisioning Profile中的一致
// 在.app文件中,把Info.plist的Bundle ID改為 com.xxx.xxx
/usr/libexec/PlistBuddy -c 'Set :CFBundleIdentifier com.xxx.xxx' "Info.plist"
- 從
Provisioning Profile提取entitlements
// 從embedded.mobileprovision文件中提取出entitlements.plist權(quán)限文件
security cms -D -i embedded.mobileprovision > temp.plist
/usr/libexec/PlistBuddy -x -c 'Print :Entitlements' temp.plist > entitlements.plist
- 把
Provisioning Profile改名為embedded.mobileprovision放在.app文件中 - 使用準(zhǔn)備好的證書,對
.framework文件、.dylib文件、PlugIns目錄里的.appex文件、Watch目錄里的.app文件分別進(jìn)行簽名,最后用證書和導(dǎo)出entitlements.plist文件再對整個.app文件簽名
// 查看可用的證書
security find-identity -v -p codesigning
// 對.app內(nèi)部的.framework文件、.dylib文件、PlugIns目錄里的.appex文件、Watch目錄里的.app文件分別進(jìn)行簽名
codesign -fs 證書ID xxx.dylib
// 對.app文件進(jìn)行簽名
codesign -fs 證書ID --entitlements entitlements.plist xxx.app
- 查看新的簽名信息
codesign -d -vv xxx.app
- 打包成
.ipa文件
zip -r xxx.ipa Payload/
注意
- 正常情況下
.app的Bundle ID要跟Provisioning Profile中的一致,但實(shí)際操作發(fā)現(xiàn),就算Bundle ID不一致也可以正常安裝使用,但應(yīng)該存在一定的隱患,所以建議還是保持一致 - 重簽名的時(shí)候,為了方便,可以直接把
.app文件里面的PlugIns目錄、Watch目錄都刪除,一般情況下不會用到。但是為了項(xiàng)目的完整性,以防出錯,最好把它們也保留。PlugIns目錄的文件可以直接用證書分別對它們進(jìn)行簽名。而在微信里,Watch目錄里面是一個.app文件,我不確定是不是所有App都是如此,以微信為例,對它進(jìn)行簽名前,需要進(jìn)去打開內(nèi)部的Info.plist文件,把其中兩個值進(jìn)行修改,分別是:- WKCompanionAppBundleIdentifier,這個key對應(yīng)的值指定了Watch目錄的
.app文件用于哪個App,在微信中為com.tencent.xin,可以看出是跟微信的Bundle ID一樣,所以需要把它改為跟Provisioning Profile中的一致 - Bundle identifier,這個key對應(yīng)的值表示W(wǎng)atch目錄的
.app文件自己的Bundle ID,在微信中為com.tencent.xin.watchapp,可以看出它的前綴是微信的Bundle ID, 所以需要把它的前綴改為跟Provisioning Profile中的一致,后面的部分保持不變就可以 - 完成上面的修改后就可以用證書對Watch目錄里面的
.app文件簽名
- WKCompanionAppBundleIdentifier,這個key對應(yīng)的值指定了Watch目錄的
結(jié)語
以上就是我個人對Code Signing體系的觀察和分析,大家可以看到相關(guān)的東西很多,需要注意的地方也很多,我盡量地把這些細(xì)節(jié)都總結(jié)出來,而這方面官方文檔確實(shí)沒有寫得很詳盡(或許是我沒找到),所以很難把所有特性和表現(xiàn)都完全正確地總結(jié)出來,如果大家有發(fā)現(xiàn)文章中什么問題,請?jiān)谠u論中指出,我會及時(shí)驗(yàn)證、修改。
參考文章
iOS Provisioning Profile(Certificate)與Code Signing詳解