一 概述
之前我在做iOS項目開發(fā)時,由于采用的是自己的開發(fā)者賬號,在Xcode的General配置中勾選上Automatically manager signing
便再也不用管證書等一些問題,所有的一切都是由xcode自己來給你做。但是當涉及到團隊開發(fā),有時候需要共享一個數(shù)字證書和mobileprovision文件時,便有層出不窮的問題。盡管有些google一下也能解決,但是并不了解其實質(zhì)原理,為何要這么做。
如果你對Provision profile
(稱為配置文件or描述文件)、CertificateSigningRequest
、P12
、Cer
等等這些證書一知半解,相信本文可以解答你心中的疑惑。
本文會從原理出發(fā),一步步解釋iOS簽名的各個處理流程,主要章節(jié)如下:
- 摘要算法
- 對稱加密算法
- 非對稱加密算法
- 數(shù)字簽名
- 數(shù)字證書
- iOS簽名機制與配置文件
- iOS上build的處理流程
- iOS app從appStore下載的驗證流程
- 加密算法在 HTTPS上的應用
二 摘要算法
摘要算法又稱為哈希算法,可以將任意長度的數(shù)據(jù)流通過hash計算,輸出固定長度的數(shù)據(jù),相同輸入的數(shù)據(jù)始終得到相同的輸出。
常用的hash算法有:
MD5
輸出長度:128bit
SHA-1
輸出長度:160bit
SHA-256
輸出長度:256bit
由于輸出長度是固定的并且輸出輸入的長度不固定,這就意味著兩個不同的輸入可能得到相同的輸出,這就是碰撞的問題。所以在設計Hash算法時盡量使其碰撞率低,并且安全的hash算法很難從輸入反推出輸入,只能依靠暴力窮舉。
特征: 不同數(shù)據(jù)的計算結(jié)果不同、不可逆
三 對稱加密算法
對稱加密,也稱單鑰加密,同一個密鑰可以加密和解密。由于其速度快,對稱性加密通常在消息發(fā)送方需要加密大量數(shù)據(jù)時使用。該加密算法的安全性不僅取決于加密算法本身,密鑰管理更為重要,如何將密鑰安全地傳遞到解密者手上就成了必須要解決的問題。
常用的對稱加密:
-
DES
數(shù)據(jù)對稱加密標準,因為加密強度不夠用得少; -
3DES
使用三個密鑰對相同的數(shù)據(jù)進行三次加密; -
AES
高級密碼加密,美國安全局使用,Apple鑰匙串便采用該種方式。
該算法特點:算法公開、計算量小、加密速度快,但是密鑰管理成問題。
四 非對稱加密
非對稱加密算法是指,加密密鑰和解密密鑰是不同的,一般加密密鑰和解密密鑰是成對出現(xiàn)的。公私鑰具有以下重要特性:
- 對于一個私鑰,有且只有一個與其對應的公鑰;
- 公鑰是公開的,但是不能通過公鑰推導出私鑰;
- 私鑰加密的文件可用公鑰解密,同樣公鑰加密的文件可用私鑰進行解密。
目前使用最廣泛的公鑰密碼算法是RSA。RSA的名字有3位開發(fā)者,即Ron Rivest、Adi Shamir、Leonard Adleman的姓氏首字母組成。
非對稱加密雖然安全性較高,但是加密速度較慢,不適合對大量數(shù)據(jù)進行加密.
了解了以上知識點,接下來便是數(shù)字簽名原理
五 數(shù)字簽名
數(shù)字簽名實際上就是將摘要算法和非對稱加密算法結(jié)合起來,其設計的目的是保證數(shù)據(jù)文件的完整性,防止中途被中間人篡改。
如上圖,當我們手上數(shù)據(jù)內(nèi)容需要上傳到服務器端,則首先將數(shù)據(jù)內(nèi)容采用MD5的hash算法生成一個32個字符摘要,然后在用RSA公鑰進行加密生成密文,即數(shù)字簽名。
而上傳到服務器的內(nèi)容則由數(shù)據(jù)內(nèi)容和數(shù)字簽名構(gòu)成,服務器拿到數(shù)據(jù)包后先將數(shù)字簽名采用RSA的私鑰進行解密拿到之前的摘要,再將獲取到的數(shù)據(jù)內(nèi)容采用md5算法得到該內(nèi)容的hash摘要值,最后將這兩個摘要進行對比,如果一致則數(shù)據(jù)完好無鎖。
note:加密后為128位(bit),按照16進制(4位一個16進制數(shù))編碼后,就成了32個字符
這個過程僅對md5加密是為了減少非對稱加解密所耗費的時間。數(shù)字簽名可以快速的驗證文本的安全性和合法性。理解了數(shù)字簽名,可以進一步來理解數(shù)字證書。
六 數(shù)字證書
簽名過程看起來已經(jīng)足夠安全,數(shù)據(jù)接收方通過發(fā)送公鑰對簽名進行解密,便可以驗證發(fā)送者的數(shù)據(jù)完整性和安全性。但是如果接收方手中的公鑰已經(jīng)被中間人劫持,而真正到達發(fā)送者手中的公鑰是來自于中間人給的,那么這個過程便又不安全,具體過程可以看如下圖:
服務器端發(fā)送的公鑰讓中間人劫持了,中間人把自己的公鑰發(fā)給用戶,而用戶便用此公鑰加密數(shù)據(jù)發(fā)送給服務器,而此時的服務器其實已經(jīng)是中間人了。中間人再次劫持用戶的數(shù)據(jù)并用自己的私鑰解密,然后用真正服務器端的公鑰加密自己篡改的數(shù)據(jù)發(fā)送給服務器。
對于這樣的問題,有一種目前通用的解決方案。找一個可以信任的數(shù)字證書機構(gòu)(Certificate Authority,CA),將我們的公鑰和注冊信息交給CA。CA將我們的合法信息和公鑰利用非對稱加密(CA自己的私鑰)生成密文(即數(shù)字簽名),再將簽名和我們的公鑰信息打包成證書給我們。下次用戶如果需要向我們發(fā)送消息,需要先去CA上請求CA公鑰,然后我們給用戶證書,用戶再去用CA公鑰解密簽名,以此來驗證我們給出的公鑰是否正確。
數(shù)字證書和生活中的證書一樣,例如駕駛證、英語四六級證書等等,數(shù)字證書的簽發(fā)機構(gòu)也有若干,例如蘋果公司就可以簽發(fā)apple開發(fā)相關證書,而web相關的證書也有幾家國際公認的機構(gòu)進行簽發(fā),這些機構(gòu)稱為CA。
七 iOS簽名機制與配置文件
iOS簽名機制的作用:保證安裝到手機上的app都是經(jīng)過Apple官方驗證和許可的。不管真機調(diào)試,還是發(fā)布App,開發(fā)者都必須經(jīng)過一些列復雜的步驟,下面我將詳細的說明這些。
-
第一步 上傳本地開發(fā)者的公鑰信息到MC
具體操作就是從mac上鑰匙串中生成一個CertificateSigningRequest.certSigningRequest
文件,該文件中主要包含以下信息:
- 申請者信息,此信息是用申請者的私鑰加密的
- 申請者公鑰,此信息是申請者使用的私鑰對應的公鑰
- 摘要算法和公鑰加密算法
可以采用openssl來解析文件中內(nèi)容:
openssl asn1parse -i -in CertificateSigningRequest.certSigningRequest
為什么要上傳這個信息呢?因為后續(xù)我們在用xcode構(gòu)建項目時,需要對可執(zhí)行文件進行簽名(即采用本地摘要算法先進行hash計算,然后在使用本地私鑰進行加密),如果MC拿不到我們的公鑰,那么如何進行非對稱解密,如何驗證我們app是否完整呢!
拿到CRS文件后上傳到MC。
-
第二步 從MC下載apple頒發(fā)的Cer證書
上一步上傳完CSR文件后,可以根據(jù)我們的需求配置證書相關的信息,例如bundleID,Push、Apple Pay等等,然后我們將MC生成的證書下載并安裝到本地鑰匙串中,如下圖:
cer證書下載.png
其實MC在拿到我們上傳CSR文件后,提取里面的公鑰,它需要做的便是將MC中關于我的賬號信息和剛剛提交的公鑰打包,再進行數(shù)字簽名,最后封裝到cer證書中。
我們可以用openssl來看一下cer文件內(nèi)容:
openssl x509 -inform der -in ios_development.cer -noout -text
也可以直接在mac上按住空格預覽,截圖如下:
其中主要包含摘要算法和RSA加密公鑰,以及一個apple的簽名。雙擊安裝證書后,KeyChain子自動將這公鑰和本地私鑰關聯(lián)起來。后續(xù)程序在真機上build時,會使用本地私鑰進行代碼簽名,而公鑰會附帶人mobileprovision文件中去,打包進app。
note: 實際上公鑰是放在了
mobileprovision
文件中,并不是隨代碼一同打包的,所以我認為我們mac上安裝的證書沒有實際用處,因為mobileprovision
是MC為我們生成的。其實安裝證書的主要目的應該是區(qū)別對應的私鑰,真正用于簽名的是私鑰,如果本地有多個不同的證書,那就有多個私鑰,所以需要依靠不同證書來區(qū)分到底用哪種私鑰進行codesign。mobileprovision
我會在后面講解。所以,有證書卻沒有私鑰還是沒用的。
既然私鑰是某臺電腦上生成的,那么團隊如何開發(fā)呢?
其實我們可以從鑰匙串中給安裝好的證書導出.p12
文件,在其他機器上安裝即可共享私鑰和證書了。
我們下載下來的證書也是有很多種類的,就好像你需要駕駛證才能開機動車,你需要護照才能出國,用途不同,證書也不同。如下是展示部分證書類型:
- iOS App Development。開發(fā)、真機調(diào)試用
- Apple Push Notification service SSL (Sandbox)。開發(fā)階段使用蘋果的推送服務
- App Store and Ad Hoc。上架和AdHoc方式發(fā)布時用
- Apple Push Notification service SSL (Production)。上架后使用蘋果推送服務
5.0 In-House。企業(yè)版發(fā)布,需$299才能擁有,還需鄧氏編碼
-
第三步 配置iOS mobileprovision文件
證書只保證了app的所屬和完整性,卻不能保證app的某些功能和服務是被蘋果認可的,例如APNs和apple pay等等。所以,蘋果想出了坑爹作死的mobileprovision
。
可以用如下命令查看描述文件的內(nèi)容:
security cms -D -i embedded.mobileprovision
截圖如下:
描述文件主要包含了:
- AppId。
- 使用哪些證書。
- 功能授權(quán)列表
- 可安裝的設備列表。對于AdHoc方式發(fā)布的app或者真機調(diào)試時,會有一個列表,這個列表里面是iOS設備的UDID,每臺iOS設備出廠的UDID都不同。
- 蘋果的簽名。這里的簽名是apple的私鑰簽名的,不是我們本地的私鑰,我們除了從MC中下載,沒有其他方法,如果我們篡改了相關信息,則文件失效。因此app的各種權(quán)利完全被apple牢牢掌控著。
如果采用Adhoc發(fā)布呢?
Adhoc允許將beta版發(fā)布給最多100臺設備安裝,apple便是通過這里描述文件的第四條來牢牢掌控,只需要描述文件中有相關設備的UDID便可以,而這些UDID需要事先添加到MC的Devices中去。
以上便是iOS簽名機制和描述文件的詳細講解,下面會繼續(xù)嗨聊iOS作死的代碼簽名。
八 iOS上build的處理流程
我們平時用VS或者clion編一些C/C++時,幾乎都是走code-build-link-run流程,無需其他什么認證,但是由于apple的嚴格生態(tài)規(guī)則,必須要驗證開發(fā)者身份和權(quán)限。
8.1 build
當我們在xcode上進行build時,apple首先去驗證開發(fā)者,根據(jù)用戶所選的證書從鑰匙串中匹配到相應的私鑰,再利用私鑰對代碼和資源文件簽名生成一個_CodeSignature
文件,然后與資源文件、app文件、描述文件、Framework文件一同打包到.ipa
壓縮包中。
我們可以打開一個.ipa
壓縮包,
unzip -q <name> -d <destination>
顯示截圖如下:
其中,_CodeSignature文件中保存著一個plist文件,其內(nèi)容是程序包中所有文件的簽名,不包含F(xiàn)rameworks文件的簽名。mobileprovision文件是打包時使用的,從MC上生成的。Frameworks文件中是引入的第三方框架,每個框架結(jié)構(gòu)類似一個app,也有自己的代碼簽名。
8.2 校驗
當ipa文件復制到iOS設備上,iOS設備會先拿到描述文件,然后先利用iOS設備本地存儲的apple MC的公鑰來驗證描述文件的簽名,已確保描述文件沒有問題。之后取出描述文件中的數(shù)字證書,同樣利用本地apple MC的公鑰來驗證證書簽名,確保證書沒有被篡改,沒有問題的情況下繼續(xù)出去證書中保存的Mac本地的公鑰,利用公鑰來驗證_CodeSignature
代碼簽名文件沒有問題,最后按照描述文件中配置的app功能權(quán)限檢測app是否有越權(quán)行為,以上驗證都沒有問題則可以在iOS設備上安裝app了。
8.3 iOS真機調(diào)試的整個流程
首先mac設備本地存有公鑰私鑰,用于加解密項目文件;然后MC上(即apple Member center)存有apple的私鑰,用于加密供我們下載使用的數(shù)字證書和描述文件;最后在iOS設備上會存著apple的私鑰,用于解密描述文件和數(shù)字證書中的簽名。結(jié)構(gòu)如下圖所示:
下圖是真機調(diào)試的整個流程圖:
整個過程主要是圍繞App完整性和驗證開發(fā)者的權(quán)限設計的。大致思路如下:
- 將Mac公鑰等核心信息上傳至MC,MC會用apple私鑰簽好名一起打包到數(shù)字證書中;
- 在MC上配置app權(quán)限和任務會生成相應的配置文件,該文件會被MC用apple私鑰做簽名,然后一起打包放入
mobileprovision
文件中,以供用戶下載安裝到xcode中; - 當xcode在真機上調(diào)試app,我們的代碼資源會被mac私鑰加密簽名生成數(shù)字簽名,然后與描述文件一起打包進ipa壓縮包中;
- iOS設備接收到ipa壓縮包,會先用本地存儲的apple公鑰進行簽名驗證,查看描述文件是否安全;
- 如果4安全,則提取描述文件中的數(shù)字證書,并用apple公鑰來驗證數(shù)字證書是否安全,如果安全,則取出證書中的Mac公鑰;
- 將取出的Mac公鑰用于驗證App的代碼簽名,如果驗證沒問題,再按照
mobileprovision
文件查看app所有權(quán)限和功能,如果everything ok,那么app就可以安裝在真機上了。
九 iOS app從appStore下載的驗證流程
從appStore下載驗證流程就簡單的多,通過pp助手等第三方工具下載一些線上的ipa文件,你會發(fā)現(xiàn)它里面沒有
mobileprovision文件
。處理流程如下:1 當從appstore下載app,appStore會用apple私鑰對app進行數(shù)字簽名;
2 iOS設備拿到資源包后,會用本地apple公鑰來驗證數(shù)字簽名是否正確,如果正確,則安裝。
因為數(shù)據(jù)是來自于apple服務器,所以apple只需要保證app的完整性就好,防止中途被篡改。
簽名小結(jié)
至此,我已經(jīng)大致介紹了Xcode本地構(gòu)建和iOS設備上的一些身份驗證機制,其實整套流程就是對摘要算法和非對稱加密的封裝和應用。同時apple未來加強對于xcode本地構(gòu)建項目的權(quán)限而設計了一個mobileprovision文件
的概念,這里只要區(qū)分好Hash摘要算法、非對稱加密算法、數(shù)字簽名、證書、描述文件等等概念,其實整套驗證機制就不那么困難了,下次再遇到證書問題、簽名問題,就不在需要不斷google問別人怎么做的,直接對癥下藥了。
最后,為了更好的理解摘要算法和非對稱加密算法,我再講解一下HTTPS的實現(xiàn)原理。
十 加密算法在 HTTPS上的應用
HTTP是常見的應用層協(xié)議,是超文本傳輸協(xié)議的總稱,其傳輸內(nèi)容都是明文的,對此有一萬種方式來劫持數(shù)據(jù)流,所以非常不安全。Https便應運而生,稍微犧牲一些速度而換取數(shù)據(jù)的傳輸安全,其中“s”表示SSL或TLS協(xié)議,就是在原有http的基礎上加上一層數(shù)據(jù)加解密的安全層。
整個HTTPs的處理流程如下圖:(PS畫圖不易哇?。?br>
對照該流程圖,我將分步詳細說明:
- 對于一個服務器開發(fā)商而言,想要采用SSL/TSL協(xié)議,則必須先從CA機構(gòu)獲取證書。這需要先將服務器支持的
非對稱加密的公鑰
(本文簡稱Server公鑰)和服務器運營商的注冊信息等一起發(fā)給CA去審核; - CA審核通過后,會將Server公鑰和網(wǎng)站注冊信息以及一個CA的數(shù)字簽名一同打包到數(shù)字證書中。其中數(shù)字簽名是用CA私鑰加密的,需要CA公鑰來驗證,而CA公鑰是分發(fā)到各個操作系統(tǒng)中的;
- 當服務器有了數(shù)字證書,之后瀏覽器或者客戶端在向該服務器的站點發(fā)送request,便可以將CA證書返回;
- 瀏覽器或者客戶端向服務器站點發(fā)送request,需要先把其所支持的Hash算法、對稱加密算法、非對稱加密算法,以及瀏覽器的一些配置信息發(fā)送出去;
- 服務器在收到后,從這些算法中選擇自己也支持的Hash、對稱、非對稱算法和CA數(shù)字證書一同發(fā)送給請求者;
- 客戶端本地拿到CA證書之后,會用本地CA公鑰先進行數(shù)字簽名的驗證,如果驗證失敗,則斷開連接,否則取出CA證書中的
server公鑰
; - 客戶端生成一個隨機的
key
,并且用server公鑰
進行加密,生成一個key
的密文;然后用key
對本次握手進行Hash計算,并將計算結(jié)果用key
進行對稱加密,生成一個握手消息的密文。最后將這兩個密文一起發(fā)送給服務器; - 服務器拿到兩個密文后,先用本地
server公鑰
解密獲取key
,然后用key
對握手消息密文解密拿到該hash值,并且自己也用相同摘要算法對握手消息進行hash計算,將兩個hash值進行對比,如果不一致,則斷開連接,否則用key
對稱加密服務器端信息,然后發(fā)送給請求者。至此基于安全協(xié)議SSL的握手階段結(jié)束,后續(xù)客戶端和服務器都會用key
來對收發(fā)的消息進行對稱加密解密。
上述過程屬于單向認證的SSL協(xié)議的握手規(guī)則,但也有雙向的認證的SSL協(xié)議的通訊,即要求服務器和用戶雙方都要有證書,雙方都驗證對方的證書的數(shù)字簽名。
總結(jié)
- 本文主要先介紹了摘要算法、對稱加密算法、非對稱加密算法,在于此基礎上講解了何為數(shù)字簽名、何為數(shù)字證書,以及兩者的關聯(lián)和作用;
- 接著本文家講解了Xcode上打包ipa的處理流程,以及在真機上build的apple驗證機制。同時也解釋了appstore上下載app的驗證流程;
- 最后未來更好了幫助大家理解這些加密算法的應用場景,例舉了HTTPs的通訊原理。
希望本文對大家有所幫助,如果不當之處,還希望大家及時給我留言,共勉!