1. 應(yīng)用簽名原理
以前操作系統(tǒng)上是不需要簽名的,軟件下載下來(lái)就能用,盜版橫行。蘋(píng)果希望解決這樣的問(wèn)題,保證每一個(gè)安裝到iOS系統(tǒng)上的軟件都是經(jīng)過(guò)蘋(píng)果驗(yàn)證的。要怎么保證呢?就是通過(guò)簽名機(jī)制。
1.1 非對(duì)稱(chēng)加密(RSA)
代碼簽名是對(duì)可執(zhí)行文件或腳本進(jìn)行數(shù)字簽名,用來(lái)確認(rèn)軟件在簽名后未被修改或損壞的措施。它是基于非對(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é)原理:
- 選兩個(gè)質(zhì)數(shù)
x和y相乘得出一個(gè)大整數(shù)n,例如 x=31,y=41,n=xy=1271 - 選
1-n間的隨便一個(gè)質(zhì)數(shù)z,例如 z=13 - 經(jīng)過(guò)一系列數(shù)學(xué)公式,算出一個(gè)數(shù)字
p,滿足:- 通過(guò)
n和z這兩個(gè)數(shù)據(jù)一組數(shù)據(jù)進(jìn)行數(shù)學(xué)運(yùn)算后,可以通過(guò)n和p去反解運(yùn)算,反過(guò)來(lái)也可以。 - 如果只知道
n和z,要推導(dǎo)出p,需要知道x和y,也就是要需要把n因數(shù)分解。
- 通過(guò)
(n,z)兩個(gè)數(shù)據(jù)在一起就是公鑰,(n,p)兩個(gè)數(shù)據(jù)就是私鑰,滿足用公鑰加密,私鑰解密,或反過(guò)來(lái)公鑰加密,私鑰解密,也滿足在只暴露公鑰的情況下,要推導(dǎo)出私鑰(n,p),需要把大整數(shù)n因數(shù)分解。目前因數(shù)分解只能靠暴力窮舉,而n數(shù)字越大,越難以用窮舉計(jì)算出因數(shù)x和y,也就越安全,當(dāng)n大到二進(jìn)制1024位或2048位時(shí),以目前技術(shù)要破解幾乎不可能,所以非常安全。
注意:生成密文的長(zhǎng)度和明文長(zhǎng)度無(wú)關(guān),但明文長(zhǎng)度不能超過(guò)密鑰長(zhǎng)度。
1.2 數(shù)字簽名
數(shù)字簽名是非對(duì)稱(chēng)密鑰加密技術(shù)與數(shù)字摘要技術(shù)的應(yīng)用。首先我們需要計(jì)算代碼的摘要,再利用非對(duì)稱(chēng)加密進(jìn)行加密處理。
Mac鑰匙串里面可以看到我們私鑰長(zhǎng)度是2048位=256字節(jié),所以我們的摘要不能長(zhǎng)于256字節(jié)。
- 我們需要一種算法算出數(shù)據(jù)的摘要,滿足:
- 原始數(shù)據(jù)若發(fā)生任何變化,計(jì)算出的摘要值都會(huì)發(fā)生改變。
- 計(jì)算出的摘要要足夠短,不能長(zhǎng)于256字節(jié)。最常用的算法就是MD5、SHA-1。
- 生成一對(duì)RSA的公鑰和私鑰,自己拿著私鑰,公鑰可以發(fā)布出去。
- 第一步計(jì)算出摘要后,用私鑰對(duì)摘要進(jìn)行加密,得到的加密數(shù)據(jù)就是原始數(shù)據(jù)的數(shù)字簽名。把數(shù)據(jù)簽名和原始數(shù)據(jù)一起發(fā)送給用戶。
- 用戶拿到數(shù)據(jù)簽名和原始數(shù)據(jù)后:
- 同樣的摘要算法對(duì)原始數(shù)據(jù)進(jìn)行計(jì)算摘要值。
- 再用公鑰對(duì)數(shù)字簽名進(jìn)行解密,得到發(fā)送者算出的摘要值,判斷兩個(gè)摘要值是否相等。
注意:若數(shù)據(jù)被篡改過(guò),這個(gè)值會(huì)不一樣,導(dǎo)致摘要值不等;若摘要值相等,則說(shuō)明數(shù)據(jù)沒(méi)有被串改。
1.3 單向簽名
通過(guò)上面的介紹,蘋(píng)果官方生成一對(duì)公鑰和私鑰,自己拿著私鑰,所有的iOS設(shè)備內(nèi)置公鑰。蘋(píng)果將我們上傳App Store的App進(jìn)行數(shù)字簽名。用戶從App Store下載App時(shí),同時(shí)下發(fā)數(shù)字簽名。iOS設(shè)備對(duì)下載的App進(jìn)行摘要值計(jì)算,再用設(shè)備內(nèi)置的公鑰對(duì)數(shù)字簽名解密得到摘要值。如果摘要值相同,則說(shuō)明應(yīng)用是官方認(rèn)證且沒(méi)有被篡改的。
如果只能通過(guò)App Store進(jìn)行下載安裝,單向數(shù)據(jù)簽名就可以解決問(wèn)題,但是蘋(píng)果還提供了多種App安裝方式:
- Development:開(kāi)發(fā)證書(shū)簽名后,認(rèn)證過(guò)的設(shè)備可以直接安裝應(yīng)用。
- In-House:企業(yè)證書(shū)簽名后,企業(yè)內(nèi)部分發(fā)安裝使用。
- AD-Hoc:相當(dāng)于企業(yè)分發(fā)的限制版,限制安裝設(shè)備數(shù)量,較少用。
上面的安裝方式總結(jié)一下:
- 開(kāi)發(fā)階段,安裝包不需要上傳到App Store就可以直接安裝到設(shè)備上。
- 既需要保證系統(tǒng)的安全性,又必須對(duì)安裝的App有絕對(duì)的控制權(quán):
- 經(jīng)過(guò)蘋(píng)果允許才可以安裝。
- 不能被濫用,導(dǎo)致非開(kāi)發(fā)App也能被安裝。
蘋(píng)果這里給出的方案是雙層簽名。
1.4 雙向簽名
雙向簽名的過(guò)程如下:
- 在Mac系統(tǒng)中生成一對(duì)公鑰和私鑰,這里稱(chēng)為公鑰M和私鑰M。(M=Mac)
- 蘋(píng)果自己有固定的一對(duì)公鑰和私鑰,跟之前App Store原理一樣,私鑰在蘋(píng)果后臺(tái),公鑰在每個(gè)iOS系統(tǒng)中。這里稱(chēng)為公鑰A和私鑰A。(A=Apple)
- 把公鑰M以及一些開(kāi)發(fā)者的信息,傳到蘋(píng)果后臺(tái)(這個(gè)就是CSR文件),用蘋(píng)果后臺(tái)里的私鑰A去簽名公鑰M。 得到一份數(shù)據(jù)包含了公鑰M以及其簽名,把這份數(shù)據(jù)稱(chēng)為證書(shū)。
- 在開(kāi)發(fā)時(shí),編譯完一個(gè)App后,用本地的私鑰M(P12)對(duì)這個(gè)App進(jìn)行簽名,同時(shí)把第三步得到的證書(shū)一起打包進(jìn)App里,安裝到手機(jī)上。
- 安裝時(shí),iOS系統(tǒng)進(jìn)行2次簽名驗(yàn)證:
- 通過(guò)系統(tǒng)內(nèi)置的公鑰A解密證書(shū)私鑰A獲取證書(shū)摘要,再驗(yàn)證證書(shū)是否被篡改。
- 驗(yàn)證證書(shū)后確保了公鑰M是蘋(píng)果認(rèn)證過(guò)的,再用公鑰M去驗(yàn)證App的簽名。

有了上面的過(guò)程,已經(jīng)可以保證開(kāi)發(fā)者的認(rèn)證,和程序的安全性了。 但是,iOS程序一般是通過(guò)App Store分發(fā)到用戶設(shè)備的。如果只有上述的過(guò)程,那豈不是只要申請(qǐng)了一個(gè)證書(shū),就可以安裝到所有 iOS設(shè)備了?
蘋(píng)果這里給出的方案是授權(quán)文件。
1.5 雙向簽名+授權(quán)文件
蘋(píng)果為了解決應(yīng)用濫用的問(wèn)題,又加上了一些限制:
- 蘋(píng)果后臺(tái)注冊(cè)過(guò)的設(shè)備才可以安裝。
- 簽名只能針對(duì)某一個(gè)具體的App。
- 蘋(píng)果還想控制App里面的iCloud、Push、后臺(tái)運(yùn)行、調(diào)試器附加這些權(quán)限,所以蘋(píng)果把這些權(quán)限開(kāi)關(guān)統(tǒng)一稱(chēng)為Entitlements(授權(quán)文件)。將這個(gè)文件放在了一個(gè)叫做Provisioning Profile(描述文件)文件中,Xcode運(yùn)行時(shí)會(huì)打包進(jìn)入App內(nèi)。
在開(kāi)發(fā)時(shí),編譯完一個(gè) App后,用本地的私鑰M對(duì)這個(gè)App進(jìn)行簽名,同時(shí)把從蘋(píng)果服務(wù)器得到的描述文件打包進(jìn)APP里,文件名為embedded.mobileprovision。App安裝到手機(jī)上后,系統(tǒng)將完成驗(yàn)證工作。
