在第一篇文章的最后衣赶,簡(jiǎn)單描述了iOS系統(tǒng)使用數(shù)字簽名的機(jī)制。本質(zhì)上就是使用RSA+信息摘要算法為基礎(chǔ)的簽名技術(shù)來(lái)對(duì)代碼和圖像素材資源進(jìn)行簽名驗(yàn)簽侧但。文章的最后提出了兩個(gè)問(wèn)題:
**
(1)RSA的公鑰和私鑰從何而來(lái)看政?
(2)iOS設(shè)備如何保證該公鑰和私鑰合法性,并有權(quán)限對(duì)代碼進(jìn)行簽名和驗(yàn)簽操作欺栗?
**
我們通過(guò)申請(qǐng)?zhí)O果開(kāi)發(fā)者證書(shū)毫痕,生成描述文件,生成ipa包等過(guò)程的詳細(xì)描述迟几,來(lái)說(shuō)明一下以上問(wèn)題如何解決消请。
1,申請(qǐng)?zhí)O果開(kāi)發(fā)者證書(shū)瘤旨。
使用KeyChain工具梯啤,生成certificateSigningRequest.CertSigningRequest竖伯。
操作步驟:“鑰匙串訪問(wèn)” -> “證書(shū)助理” -> “從證書(shū)頒發(fā)機(jī)構(gòu)請(qǐng)求證書(shū)” -> “用戶(hù)電子郵件地址填寫(xiě):apple id存哲;常用名稱(chēng)寫(xiě)得形象一點(diǎn)因宇。”->“請(qǐng)求是選擇存儲(chǔ)到磁盤(pán)”
保存在本地的就是certificateSigningRequest.CertSigningRequest文件了祟偷。如何查看這個(gè)文件的內(nèi)容呢察滑?有兩種方法,第一種是使用蘋(píng)果的keyChain(鑰匙串訪問(wèn))修肠,查看密鑰贺辰。第二種是使用openssl的命令行工具。
//查看certificateSigningRequest.CertSigningRequest的方法
openssl asn1parse -i -in CertificateSigningRequest.certSigningRequest
總結(jié)以上步驟的產(chǎn)物:
**
a嵌施,生成私鑰和公鑰對(duì)饲化。
b,指明使用加密和簽名算法(RSA+SHA1)吗伤。
**
最后吃靠,certificateSigningRequest.CertSigningRequest = 加密后信息+公鑰+加密方法和摘要方法。
我們就得到了足淆,可以和蘋(píng)果交互并認(rèn)證的RSA的密鑰對(duì)了巢块,那么接下來(lái)的問(wèn)題就是如何保證我們與蘋(píng)果之間所使用的密鑰對(duì)不被別的中間人所攻擊或者替換呢?
2巧号, 上傳certificateSigningRequest.CertSigningRequest文件到蘋(píng)果開(kāi)發(fā)者網(wǎng)站族奢,蘋(píng)果處理后下載開(kāi)發(fā)者證書(shū)。
這里丹鸿,將certificateSigningRequest.CertSigningRequest上傳的步驟保證了越走,你的公鑰信息準(zhǔn)確的提交給了蘋(píng)果。首先卜高,你需要有蘋(píng)果的開(kāi)發(fā)者賬號(hào)弥姻,登錄到上傳certificateSigningRequest.CertSigningRequest的界面;其次掺涛,信息摘要和簽名技術(shù)保證了你上傳公鑰的完整和有效性庭敦。因此,這個(gè)步驟保證了你的公鑰被安全準(zhǔn)確的送到了蘋(píng)果的手中薪缆。蘋(píng)果通過(guò)驗(yàn)證蘋(píng)果自己在Mac主機(jī)里面的公鑰(蘋(píng)果公鑰秧廉,非上面步驟生成),來(lái)保證你的請(qǐng)求是合法有效的拣帽,同時(shí)疼电,蘋(píng)果生成數(shù)字證書(shū),對(duì)你的公鑰進(jìn)行了認(rèn)證减拭。
3蔽豺,導(dǎo)入開(kāi)發(fā)者證書(shū)。
雙擊證書(shū)后拧粪,系統(tǒng)導(dǎo)入到keyChain工具里修陡,可以直接在keyChain(鑰匙串訪問(wèn))里面查看沧侥,還可以使用openssl查看證書(shū)內(nèi)容:
openssl x509 -inform der -in ios_development.cer -noout –text
通過(guò)查看證書(shū)的內(nèi)容,我們發(fā)現(xiàn)魄鸦,蘋(píng)果做的事情僅僅就是將我們的公鑰原封不動(dòng)的打包到證書(shū)里面宴杀,再交還給我們導(dǎo)入到KeyChain進(jìn)行管理。蘋(píng)果的這個(gè)流程拾因,就是對(duì)我們公鑰的一個(gè)認(rèn)證旺罢。
當(dāng)我們的程序?qū)懞玫臅r(shí)候,進(jìn)行程序打包的過(guò)程時(shí)绢记。我們自己手上掌握的私鑰扁达,會(huì)將程序代碼和其它文件資源,使用私鑰加密蠢熄。
4罩驻,真機(jī)調(diào)試。
好了护赊,現(xiàn)在打包好的程序就要進(jìn)入真機(jī)調(diào)試了惠遏,真機(jī)如果要驗(yàn)證我們的代碼和程序合法且有權(quán)限在真機(jī)運(yùn)行,需要什么呢骏啰?請(qǐng)讀者在這里想一下节吮。
好了,首先判耕,就是需要公鑰進(jìn)行驗(yàn)簽操作透绩。從蘋(píng)果下載的證書(shū),就是認(rèn)證后的公鑰壁熄,需要放在描述文件里面帚豪,打包進(jìn)入真機(jī)。此外草丧,描述文件除了證書(shū)外狸臣,還有AppID、功能授權(quán)列表昌执、設(shè)備列表烛亦、蘋(píng)果簽名等信息,對(duì)App在設(shè)備中的能力和權(quán)限做出有效的規(guī)定懂拾。
iOS程序最終都會(huì)以.ipa文件導(dǎo)出煤禽,先來(lái)了解一下ipa文件的結(jié)構(gòu):
事實(shí)上,ipa文件只是一個(gè)zip包岖赋,可以使用如下命令解壓:
/usr/bin/unzip -q xxx.ipa -d <destination>
解壓后檬果,得到上圖的Payload目錄,下面是個(gè)子目錄,其中的內(nèi)容如下:
(1) 資源文件选脊,例如圖片衷畦、html、等等知牌。
(2) _CodeSignature/CodeResources。這是一個(gè)plist文件斤程,可用文本查看角寸,其中的內(nèi)容就是是程序包中(不包括Frameworks)所有文件的簽名。注意這里是所有文件忿墅。意味著你的程序一旦簽名扁藕,就不能更改其中任何的東西,包括資源文件和可執(zhí)行文件本身疚脐。iOS系統(tǒng)會(huì)檢查這些簽名亿柑。
(3) 可執(zhí)行文件。此文件跟資源文件一樣需要簽名棍弄。
(4) 一個(gè)mobileprovision文件.打包的時(shí)候使用的望薄,從MC上生成的。
(5) Frameworks呼畸。程序引用的非系統(tǒng)自帶的Frameworks痕支,每個(gè)Frameworks其實(shí)就是一個(gè)app,其中的結(jié)構(gòu)應(yīng)該和app差不多蛮原,也包含簽名信息CodeResources文件
驗(yàn)證一個(gè)ipa是否合法關(guān)鍵的幾個(gè)點(diǎn):
(1) 解壓ipa
(2) 取出embedded.mobileprovision卧须,通過(guò)簽名校驗(yàn)是否被篡改過(guò)。
(3) 校驗(yàn)所有文件的簽名儒陨,包括Frameworks花嘶。
(4) 比對(duì)Info.plist里面的BundleId是否符合embedded.mobileprovision文件中的AppID。
整個(gè)過(guò)程除了技術(shù)支持(RSA+摘要算法+數(shù)字證書(shū))蹦漠,還有安全流程管控(蘋(píng)果開(kāi)發(fā)者賬號(hào)椭员,上傳公鑰,蘋(píng)果控制發(fā)布數(shù)字證書(shū)笛园,認(rèn)證公鑰拆撼,且保證公鑰合法準(zhǔn)確)。整個(gè)機(jī)制設(shè)計(jì)喘沿,環(huán)環(huán)相扣闸度,蘋(píng)果做到對(duì)APP在真機(jī)運(yùn)行和調(diào)試的有限管控。