理解iOS開發(fā)的簽名原理

一 概述

之前我在做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ù)時使用。該加密算法的安全性不僅取決于加密算法本身,密鑰管理更為重要,如何將密鑰安全地傳遞到解密者手上就成了必須要解決的問題。
常用的對稱加密:

  1. DES 數(shù)據(jù)對稱加密標準,因為加密強度不夠用得少;
  2. 3DES 使用三個密鑰對相同的數(shù)據(jù)進行三次加密;
  3. AES 高級密碼加密,美國安全局使用,Apple鑰匙串便采用該種方式。
    該算法特點:算法公開、計算量小、加密速度快,但是密鑰管理成問題。

四 非對稱加密

非對稱加密算法是指,加密密鑰和解密密鑰是不同的,一般加密密鑰和解密密鑰是成對出現(xiàn)的。公私鑰具有以下重要特性:

  • 對于一個私鑰,有且只有一個與其對應的公鑰;
  • 公鑰是公開的,但是不能通過公鑰推導出私鑰;
  • 私鑰加密的文件可用公鑰解密,同樣公鑰加密的文件可用私鑰進行解密。

目前使用最廣泛的公鑰密碼算法是RSA。RSA的名字有3位開發(fā)者,即Ron Rivest、Adi Shamir、Leonard Adleman的姓氏首字母組成。

非對稱加密雖然安全性較高,但是加密速度較慢,不適合對大量數(shù)據(jù)進行加密.
了解了以上知識點,接下來便是數(shù)字簽名原理

五 數(shù)字簽名

數(shù)字簽名實際上就是將摘要算法非對稱加密算法結(jié)合起來,其設計的目的是保證數(shù)據(jù)文件的完整性,防止中途被中間人篡改。

數(shù)字簽名處理流程圖.png

如上圖,當我們手上數(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ā)送者手中的公鑰是來自于中間人給的,那么這個過程便又不安全,具體過程可以看如下圖:


數(shù)據(jù)劫持.png

服務器端發(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公鑰解密簽名,以此來驗證我們給出的公鑰是否正確。


CA頒發(fā)證書.png

數(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文件,該文件中主要包含以下信息:
  1. 申請者信息,此信息是用申請者的私鑰加密的
  2. 申請者公鑰,此信息是申請者使用的私鑰對應的公鑰
  3. 摘要算法和公鑰加密算法

可以采用openssl來解析文件中內(nèi)容:

openssl asn1parse -i -in CertificateSigningRequest.certSigningRequest
CertificateSigningRequest.certSigningRequest.png

為什么要上傳這個信息呢?因為后續(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上按住空格預覽,截圖如下:


cer證書內(nèi)容.png

其中主要包含摘要算法和RSA加密公鑰,以及一個apple的簽名。雙擊安裝證書后,KeyChain子自動將這公鑰和本地私鑰關聯(lián)起來。后續(xù)程序在真機上build時,會使用本地私鑰進行代碼簽名,而公鑰會附帶人mobileprovision文件中去,打包進app。

note: 實際上公鑰是放在了mobileprovision文件中,并不是隨代碼一同打包的,所以我認為我們mac上安裝的證書沒有實際用處,因為mobileprovision是MC為我們生成的。其實安裝證書的主要目的應該是區(qū)別對應的私鑰,真正用于簽名的是私鑰,如果本地有多個不同的證書,那就有多個私鑰,所以需要依靠不同證書來區(qū)分到底用哪種私鑰進行codesign。mobileprovision我會在后面講解。所以,有證書卻沒有私鑰還是沒用的。

既然私鑰是某臺電腦上生成的,那么團隊如何開發(fā)呢?
其實我們可以從鑰匙串中給安裝好的證書導出.p12文件,在其他機器上安裝即可共享私鑰和證書了。
我們下載下來的證書也是有很多種類的,就好像你需要駕駛證才能開機動車,你需要護照才能出國,用途不同,證書也不同。如下是展示部分證書類型:

  1. iOS App Development。開發(fā)、真機調(diào)試用
  2. Apple Push Notification service SSL (Sandbox)。開發(fā)階段使用蘋果的推送服務
  3. App Store and Ad Hoc。上架和AdHoc方式發(fā)布時用
  4. 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

截圖如下:


配置文件1.png

配置文件2.png

描述文件主要包含了:

  1. AppId。
  2. 使用哪些證書。
  3. 功能授權(quán)列表
  4. 可安裝的設備列表。對于AdHoc方式發(fā)布的app或者真機調(diào)試時,會有一個列表,這個列表里面是iOS設備的UDID,每臺iOS設備出廠的UDID都不同。
  5. 蘋果的簽名。這里的簽名是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>

顯示截圖如下:


ipa壓縮包.png

其中,_CodeSignature文件中保存著一個plist文件,其內(nèi)容是程序包中所有文件的簽名,不包含F(xiàn)rameworks文件的簽名。mobileprovision文件是打包時使用的,從MC上生成的。Frameworks文件中是引入的第三方框架,每個框架結(jié)構(gòu)類似一個app,也有自己的代碼簽名。


iipa文件內(nèi)容.png

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)如下圖所示:

各種密鑰及其存儲.png

下圖是真機調(diào)試的整個流程圖:
ipa安裝和驗證全流程.png

整個過程主要是圍繞App完整性和驗證開發(fā)者的權(quán)限設計的。大致思路如下:

  1. 將Mac公鑰等核心信息上傳至MC,MC會用apple私鑰簽好名一起打包到數(shù)字證書中;
  2. 在MC上配置app權(quán)限和任務會生成相應的配置文件,該文件會被MC用apple私鑰做簽名,然后一起打包放入mobileprovision文件中,以供用戶下載安裝到xcode中;
  3. 當xcode在真機上調(diào)試app,我們的代碼資源會被mac私鑰加密簽名生成數(shù)字簽名,然后與描述文件一起打包進ipa壓縮包中;
  4. iOS設備接收到ipa壓縮包,會先用本地存儲的apple公鑰進行簽名驗證,查看描述文件是否安全;
  5. 如果4安全,則提取描述文件中的數(shù)字證書,并用apple公鑰來驗證數(shù)字證書是否安全,如果安全,則取出證書中的Mac公鑰;
  6. 將取出的Mac公鑰用于驗證App的代碼簽名,如果驗證沒問題,再按照mobileprovision文件查看app所有權(quán)限和功能,如果everything ok,那么app就可以安裝在真機上了。

九 iOS app從appStore下載的驗證流程

appstore下載驗證流程.png

從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>

HTTPs流程圖.png

對照該流程圖,我將分步詳細說明:

  1. 對于一個服務器開發(fā)商而言,想要采用SSL/TSL協(xié)議,則必須先從CA機構(gòu)獲取證書。這需要先將服務器支持的非對稱加密的公鑰(本文簡稱Server公鑰)和服務器運營商的注冊信息等一起發(fā)給CA去審核;
  2. CA審核通過后,會將Server公鑰和網(wǎng)站注冊信息以及一個CA的數(shù)字簽名一同打包到數(shù)字證書中。其中數(shù)字簽名是用CA私鑰加密的,需要CA公鑰來驗證,而CA公鑰是分發(fā)到各個操作系統(tǒng)中的;
  3. 當服務器有了數(shù)字證書,之后瀏覽器或者客戶端在向該服務器的站點發(fā)送request,便可以將CA證書返回;
  4. 瀏覽器或者客戶端向服務器站點發(fā)送request,需要先把其所支持的Hash算法、對稱加密算法、非對稱加密算法,以及瀏覽器的一些配置信息發(fā)送出去;
  5. 服務器在收到后,從這些算法中選擇自己也支持的Hash、對稱、非對稱算法和CA數(shù)字證書一同發(fā)送給請求者;
  6. 客戶端本地拿到CA證書之后,會用本地CA公鑰先進行數(shù)字簽名的驗證,如果驗證失敗,則斷開連接,否則取出CA證書中的server公鑰;
  7. 客戶端生成一個隨機的key,并且用server公鑰進行加密,生成一個key的密文;然后用key對本次握手進行Hash計算,并將計算結(jié)果用key進行對稱加密,生成一個握手消息的密文。最后將這兩個密文一起發(fā)送給服務器;
  8. 服務器拿到兩個密文后,先用本地server公鑰解密獲取key,然后用key對握手消息密文解密拿到該hash值,并且自己也用相同摘要算法對握手消息進行hash計算,將兩個hash值進行對比,如果不一致,則斷開連接,否則用key對稱加密服務器端信息,然后發(fā)送給請求者。至此基于安全協(xié)議SSL的握手階段結(jié)束,后續(xù)客戶端和服務器都會用key來對收發(fā)的消息進行對稱加密解密。
    上述過程屬于單向認證的SSL協(xié)議的握手規(guī)則,但也有雙向的認證的SSL協(xié)議的通訊,即要求服務器和用戶雙方都要有證書,雙方都驗證對方的證書的數(shù)字簽名。

總結(jié)

  1. 本文主要先介紹了摘要算法、對稱加密算法、非對稱加密算法,在于此基礎上講解了何為數(shù)字簽名、何為數(shù)字證書,以及兩者的關聯(lián)和作用;
  2. 接著本文家講解了Xcode上打包ipa的處理流程,以及在真機上build的apple驗證機制。同時也解釋了appstore上下載app的驗證流程;
  3. 最后未來更好了幫助大家理解這些加密算法的應用場景,例舉了HTTPs的通訊原理。
    希望本文對大家有所幫助,如果不當之處,還希望大家及時給我留言,共勉!
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,698評論 6 539
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,202評論 3 426
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 177,742評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,580評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,297評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,688評論 1 327
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,693評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,875評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,438評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,183評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,384評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,931評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,612評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,022評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,297評論 1 292
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,093評論 3 397
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,330評論 2 377

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