? ? ? 在iOS開發過程中,不可避免的要和證書打交道,真機調試、App上架、打包給測試去測試等都需要搞證書。在此過程中我們會遇到很多的問題,但是如果掌握了真機調試的原理和本質;遇到問題,我們就更容易定位問題之所在,從而迅速的解決問題。
知識點補充:
? ? 摘要算法:
? ? ? ? 摘要算法是指,可以將任意長度的文本,通過一個算法,得到一個固定長度的文本。這里文本不一定只是文本,可以是字節數據。所以摘要算法試圖將世間萬物,變成一個固定長度的東西
? ? ?1.只要源文本不同,計算得到的結果,必然不同
? ? ?2. 無法從結果反推出源(那是當然的,不然就能量不守恒了)
? ? ? MD5和SHA。摘要算法主要用于比對信息源是否一致,因為只要源發生變化,得到的摘要必然不同;而且通常結果要比源短很 多,所以稱為“摘要”。
數字證書(digital certificate)
證書生成
? ? ? 開發者在申請iOS開發證書時,需要通過keychain生成證書簽名請求 (CSR) 文件 (*.certSigningRequest),生成 CSR 會創建公鑰、私鑰以及 *.certSigningRequest 文件。公鑰包含在 CSR 中,私鑰用于為請求簽名。提交給蘋果的 Apple Worldwide Developer Relations Certification Authority(WWDR)證書認證中心進行簽名,最后從蘋果官網下載并安裝使用。,證書中的用戶的這個公鑰與我本機的私鑰是對應的。當我們雙擊安裝完證書后,KeyChain會自動將這對密鑰關聯起來,所以在KeyChain中可以看到類似的效果::
CertificateSigningRequest.certSigningRequest文件:
1.申請者信息,此信息是用申請者的私鑰加密的
2.申請者公鑰,此信息是申請者使用的私鑰對應的公鑰
3.摘要算法和公鑰加密算法
? ? ? ? WWDR (Apple Worldwide Developer)是我們從蘋果MC中申請的所有證書的“根證書”,安裝這個證書意味著我們的開發工具對此CA的信任,從而可以用此CA簽發的其他證書進行簽名和打包。一般而言,如果安裝了Xcode,那么這個證書是自動安裝在Key Chain中了。證書如下圖
證書簽名請求 (CSR) 文件的生成過程
(1)打開Keychain(鑰匙串),點擊菜單欄“鑰匙串訪問”->“證書助理”->“從證書頒發機構請求證書”
填寫開發賬號郵件和常用名稱,勾選“存儲到磁盤”。
繼續并選擇存儲位置后,Keychain將生成一個包含開發者身份信息的CSR(Certificate Signing Request)文件。同時,Keychain Access->Keys(密鑰)中增加一對Public/Private Key Pair。
私鑰(private key)始終保存在Mac OS的Keychain Access中,用于簽名(CodeSign)對外發布的App。
公鑰(public key)一般隨證書散布出去,對App簽名進行校驗認證。
數字簽名(digital signature)
? ? ? ? 假設,我們有一段授權文本,需要發布,為了防止中途篡改文本內容,保證文本的完整性,以及文本是由指定的權限狗發的。首先,先將文本內容通過摘要算法,得到摘要,再用權限狗的私鑰對摘要進行加密得到密文,將源文本、密文、和私鑰對應的公鑰一并發布即可。那么如何驗證呢?
? ? ? ?驗證方首先查看公鑰是否是權限狗的,然后用公鑰對密文進行解密得到摘要,將文本用同樣的摘要算法得到摘要,兩個摘要進行比對,如果相等那么一切正常。這個過程只要有一步出問題就視為無效。
? ? ? ? ?數字簽名可以快速驗證文本的完整性和合法性,已廣泛應用于各個領域。理解了數字簽名以后,我們進一步來看什么是數字證書。
? ? ? ? ?非對稱加密的用途之一:
身份驗證和防止篡改:權限狗用自己的私鑰加密一段授權明文,并將授權明文和加密后的密文,以及公鑰一并發送出來,接收方只需要通過公鑰將密文解密后與授權明文對比是否一致,就可以判斷明文在中途是否被篡改過。此方法用于數字簽名。
數字證書組成
經過WWDR數字簽名后的數字證書長這個樣子:
其中包含兩大部分:
· 證書本身
包含用戶的公鑰、用戶個人信息、證書頒發機構信息、證書有效期等信息。
· 證書簽名
WWDR將上述證書本身內容的使用哈希算法得到一個固定長度的信息摘要,然后使用自己的私鑰對該信息摘要加密生成數字簽名,整個過程如圖所示:
數字證書使用
iOS系統原本就持有WWDR的公鑰,系統首先會對證書內容通過指定的哈希算法計算得到一個信息摘要;然后使用WWDR的公鑰對證書中包含的數字簽名解密,從而得到經過WWDR的私鑰加密過的信息摘要;最后對比兩個信息摘要,如果內容相同就說明該證書可信。整個過程如圖所示:
在驗證了證書是可信的以后,iOS系統就可以獲取到證書中包含的開發者的公鑰,并使用該公鑰來判斷代碼簽名的可用性了。
證書存在的意義
通過證書使用過程可以看出,證書本身只是一個中間媒介,iOS系統對證書并不關心,它其實只想要證書中包含的開發者的公鑰!!
但是開發者怎么才能證明公鑰是自己的呢?iOS安全系統怎么才能相信這個公鑰就是這個開發者的呢?
不管是哪一個開發者對iOS的安全系統說,這個公鑰就是我的,系統是都不相信的,即系統對開發者有著百分之百的不信任感。但是iOS安全系統對自家的WWDR是可信任的,蘋果將WWDR的公鑰內置在了iOS系統中。有了證書,iOS安全系統只需要通過WWDR的公鑰就可以獲取到任何一個開發者的可信任的公鑰了,這就是證書存在的意義!!
三、公鑰(public key)
公鑰被包含在數字證書里,數字證書又被包含在描述文件(Provisioning File)中,描述文件在應用被安裝的時候會被拷貝到iOS設備中。
iOS安全系統通過證書就能夠確定開發者身份,就能夠通過從證書中獲取到的公鑰來驗證開發者用該公鑰對應的私鑰簽名后的代碼、資源文件等有沒有被更改破壞,最終確定應用能否合法的在iOS設備上合法運行。
四、私鑰(private key)
每個證書(其實是公鑰)都對應有一個私鑰,
私鑰會被用來對代碼、資源文件等簽名。只有開發證書和描述文件是沒辦法正常調試的,因為沒有私鑰根本無法簽名。
此后的內容基本都是從《代碼簽名探析》摘抄過來的筆記,建議大家看原文好了。
通過私鑰加密的密文只能通過公鑰解密,公鑰加密的密文只有通過私鑰解密
開發者證書分為三種
1)? ? Developer Certification(開發證書)
安裝在電腦上提供權限:開發人員通過設備進行真機測試。
可以生成副本供多臺電腦安裝;
2)??????Distribution Certification(發布證書)
安裝在電腦上提供發布iOS程序的權限:開發人員可以制做測試版和發布版的程序。
不可生成副本,僅有配置該證書的電腦才可使用;
? ? ? 上面提到的證書副本就是通過配置證書的電腦導出Keychain(就是.p12文件)安裝到其他機子上,讓其他機子得到證書對應的權 限。Developer Certification就可以制做副本Keychain分發到其他電腦上安裝,使其可以進行真機測試。
注意:Distribution Certification只有配置證書的電腦才可使用,因此即使導出導出Keychain安裝到其他電腦上,其他電腦也不可能具有證書的權限。
? ? ?開發證書和發布證書每種最多有3個,無法創建更多了。
3)? ? ? Push Notifications Certification(推送證書)
下面詳細講解下推送證書的生成步驟:
有兩種方式,
? ?<1>.一個是在APPID里面 Edit 設置里打開 Push notifications 功能,此時此功能的狀態是 Configurable(可配置)狀態。
分別在為開發環境下的推送證書、發布環境下的推送證書上傳你電腦導出的 證書簽名請求 (CSR) 文件即可,全部添加后功能的狀態會變成 ?Enabled狀態。
<2>.通過為指定APPID設置 測試、生產環境下的推送證書來實現。
選擇開發證書或者生產證書,這里以生產證書為例,繼續
選擇App ID,即我們在“ Identifiers”中創建的App ID,繼續
這里需要添加生成的證書請求文件(CSR),“Choose File”選擇生成的.certSigningRequest文件,點擊“Generate”。
我們可以點擊“Download”下載該開發證書,或者在“Certificates”->“All”中查看該證書,并進行下載或刪除,如圖:
下載證書,雙擊導入Keychain Access,可在Keychain Access->“證書”中查看
展開安裝的證書(ios_development.cer)前面的箭頭,可以看到其對應的私鑰。在KeychainAccess->“密鑰”中展開創建CSR時生成的Key Pair中的私鑰前面的箭頭,可以查看到包含其對應公鑰的證書.
打開Keychain Access,選擇安裝成功的證書,右鍵選擇“導出”
輸入名字,默認格式為.p12類型,選擇“Save”
設置密碼,點擊“OK”
自此指定APPID的推送證書便生成并導出完畢。
? ? 下面這種開發打包過程中遇到的問題是因為 WWDR 證書過期了,需要刪掉舊的WWDR 證書,重新下載新的根證書安裝即可:
Provisioning Profiles(mobileprovision文件)
? 有新的設備加進來之后,不用更新證書,只需 到開發者中心那里,編輯你之前使用的 配置文件,重新把新設備的UDID 包含進來,然后重新下載,在本地雙擊安裝即可(雙擊后自動更新了本地同名的配置文件)。
? ?iPad 的UDID 的獲取方法跟 iPhone的方式一樣。
mobileprovision文件包含:
AppId。每個app必須在MC中創建一個對應的AppId。
使用哪些證書。上面說了,不同類型的證書就代表了不同的發布方式,還包括一些功能的能否使用(比如APN)
功能授權列表
可安裝的設備列表。對于AdHoc方式發布的app或者真機調試時,會有一個列表,這個列表里面是iOS設備的UDID,每臺iOS設備出廠的UDID都不同,所以可以用來標識設備。可通過iTunes連接設備,或者http://fir.im/udid這里獲取
蘋果的簽名!
注意5,這里的簽名是蘋果簽的,跟我們的私鑰沒有關系。也就是說mobileprovision文件是蘋果簽名的,我們除了從MC中獲取,別無他法。也不能再獲取后隨意篡改(比如添加別的設備)。因此上面的1-4就被蘋果牢牢的控制在手里,所有的規則都必須由蘋果來制定和約束。
? ? ? ?描述文件描述了可由哪臺電腦,把哪個App,安裝到哪臺手機上面。一個描述文件的制作是需要上面的一些信息的。所以蘋果在Member Center中把這個文件的制作排在最后面是很合理的。描述文件其實可以分為兩種類型,一種是帶有device信息的;而另一種是不帶device信息的。
帶device信息的描述文件
? ? ? 這種類型的描述文件包括所有開發類型的描述文件和發布到Ad Hoc上面的描述文件,因為做這些事情的時候,都有很明確的目的,這個App要安裝到哪臺設備上面。
不帶device信息的描述文件
? ? ? 不帶device信息的描述文件只有發布到App Store和In House兩種情況下才使用這個描述文件,因為通過這兩個渠道發布的App我們是不能確定將來那一臺設備才會安裝,只讓也就不會帶有App的信息。
ipa的組成
iOS程序最終都會以.ipa文件導出,先來了解一下ipa文件的結構:
事實上,ipa文件只是一個zip包,可以使用如下命令解壓:
/usr/bin/unzip -q xxx.ipa -d
解壓后,得到上圖的Payload目錄,下面是個子目錄,其中的內容如下:
資源文件,例如圖片、html、等等。
_CodeSignature/CodeResources。這是一個plist文件,可用文本查看,其中的內容就是是程序包中(不包括Frameworks)所有文件的簽名。注意這里是所有文件。意味著你的程序一旦簽名,就不能更改其中任何的東西,包括資源文件和可執行文件本身。iOS系統會檢查這些簽名。
可執行文件。此文件跟資源文件一樣需要簽名。
一個mobileprovision文件.打包的時候使用的,從MC上生成的。
Frameworks。程序引用的非系統自帶的Frameworks,每個Frameworks其實就是一個app,其中的結構應該和app差不多,也包含簽名信息CodeResources文件
iOS設備如何驗證app是否合法
? 關鍵的幾個點:
解壓ipa
取出embedded.mobileprovision,通過簽名校驗是否被篡改過
其中有幾個證書的公鑰,其中開發證書和發布證書用于校驗簽名
BundleId
授權列表
校驗所有文件的簽名,包括Frameworks
比對Info.plist里面的BundleId是否符合embedded.mobileprovision文件中的
總結
? ? ? 蘋果通過證書來授權開發者開發iOS應用,不同的證書具有不同的用處,建議申請時使用相同的請求文件(即保證私鑰統一)。可以通過共享私鑰的方式讓團隊使用相同的私鑰和證書,已方便開發。為了保證app的安全性,app中所有的文件都會被簽名,這樣,簽過名的app除非重新簽名,否則無法改動其中的任何東西。
? ? ? ?mobileprovision是一個配置文件,由蘋果簽名并發布給開發者。配置文件是一組信息的集合,這組信息決定了某一個應用是否能夠在某一個特定的設備上運行。配置文件可以用于讓應用在你的開發設備上可以被運行和調試,也可以用于內部測試 (ad-hoc) 或者企業級應用的發布。有了配置文件,蘋果對開發者的約束就十分穩固了。所以,證書(及其對應的私鑰)和配置文件是簽名和打包的兩個必要文件。必須深刻理解,才能在日常的錯誤中找到解決辦法。
更多內容請參考: