iOS安全之?dāng)?shù)字證書和安全機(jī)制

作者comst

本文轉(zhuǎn)載自:http://www.lxweimin.com/p/d022470cef7e

iOS安全之?dāng)?shù)字證書和安全機(jī)制

非對(duì)稱加密和摘要

非對(duì)稱加密就是指加密密鑰和解密密鑰是不同的,而且加密密鑰和解密密鑰是成對(duì)出現(xiàn)。非對(duì)稱加密又叫公鑰加密,也就是說成對(duì)的密鑰,其中一個(gè)是對(duì)外公開的,所有人都可以獲得,稱為公鑰,而與之相對(duì)應(yīng)的稱為私鑰,只有這對(duì)密鑰的生成者才能擁有。公私鑰具有以下重要特性:

對(duì)于一個(gè)私鑰,有且只有一個(gè)與之對(duì)應(yīng)的公鑰。生成者負(fù)責(zé)生成私鑰和公鑰,并保存私鑰,公開公鑰。

公鑰是公開的,但不可能通過公鑰反推出私鑰,或者說極難反推,所以只要秘鑰足夠長度,要通過窮舉而得到私鑰,幾乎是不可能的。

通過私鑰加密的密文只能通過公鑰解密,公鑰加密的密文只有通過私鑰解密。

由于上述特性,非對(duì)稱加密具有以下的典型用法:

對(duì)信息保密,防止中間人攻擊:將明文通過接收人的公鑰加密,傳輸給接收人,因?yàn)橹挥薪邮杖藫碛袑?duì)應(yīng)的私鑰,別人不可能擁有或者不可能通過公鑰推算出私鑰,所以傳輸過程中無法被中間人截獲。只有擁有私鑰的接收人才能閱讀。此用法通常用于交換對(duì)稱密鑰。

身份驗(yàn)證和防止篡改:權(quán)限狗用自己的私鑰加密一段授權(quán)明文,并將授權(quán)明文和加密后的密文,以及公鑰一并發(fā)送出來,接收方只需要通過公鑰將密文解密后與授權(quán)明文對(duì)比是否一致,就可以判斷明文在中途是否被篡改過。此方法用于數(shù)字簽名。

著名的RSA算法就是非對(duì)稱加密算法,RSA以三個(gè)發(fā)明人的首字母命名。

非對(duì)稱加密算法如此強(qiáng)大可靠,卻有一個(gè)弊端,就是加解密比較耗時(shí)。因此,在實(shí)際使用中,往往與對(duì)稱加密和摘要算法結(jié)合使用。

對(duì)稱加密是將明文(原始數(shù)據(jù))和加密密鑰(mi yao)一起經(jīng)過特殊加密算法處理后,使其變成復(fù)雜的加密密文發(fā)送出去。收信方收到密文后,若想解讀原文,則需要使用加密用過的密鑰及相同算法的逆算法對(duì)密文進(jìn)行解密,才能使其恢復(fù)成可讀明文。在對(duì)稱加密算法中,使用的密鑰只有一個(gè),發(fā)收信雙方都使用這個(gè)密鑰對(duì)數(shù)據(jù)進(jìn)行加密和解密,這就要求解密方事先必須知道加密密鑰。計(jì)算機(jī)專網(wǎng)系統(tǒng)中廣泛使用的對(duì)稱加密算法有DES和IDEA等。

摘要算法可以將任意長度的文本,通過一個(gè)算法,得到一個(gè)固定長度的文本。這里文本不一定只是文本,可以是字節(jié)數(shù)據(jù)。所以摘要算法試圖將世間萬物,變成一個(gè)固定長度的東西。摘要算法具有以下重要特性:

只要源文本不同,計(jì)算得到的結(jié)果,必然不同。

無法從結(jié)果反推出源。

典型的摘要算法,比如大名鼎鼎的MD5和SHA。摘要算法主要用于比對(duì)信息源是否一致,因?yàn)橹灰窗l(fā)生變化,得到的摘要必然不同;而且通常結(jié)果要比源短很多,所以稱為“摘要”。

數(shù)字簽名

數(shù)字簽名一般用于數(shù)據(jù)接收方(一般指客戶端)驗(yàn)證數(shù)據(jù)發(fā)送發(fā)方(一般只指代服務(wù)器)發(fā)送的數(shù)據(jù)是否合法(是否經(jīng)過第三方篡改)。舉個(gè)例子,A有一段文本要發(fā)給B,A為了防止文本在中途被惡意篡改。A找來C,C將文本內(nèi)容通過摘要算法,得到摘要,再用自己(C的)私鑰對(duì)摘要加密得到密文,A將原文、密文一并發(fā)給B。接收方B收到數(shù)據(jù)以后用C的公鑰(提前固化在系統(tǒng)中了)對(duì)密文進(jìn)行解密,將文本用同樣的算法得到摘要,兩個(gè)摘要進(jìn)行對(duì)比,如果相等那么一切正常,否則視為接收數(shù)據(jù)視為無效。如圖:

數(shù)字簽名可以快速驗(yàn)證文本的完整性和合法性。

數(shù)字證書

數(shù)字證書就是通過數(shù)字簽名實(shí)現(xiàn)的數(shù)字化的證書。在一般的證書組成部分中,還加入了其他的信息,比如證書有效期,過了有效期,需要重新簽發(fā)。

數(shù)字證書的簽發(fā)機(jī)構(gòu)也有若干,并有不同的用處。比如蘋果公司就可以簽發(fā)跟蘋果公司有關(guān)的證書,而跟web訪問有關(guān)的證書則是又幾家公認(rèn)的機(jī)構(gòu)進(jìn)行簽發(fā)。這些簽發(fā)機(jī)構(gòu)稱為CA(Certificate Authority)。我們的app要想運(yùn)行在iPhone上,就要從蘋果申請(qǐng)相關(guān)的證書。而iOS設(shè)備在運(yùn)行我們的app之前,首先驗(yàn)證證書是否合法,然后再通過證書中的公鑰驗(yàn)證程序是不是我們發(fā)布的,中間有沒有被修改。

iOS證書申請(qǐng)和打包

流程圖

證書申請(qǐng)

開發(fā)iOS程序必然進(jìn)行的工作就是成為開發(fā)者,并申請(qǐng)相關(guān)的證書。在申請(qǐng)之前需要:

支付$99或$299成為蘋果開發(fā)者,并每年續(xù)費(fèi),$99針對(duì)個(gè)人和小企業(yè),$299針對(duì)大企業(yè)。

安裝蘋果開發(fā)者根證書,此證書實(shí)際上是我們從蘋果MC中申請(qǐng)的所有證書的“根證書”,安裝這個(gè)證書意味著我們的開發(fā)工具對(duì)此CA的信任,從而可以用此CA簽發(fā)的其他證書進(jìn)行簽名和打包。一般而言,如果安裝了Xcode,那么這個(gè)證書是自動(dòng)安裝在Key Chain中了。

CertificateSigningRequest.certSigningRequest

我們需要生成一個(gè)CertificateSigningRequest.certSigningRequest文件來提交到MC中,從而獲取某種證書。這個(gè)文件包含兩部分內(nèi)容:

申請(qǐng)者信息,此信息是用申請(qǐng)者的私鑰加密的。

申請(qǐng)者公鑰,此信息是申請(qǐng)者使用的私鑰對(duì)應(yīng)的公鑰。

摘要算法和公鑰加密算法。

從MC中申請(qǐng)到的證書

證書中最為重要的是我的公鑰,這個(gè)公鑰與我本機(jī)的私鑰是對(duì)應(yīng)的。當(dāng)我們雙擊安裝完證書后,KeyChain會(huì)自動(dòng)將這對(duì)密鑰關(guān)聯(lián)起來。后續(xù)在程序上真機(jī)的過程中,會(huì)使用這個(gè)私鑰,對(duì)代碼進(jìn)行簽名,而公鑰會(huì)附帶在mobileprovision文件中,打包進(jìn)app。所以,就算你有證書,但是如果沒有對(duì)應(yīng)的私鑰是沒有用的。

團(tuán)隊(duì)開發(fā)

打包到真機(jī)上的app需要我們的私鑰進(jìn)行簽名,所以我們?cè)趫F(tuán)隊(duì)開發(fā)中需要公開私鑰。將最初申請(qǐng)證書的機(jī)器的私鑰導(dǎo)出成.p12文件,并讓其他機(jī)器導(dǎo)入,同時(shí)其他機(jī)器也應(yīng)該安裝下載下來的證書。

由于iOS證書有多種類型,用于不同的用處,所以我們可能后續(xù)還會(huì)去MC上申請(qǐng)別的證書。所以強(qiáng)烈建議CertificateSigningRequest.certSigningRequest需要保留,因?yàn)槿绻俅紊蒀ertificateSigningRequest.certSigningRequest文件,可能就是對(duì)應(yīng)另一個(gè)私鑰了!還需要在共享一次私鑰,會(huì)比較麻煩。

iOS證書類型

常用的有:

iOS App Development。開發(fā)、真機(jī)調(diào)試用。

Apple Push Notification service SSL (Sandbox)。開發(fā)階段使用蘋果的推送服務(wù)。

App Store and Ad Hoc。上架和AdHoc方式發(fā)布時(shí)用。

Apple Push Notification service SSL (Production)。上架后使用蘋果推送服務(wù)。

In-House。企業(yè)版發(fā)布,需$299才能擁有,還需鄧氏編碼。

iOS授權(quán)和描述文件

可以使用如下命令查看描述文件。

security cms -D -i embedded.mobileprovision

mobileprovision文件包含:

AppId。每個(gè)app必須在MC中創(chuàng)建一個(gè)對(duì)應(yīng)的AppId。

使用哪些證書。不同類型的證書就代表了不同的發(fā)布方式,還包括一些功能的能否使用(比如APN)。

功能授權(quán)列表。

可安裝的設(shè)備列表。對(duì)于AdHoc方式發(fā)布的app或者真機(jī)調(diào)試時(shí),會(huì)有一個(gè)列表,這個(gè)列表里面是iOS設(shè)備的UDID,每臺(tái)iOS設(shè)備出廠的UDID都不同,所以可以用來標(biāo)識(shí)設(shè)備。

蘋果的簽名。

注意,這里的簽名是蘋果簽的,跟我們的私鑰沒有關(guān)系。也就是說mobileprovision文件是蘋果簽名的,我們除了從MC中獲取,別無他法。也不能再獲取后隨意篡改(比如添加別的設(shè)備)。

AdHoc發(fā)布和真機(jī)調(diào)試

AdHoc允許將測(cè)試版app發(fā)布給有限的設(shè)備安裝,而無需通過appstore的審核。這里的關(guān)鍵是如何控制哪些設(shè)備可以裝。答案就是mobileprovision文件,記得你在生成mobileprovision文件的時(shí)候需要選設(shè)備的UDID吧,所以這些設(shè)備需要事先添加到MC的Devices里面。對(duì)于開發(fā)時(shí)候的真機(jī)調(diào)試,原理差不多。都是通過mobileprovision的條目4來做到的。而蘋果對(duì)于調(diào)試和測(cè)試用機(jī)的數(shù)量限制為100臺(tái)!

iOS代碼簽名

ipa的組成

iOS程序最終都會(huì)以.ipa(事實(shí)上,ipa文件只是一個(gè)zip包)文件導(dǎo)出,先來了解一下ipa文件的結(jié)構(gòu):

將appname.ipa的后綴名改成appname.zip然后解壓,得到上圖的Payload目錄,下面是個(gè)子目錄,其中的內(nèi)容如下。

資源文件,例如圖片、html、等等。

_CodeSignature/CodeResources。這是一個(gè)plist文件,可用文本查看,其中的內(nèi)容就是是程序包中(不包括Frameworks)所有文件的簽名。注意這里是所有文件。意味著你的程序一旦簽名,就不能更改其中任何的東西,包括資源文件和可執(zhí)行文件本身。iOS系統(tǒng)會(huì)檢查這些簽名。

可執(zhí)行文件。此文件跟資源文件一樣需要簽名。

一個(gè)mobileprovision文件.打包的時(shí)候使用的,從MC上生成的。

Frameworks。程序引用的非系統(tǒng)自帶的Frameworks,每個(gè)Frameworks其實(shí)就是一個(gè)app,其中的結(jié)構(gòu)應(yīng)該和app差不多,也包含簽名信息CodeResources文件。

相關(guān)的程序和命令

一般我們會(huì)用Xcode自帶的archive功能來打包ipa和簽名,實(shí)際上xcode只不過是調(diào)用了一些外部程序完成了工作,如果我們有朝一日需要自己實(shí)現(xiàn)自動(dòng)化的簽名流程,就需要了解究竟相關(guān)的程序和命令有哪些。

用下面命令,列出系統(tǒng)中可用于簽名的有效證書:

security find-identity -v -p codesigning

使用如下命令對(duì)xxx.app目錄簽名,codesign程序會(huì)自動(dòng)將其中的文件都簽名,(Frameworks不會(huì)自動(dòng)簽):

codesign -fs “Your Cer” --no-strict Payload/xxx.app

對(duì)于每個(gè)Framework,也需要使用這個(gè)命令簽名,上面說了Framework的結(jié)構(gòu)跟app其實(shí)差不多,所以簽名命令類似。這個(gè)命令會(huì)自動(dòng)找到證書相關(guān)的私鑰。-f表示對(duì)于已經(jīng)簽名的app強(qiáng)制重簽。

最后用下面命令校驗(yàn)簽名是否合法:

codesign -v xxx.app

使用zip命令重新打包成ipa包

zip -qry destination source

對(duì)app重新簽名的流程

如果要設(shè)計(jì)一個(gè)自動(dòng)化的重簽程序,大致需要這么個(gè)流程:

解壓ipa。

如果mobileprovision需要替換,替換。

如果存在Frameworks子目錄,則對(duì).app文件夾下的所有Frameworks進(jìn)行簽名,在Frameworks文件夾下的.dylib或.framework。

對(duì)xxx.app簽名。

重新打包。

iOS設(shè)備如何驗(yàn)證app是否合法

解壓ipa。

取出embedded.mobileprovision,通過簽名校驗(yàn)是否被篡改過。

其中有幾個(gè)證書的公鑰,其中開發(fā)證書和發(fā)布證書用于校驗(yàn)簽名。

BundleId。

授權(quán)列表。

校驗(yàn)所有文件的簽名,包括Frameworks。

比對(duì)Info.plist里面的BundleId是否符合embedded.mobileprovision文件中的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容