iOS App 簽名的原理
iOS 簽名機(jī)制挺復(fù)雜嫌褪,各種證書(shū),Provisioning Profile胚股,entitlements笼痛,CertificateSigningRequest,p12琅拌,AppID缨伊,概念一堆,也很容易出錯(cuò)进宝,本文嘗試從原理出發(fā)刻坊,一步步推出為什么會(huì)有這么多概念,希望能有助于理解 iOS App 簽名的原理和流程党晋。
目的
先來(lái)看看蘋(píng)果的簽名機(jī)制是為了做什么谭胚。在 iOS 出來(lái)之前,在主流操作系統(tǒng)(Mac/Windows/Linux)上開(kāi)發(fā)和運(yùn)行軟件是不需要簽名的未玻,軟件隨便從哪里下載都能運(yùn)行灾而,導(dǎo)致平臺(tái)對(duì)第三方軟件難以控制,盜版流行扳剿。蘋(píng)果希望解決這樣的問(wèn)題旁趟,在 iOS 平臺(tái)對(duì)第三方 APP 有絕對(duì)的控制權(quán),一定要保證每一個(gè)安裝到 iOS 上的 APP 都是經(jīng)過(guò)蘋(píng)果官方允許的庇绽,怎樣保證呢轻庆?就是通過(guò)簽名機(jī)制癣猾。
非對(duì)稱(chēng)加密
通常我們說(shuō)的簽名就是數(shù)字簽名,它是基于非對(duì)稱(chēng)加密算法實(shí)現(xiàn)的余爆。對(duì)稱(chēng)加密是通過(guò)同一份密鑰加密和解密數(shù)據(jù)纷宇,而非對(duì)稱(chēng)加密則有兩份密鑰,分別是公鑰和私鑰蛾方,用公鑰加密的數(shù)據(jù)像捶,要用私鑰才能解密,用私鑰加密的數(shù)據(jù)桩砰,要用公鑰才能解密拓春。
簡(jiǎn)單說(shuō)一下常用的非對(duì)稱(chēng)加密算法 RSA 的數(shù)學(xué)原理,理解簡(jiǎn)單的數(shù)學(xué)原理亚隅,就可以理解非對(duì)稱(chēng)加密是怎么做到的硼莽,為什么會(huì)是安全的:
選兩個(gè)質(zhì)數(shù) p 和 q,相乘得出一個(gè)大整數(shù)n煮纵,例如 p = 61懂鸵,q = 53,n = pq = 3233
選 1-n 間的隨便一個(gè)質(zhì)數(shù)e行疏,例如 e = 17
經(jīng)過(guò)一系列數(shù)學(xué)公式匆光,算出一個(gè)數(shù)字 d,滿(mǎn)足:
a.通過(guò) n 和 e 這兩個(gè)數(shù)據(jù)一組數(shù)據(jù)進(jìn)行數(shù)學(xué)運(yùn)算后酿联,可以通過(guò) n 和 d 去反解運(yùn)算终息,反過(guò)來(lái)也可以。
b.如果只知道 n 和 e贞让,要推導(dǎo)出 d周崭,需要知道 p 和 q,也就是要需要把 n 因數(shù)分解喳张。
上述的 (n,e) 這兩個(gè)數(shù)據(jù)在一起就是公鑰续镇,(n,d) 這兩個(gè)數(shù)據(jù)就是私鑰,滿(mǎn)足用私鑰加密蹲姐,公鑰解密,或反過(guò)來(lái)公鑰加密人柿,私鑰解密柴墩,也滿(mǎn)足在只暴露公鑰 (只知道 n 和 e)的情況下,要推導(dǎo)出私鑰 (n,d)凫岖,需要把大整數(shù) n 因數(shù)分解江咳。目前因數(shù)分解只能靠暴力窮舉,而 n 數(shù)字越大哥放,越難以用窮舉計(jì)算出因數(shù) p 和 q歼指,也就越安全爹土,當(dāng) n 大到二進(jìn)制 1024 位或 2048 位時(shí),以目前技術(shù)要破解幾乎不可能踩身,所以非常安全胀茵。
若對(duì)數(shù)字 d 是怎樣計(jì)算出來(lái)的感興趣,可以詳讀這兩篇文章:RSA 算法原理(一)(二)
數(shù)字簽名
現(xiàn)在知道了有非對(duì)稱(chēng)加密這東西挟阻,那數(shù)字簽名是怎么回事呢琼娘?
數(shù)字簽名的作用是我對(duì)某一份數(shù)據(jù)打個(gè)標(biāo)記,表示我認(rèn)可了這份數(shù)據(jù)(簽了個(gè)名)附鸽,然后我發(fā)送給其他人脱拼,其他人可以知道這份數(shù)據(jù)是經(jīng)過(guò)我認(rèn)證的,數(shù)據(jù)沒(méi)有被篡改過(guò)坷备。
有了上述非對(duì)稱(chēng)加密算法熄浓,就可以實(shí)現(xiàn)這個(gè)需求:
首先用一種算法,算出原始數(shù)據(jù)的摘要省撑。需滿(mǎn)足 a.若原始數(shù)據(jù)有任何變化赌蔑,計(jì)算出來(lái)的摘要值都會(huì)變化。 b.摘要要夠短丁侄。這里最常用的算法是MD5惯雳。
生成一份非對(duì)稱(chēng)加密的公鑰和私鑰,私鑰我自己拿著鸿摇,公鑰公布出去石景。
對(duì)一份數(shù)據(jù),算出摘要后拙吉,用私鑰加密這個(gè)摘要潮孽,得到一份加密后的數(shù)據(jù),稱(chēng)為原始數(shù)據(jù)的簽名筷黔。把它跟原始數(shù)據(jù)一起發(fā)送給用戶(hù)往史。
用戶(hù)收到數(shù)據(jù)和簽名后,用公鑰解密得到摘要佛舱。同時(shí)用戶(hù)用同樣的算法計(jì)算原始數(shù)據(jù)的摘要椎例,對(duì)比這里計(jì)算出來(lái)的摘要和用公鑰解密簽名得到的摘要是否相等,若相等則表示這份數(shù)據(jù)中途沒(méi)有被篡改過(guò)请祖,因?yàn)槿绻鄹倪^(guò)订歪,摘要會(huì)變化。
之所以要有第一步計(jì)算摘要肆捕,是因?yàn)榉菍?duì)稱(chēng)加密的原理限制可加密的內(nèi)容不能太大(不能大于上述 n 的位數(shù)刷晋,也就是一般不能大于 1024 位 / 2048 位),于是若要對(duì)任意大的數(shù)據(jù)簽名,就需要改成對(duì)它的特征值簽名眼虱,效果是一樣的喻奥。
好了,有了非對(duì)稱(chēng)加密的基礎(chǔ)捏悬,知道了數(shù)字簽名是什么撞蚕,怎樣可以保證一份數(shù)據(jù)是經(jīng)過(guò)某個(gè)地方認(rèn)證的,來(lái)看看怎樣通過(guò)數(shù)字簽名的機(jī)制保證每一個(gè)安裝到 iOS 上的 APP 都是經(jīng)過(guò)蘋(píng)果認(rèn)證允許的邮破。
最簡(jiǎn)單的簽名
要實(shí)現(xiàn)這個(gè)需求很簡(jiǎn)單诈豌,最直接的方式,蘋(píng)果官方生成一對(duì)公私鑰抒和,在 iOS 里內(nèi)置一個(gè)公鑰矫渔,私鑰由蘋(píng)果后臺(tái)保存,我們傳 App 上 AppStore 時(shí)摧莽,蘋(píng)果后臺(tái)用私鑰對(duì) APP 數(shù)據(jù)進(jìn)行簽名庙洼,iOS 系統(tǒng)下載這個(gè) APP 后,用公鑰驗(yàn)證這個(gè)簽名镊辕,若簽名正確油够,這個(gè) APP 肯定是由蘋(píng)果后臺(tái)認(rèn)證的,并且沒(méi)有被修改過(guò)征懈,也就達(dá)到了蘋(píng)果的需求:保證安裝的每一個(gè) APP 都是經(jīng)過(guò)蘋(píng)果官方允許的石咬。
如果我們 iOS 設(shè)備安裝 APP 只有從 AppStore 下載這一種方式的話,這件事就結(jié)束了卖哎,沒(méi)有任何復(fù)雜的東西鬼悠,只有一個(gè)數(shù)字簽名,非常簡(jiǎn)單地解決問(wèn)題亏娜。
但實(shí)際上因?yàn)槌藦?AppStore 下載焕窝,我們還可以有三種方式安裝一個(gè) App:
開(kāi)發(fā) App 時(shí)可以直接把開(kāi)發(fā)中的應(yīng)用安裝進(jìn)手機(jī)進(jìn)行調(diào)試。
In-House 企業(yè)內(nèi)部分發(fā)维贺,可以直接安裝企業(yè)證書(shū)簽名后的 APP它掂。
AD-Hoc 相當(dāng)于企業(yè)分發(fā)的限制版,限制安裝設(shè)備數(shù)量溯泣,較少用虐秋。
蘋(píng)果要對(duì)用這三種方式安裝的 App 進(jìn)行控制,就有了新的需求垃沦,無(wú)法像上面這樣簡(jiǎn)單了客给。
新的需求
我們先來(lái)看第一個(gè),開(kāi)發(fā)時(shí)安裝APP栏尚,它有兩個(gè)個(gè)需求:
安裝包不需要傳到蘋(píng)果服務(wù)器起愈,可以直接安裝到手機(jī)上。如果你編譯一個(gè) APP 到手機(jī)前要先傳到蘋(píng)果服務(wù)器簽名译仗,這顯然是不能接受的抬虽。
蘋(píng)果必須對(duì)這里的安裝有控制權(quán),包括
a. 經(jīng)過(guò)蘋(píng)果允許才可以這樣安裝纵菌。
b. 不能被濫用導(dǎo)致非開(kāi)發(fā)app也能被安裝阐污。
為了實(shí)現(xiàn)這些需求,iOS 簽名的復(fù)雜度也就開(kāi)始增加了咱圆。
蘋(píng)果這里給出的方案是使用了雙層簽名笛辟,會(huì)比較繞,流程大概是這樣的:
在你的 Mac 開(kāi)發(fā)機(jī)器生成一對(duì)公私鑰序苏,這里稱(chēng)為公鑰L手幢,私鑰L。L:Local
蘋(píng)果自己有固定的一對(duì)公私鑰忱详,跟上面 AppStore 例子一樣围来,私鑰在蘋(píng)果后臺(tái),公鑰在每個(gè) iOS 設(shè)備上匈睁。這里稱(chēng)為公鑰A监透,私鑰A。A:Apple
把公鑰 L 傳到蘋(píng)果后臺(tái)航唆,用蘋(píng)果后臺(tái)里的私鑰 A 去簽名公鑰 L胀蛮。得到一份數(shù)據(jù)包含了公鑰 L 以及其簽名,把這份數(shù)據(jù)稱(chēng)為證書(shū)糯钙。
在開(kāi)發(fā)時(shí)粪狼,編譯完一個(gè) APP 后,用本地的私鑰 L 對(duì)這個(gè) APP 進(jìn)行簽名超营,同時(shí)把第三步得到的證書(shū)一起打包進(jìn) APP 里鸳玩,安裝到手機(jī)上。
在安裝時(shí)演闭,iOS 系統(tǒng)取得證書(shū)不跟,通過(guò)系統(tǒng)內(nèi)置的公鑰 A,去驗(yàn)證證書(shū)的數(shù)字簽名是否正確米碰。
驗(yàn)證證書(shū)后確保了公鑰 L 是蘋(píng)果認(rèn)證過(guò)的窝革,再用公鑰 L 去驗(yàn)證 APP 的簽名,這里就間接驗(yàn)證了這個(gè) APP 安裝行為是否經(jīng)過(guò)蘋(píng)果官方允許吕座。(這里只驗(yàn)證安裝行為虐译,不驗(yàn)證APP 是否被改動(dòng),因?yàn)殚_(kāi)發(fā)階段 APP 內(nèi)容總是不斷變化的吴趴,蘋(píng)果不需要管漆诽。)
加點(diǎn)東西
上述流程只解決了上面第一個(gè)需求,也就是需要經(jīng)過(guò)蘋(píng)果允許才可以安裝,還未解決第二個(gè)避免被濫用的問(wèn)題厢拭。怎么解決呢兰英?蘋(píng)果再加了兩個(gè)限制,一是限制在蘋(píng)果后臺(tái)注冊(cè)過(guò)的設(shè)備才可以安裝供鸠,二是限制簽名只能針對(duì)某一個(gè)具體的 APP畦贸。
怎么加的?在上述第三步楞捂,蘋(píng)果用私鑰 A 簽名我們本地公鑰 L 時(shí)薄坏,實(shí)際上除了簽名公鑰 L,還可以加上無(wú)限多數(shù)據(jù)寨闹,這些數(shù)據(jù)都可以保證是經(jīng)過(guò)蘋(píng)果官方認(rèn)證的胶坠,不會(huì)有被篡改的可能。
可以想到把 允許安裝的設(shè)備 ID 列表 和 App對(duì)應(yīng)的 AppID 等數(shù)據(jù)繁堡,都在第三步這里跟公鑰L一起組成證書(shū)涵但,再用蘋(píng)果私鑰 A 對(duì)這個(gè)證書(shū)簽名。在最后第 5 步驗(yàn)證時(shí)就可以拿到設(shè)備 ID 列表帖蔓,判斷當(dāng)前設(shè)備是否符合要求矮瘟。根據(jù)數(shù)字簽名的原理,只要數(shù)字簽名通過(guò)驗(yàn)證塑娇,第 5 步這里的設(shè)備 IDs / AppID / 公鑰 L 就都是經(jīng)過(guò)蘋(píng)果認(rèn)證的澈侠,無(wú)法被修改,蘋(píng)果就可以限制可安裝的設(shè)備和 APP埋酬,避免濫用哨啃。
最終流程
到這里這個(gè)證書(shū)已經(jīng)變得很復(fù)雜了,有很多額外信息写妥,實(shí)際上除了 設(shè)備 ID / AppID拳球,還有其他信息也需要在這里用蘋(píng)果簽名,像這個(gè) APP 里 iCloud / push / 后臺(tái)運(yùn)行 等權(quán)限蘋(píng)果都想控制珍特,蘋(píng)果把這些權(quán)限開(kāi)關(guān)統(tǒng)一稱(chēng)為 Entitlements祝峻,它也需要通過(guò)簽名去授權(quán)。
實(shí)際上一個(gè)“證書(shū)”本來(lái)就有規(guī)定的格式規(guī)范扎筒,上面我們把各種額外信息塞入證書(shū)里是不合適的莱找,于是蘋(píng)果另外搞了個(gè)東西,叫 Provisioning Profile嗜桌,一個(gè) Provisioning Profile 里就包含了證書(shū)以及上述提到的所有額外信息奥溺,以及所有信息的簽名。
所以整個(gè)流程稍微變一下骨宠,就變成這樣了:
因?yàn)椴襟E有小變動(dòng)浮定,這里我們不辭啰嗦重新再列一遍整個(gè)流程:
在你的 Mac 開(kāi)發(fā)機(jī)器生成一對(duì)公私鑰相满,這里稱(chēng)為公鑰L,私鑰L桦卒。L:Local
蘋(píng)果自己有固定的一對(duì)公私鑰雳灵,跟上面 AppStore 例子一樣,私鑰在蘋(píng)果后臺(tái)闸盔,公鑰在每個(gè) iOS 設(shè)備上。這里稱(chēng)為公鑰A琳省,私鑰A迎吵。A:Apple
把公鑰 L 傳到蘋(píng)果后臺(tái),用蘋(píng)果后臺(tái)里的私鑰 A 去簽名公鑰 L针贬。得到一份數(shù)據(jù)包含了公鑰 L 以及其簽名击费,把這份數(shù)據(jù)稱(chēng)為證書(shū)。
在蘋(píng)果后臺(tái)申請(qǐng) AppID桦他,配置好設(shè)備 ID 列表和 APP 可使用的權(quán)限蔫巩,再加上第③步的證書(shū),組成的數(shù)據(jù)用私鑰 A 簽名快压,把數(shù)據(jù)和簽名一起組成一個(gè) Provisioning Profile 文件圆仔,下載到本地 Mac 開(kāi)發(fā)機(jī)。
在開(kāi)發(fā)時(shí)蔫劣,編譯完一個(gè) APP 后坪郭,用本地的私鑰 L 對(duì)這個(gè) APP 進(jìn)行簽名,同時(shí)把第④步得到的 Provisioning Profile 文件打包進(jìn) APP 里脉幢,文件名為 embedded.mobileprovision歪沃,把 APP 安裝到手機(jī)上。
在安裝時(shí)嫌松,iOS 系統(tǒng)取得證書(shū)沪曙,通過(guò)系統(tǒng)內(nèi)置的公鑰 A,去驗(yàn)證 embedded.mobileprovision 的數(shù)字簽名是否正確萎羔,里面的證書(shū)簽名也會(huì)再驗(yàn)一遍液走。
確保了 embedded.mobileprovision 里的數(shù)據(jù)都是蘋(píng)果授權(quán)以后,就可以取出里面的數(shù)據(jù)贾陷,做各種驗(yàn)證育灸,包括用公鑰 L 驗(yàn)證APP簽名,驗(yàn)證設(shè)備 ID 是否在 ID 列表上昵宇,AppID 是否對(duì)應(yīng)得上磅崭,權(quán)限開(kāi)關(guān)是否跟 APP 里的 Entitlements 對(duì)應(yīng)等。
開(kāi)發(fā)者證書(shū)從簽名到認(rèn)證最終蘋(píng)果采用的流程大致是這樣瓦哎,還有一些細(xì)節(jié)像證書(shū)有效期/證書(shū)類(lèi)型等就不細(xì)說(shuō)了砸喻。
概念和操作
上面的步驟對(duì)應(yīng)到我們平常具體的操作和概念是這樣的:
第 1 步對(duì)應(yīng)的是 keychain 里的 “從證書(shū)頒發(fā)機(jī)構(gòu)請(qǐng)求證書(shū)”柔逼,這里就本地生成了一對(duì)公私鑰,保存的 CertificateSigningRequest 就是公鑰割岛,私鑰保存在本地電腦里愉适。
第 2 步蘋(píng)果處理,不用管癣漆。
第 3 步對(duì)應(yīng)把 CertificateSigningRequest 傳到蘋(píng)果后臺(tái)生成證書(shū)维咸,并下載到本地。這時(shí)本地有兩個(gè)證書(shū)惠爽,一個(gè)是第 1 步生成的癌蓖,一個(gè)是這里下載回來(lái)的,keychain 會(huì)把這兩個(gè)證書(shū)關(guān)聯(lián)起來(lái)婚肆,因?yàn)樗麄児借€是對(duì)應(yīng)的胳蛮,在XCode選擇下載回來(lái)的證書(shū)時(shí)码撰,實(shí)際上會(huì)找到 keychain 里對(duì)應(yīng)的私鑰去簽名衡查。這里私鑰只有生成它的這臺(tái) Mac 有壶栋,如果別的 Mac 也要編譯簽名這個(gè) App 怎么辦?答案是把私鑰導(dǎo)出給其他 Mac 用赞咙,在 keychain 里導(dǎo)出私鑰责循,就會(huì)存成 .p12 文件,其他 Mac 打開(kāi)后就導(dǎo)入了這個(gè)私鑰攀操。
第 4 步都是在蘋(píng)果網(wǎng)站上操作沼死,配置 AppID / 權(quán)限 / 設(shè)備等,最后下載 Provisioning Profile 文件崔赌。
第 5 步 XCode 會(huì)通過(guò)第 3 步下載回來(lái)的證書(shū)(存著公鑰)意蛀,在本地找到對(duì)應(yīng)的私鑰(第一步生成的),用本地私鑰去簽名 App健芭,并把 Provisioning Profile 文件命名為 embedded.mobileprovision 一起打包進(jìn)去县钥。這里對(duì) App 的簽名數(shù)據(jù)保存分兩部分,Mach-O 可執(zhí)行文件會(huì)把簽名直接寫(xiě)入這個(gè)文件里慈迈,其他資源文件則會(huì)保存在 _CodeSignature 目錄下若贮。
第 6 – 7 步的打包和驗(yàn)證都是 Xcode 和 iOS 系統(tǒng)自動(dòng)做的事。
這里再總結(jié)一下這些概念:
證書(shū):內(nèi)容是公鑰或私鑰痒留,由其他機(jī)構(gòu)對(duì)其簽名組成的數(shù)據(jù)包谴麦。
Entitlements:包含了 App 權(quán)限開(kāi)關(guān)列表。
CertificateSigningRequest:本地公鑰伸头。
p12:本地私鑰匾效,可以導(dǎo)入到其他電腦。
Provisioning Profile:包含了 證書(shū) / Entitlements 等數(shù)據(jù)恤磷,并由蘋(píng)果后臺(tái)私鑰簽名的數(shù)據(jù)包面哼。
其他發(fā)布方式
前面以開(kāi)發(fā)包為例子說(shuō)了簽名和驗(yàn)證的流程野宜,另外兩種方式 In-House 企業(yè)簽名和 AD-Hoc 流程也是差不多的,只是企業(yè)簽名不限制安裝的設(shè)備數(shù)魔策,另外需要用戶(hù)在 iOS 系統(tǒng)設(shè)置上手動(dòng)點(diǎn)擊信任這個(gè)企業(yè)才能通過(guò)驗(yàn)證匈子。
而 AppStore 的簽名驗(yàn)證方式有些不一樣,前面我們說(shuō)到最簡(jiǎn)單的簽名方式闯袒,蘋(píng)果在后臺(tái)直接用私鑰簽名 App 就可以了虎敦,實(shí)際上蘋(píng)果確實(shí)是這樣做的,如果去下載一個(gè) AppStore 的安裝包政敢,會(huì)發(fā)現(xiàn)它里面是沒(méi)有 embedded.mobileprovision 文件的其徙,也就是它安裝和啟動(dòng)的流程是不依賴(lài)這個(gè)文件,驗(yàn)證流程也就跟上述幾種類(lèi)型不一樣了堕仔。
據(jù)猜測(cè),因?yàn)樯蟼鞯?AppStore 的包蘋(píng)果會(huì)重新對(duì)內(nèi)容加密晌区,原來(lái)的本地私鑰簽名就沒(méi)有用了摩骨,需要重新簽名,從 AppStore 下載的包蘋(píng)果也并不打算控制它的有效期朗若,不需要內(nèi)置一個(gè) embedded.mobileprovision 去做校驗(yàn)恼五,直接在蘋(píng)果用后臺(tái)的私鑰重新簽名,iOS 安裝時(shí)用本地公鑰驗(yàn)證 App 簽名就可以了哭懈。
那為什么發(fā)布 AppStore 的包還是要跟開(kāi)發(fā)版一樣搞各種證書(shū)和 Provisioning Profile灾馒?猜測(cè)因?yàn)樘O(píng)果想做統(tǒng)一管理,Provisioning Profile 里包含一些權(quán)限控制遣总,AppID 的檢驗(yàn)等睬罗,蘋(píng)果不想在上傳 AppStore 包時(shí)重新用另一種協(xié)議做一遍這些驗(yàn)證,就不如統(tǒng)一把這部分放在 Provisioning Profile 里旭斥,上傳 AppStore 時(shí)只要用同樣的流程驗(yàn)證這個(gè) Provisioning Profile 是否合法就可以了容达。
所以 App 上傳到 AppStore 后,就跟你的 證書(shū) / Provisioning Profile 都沒(méi)有關(guān)系了垂券,無(wú)論他們是否過(guò)期或被廢除花盐,都不會(huì)影響 AppStore 上的安裝包。
到這里 iOS 簽名機(jī)制的原理和主流程大致說(shuō)完了菇爪,希望能對(duì)理解蘋(píng)果簽名和排查日常簽名問(wèn)題有所幫助算芯。
P.S.一些疑問(wèn)
最后這里再提一下我關(guān)于簽名流程的一些的疑問(wèn)。
企業(yè)證書(shū)
企業(yè)證書(shū)簽名因?yàn)橄拗粕俚手妫趪?guó)內(nèi)被廣泛用于測(cè)試和盜版熙揍,fir.im / 蒲公英等測(cè)試平臺(tái)都是通過(guò)企業(yè)證書(shū)分發(fā),國(guó)內(nèi)一些市場(chǎng)像 PP 助手氏涩,愛(ài)思助手诈嘿,一部分安裝手段也是通過(guò)企業(yè)證書(shū)重簽名堪旧。通過(guò)企業(yè)證書(shū)簽名安裝的 App,啟動(dòng)時(shí)都會(huì)驗(yàn)證證書(shū)的有效期奖亚,并且不定期請(qǐng)求蘋(píng)果服務(wù)器看證書(shū)是否被吊銷(xiāo)淳梦,若已過(guò)期或被吊銷(xiāo),就會(huì)無(wú)法啟動(dòng) App昔字。對(duì)于這種助手的盜版安裝手段爆袍,蘋(píng)果想打擊只能一個(gè)個(gè)吊銷(xiāo)企業(yè)證書(shū),并沒(méi)有太好的辦法作郭。
這里我的疑問(wèn)是陨囊,蘋(píng)果做了那么多簽名和驗(yàn)證機(jī)制去限制在 iOS 安裝 App,為什么又要出這樣一個(gè)限制很少的方式讓盜版鉆空子呢夹攒?若真的是企業(yè)用途不適合上 AppStore蜘醋,也完全可以在 AppStore 開(kāi)辟一個(gè)小的私密版塊,還是通過(guò) AppStore 去安裝咏尝,就不會(huì)有這個(gè)問(wèn)題了压语。
AppStore 加密
另一個(gè)問(wèn)題是我們把 App 傳上 AppStore 后,蘋(píng)果會(huì)對(duì) App 進(jìn)行加密编检,導(dǎo)致 App 體積增大不少胎食,這個(gè)加密實(shí)際上是沒(méi)卵用的,只是讓破解的人要多做一個(gè)步驟允懂,運(yùn)行 App 去內(nèi)存 dump 出可執(zhí)行文件而已厕怜,無(wú)論怎樣加密,都可以用這種方式拿出加密前的可執(zhí)行文件蕾总。所以為什么要做這樣的加密呢粥航?想不到有什么好處。
本地私鑰
我們看到前面說(shuō)的簽名流程很繞很復(fù)雜生百,經(jīng)常出現(xiàn)各種問(wèn)題躁锡,像有 Provisioning Profile 文件但證書(shū)又不對(duì),本地有公鑰證書(shū)沒(méi)對(duì)應(yīng)私鑰等情況置侍,不理解原理的情況下會(huì)被繞暈映之,我的疑問(wèn)是,這里為什么不能簡(jiǎn)化呢蜡坊?還是以開(kāi)發(fā)證書(shū)為例杠输,為什么一定要用本地 Mac 生成的私鑰去簽名?蘋(píng)果要的只是本地簽名秕衙,私鑰不一定是要本地生成的蠢甲,蘋(píng)果也可以自己生成一對(duì)公私鑰給我們,放在 Provisioning Profile 里据忘,我們用里面的私鑰去加密就行了鹦牛,這樣就不會(huì)有 CertificateSigningRequest 和 p12 的概念搞糕,跟本地 keychain 沒(méi)有關(guān)系,不需要關(guān)心證書(shū)曼追,只要有 Provisioning Profile 就能簽名窍仰,流程會(huì)減少,易用性會(huì)提高很多礼殊,同時(shí)蘋(píng)果想要的控制一點(diǎn)都不會(huì)少驹吮,也沒(méi)有什么安全問(wèn)題,為什么不這樣設(shè)計(jì)呢晶伦?
能想到的一個(gè)原因是 Provisioning Profile 在非 AppStore 安裝時(shí)會(huì)打包進(jìn)安裝包碟狞,第三方拿到這個(gè) Provisioning Profile 文件就能直接用起來(lái)給他自己的 App 簽名了。但這種問(wèn)題也挺好解決婚陪,只需要打包時(shí)去掉文件里的私鑰就行了族沃,所以仍不明白為什么這樣設(shè)計(jì)。