概覽
- 數字簽名
- 簽名機制與驗證過程
- 操作流程
數字簽名
摘要算法
- 將任意長度文本通過一個算法得到一個固定長度的文本。
- 源文本不同,計算結果必然不同
- 無法從結果反推源
例如,MD5和SHA算法
非對稱加密
- 即加密密鑰與解密密鑰不同,且成對出現
- 對外公開的稱為公鑰,這對密鑰生成者才擁有的稱為私鑰
- 通過私鑰加密的密文只能通過公鑰解密,反之亦然
例如,RSA算法,非對稱加密加解密比較耗時,實際使用中,往往與對稱加密和摘要算法結合使用
數字簽名的作用是我對某一份數據打了個標記,表示我認可了這份數據(簽了個名),然后我發送給其他人,其他人可以知道這份數據是經過我認證的,數據沒有被篡改過。
哪怎么做呢?
- 生成一份非對稱加密的公鑰和私鑰,私鑰自己拿着,公鑰發布出去。
- 用一種算法,算出原始數據的摘要。常用的算法是MD5。
對一份數據,算出摘要之后,用私鑰加密這個摘要,得到一份加密后的數據,稱為原始數據的簽名。把它跟原始數據一起發送給用戶。
用戶收到數據和簽名后,用公鑰解密得到摘要,同時用戶用同樣的算法計算原始數據的摘要,比對這里計算出來的摘要和公鑰解密簽名得到的摘要是否相等,若相等則表示這份數據中途沒有被篡改過,因為如果有篡改,摘要會變化。
簽名機制與驗證過程
最簡單的簽名
蘋果官方生成一對公私鑰,在iOS里內置一個公鑰,私鑰由蘋果后台保存,我們傳App上AppStore時,蘋果后台用私鑰對App數據進行簽名,iOS系統下載這個App后,用公鑰驗證這個簽名,若簽名正確,這個App肯定由蘋果后台認證的,並且沒有被修改過,也就達到了蘋果的需求:保證安裝的每一個App都是經過蘋果認證允許的。

- 開發App時可以直接把開發中的應用安裝進手機調試;
- In-House企業內部分發,可以直接安裝企業證書簽名后的App;
- AD-Hoc相當於企業分發的限制版,限制安裝設備數量。
iOS的雙層代碼簽名
安裝包不需要傳到蘋果服務器,經過蘋果認證后,可以直接安裝到手機上。
生成簽名
- 在Mac開發機器生成一對公私鑰,這里稱公鑰L,私鑰L;
- 把公鑰L上傳到蘋果后台,用蘋果后台里的私鑰A去簽名公鑰L。得到一份數據包含了公鑰L以及其簽名,把這份數據稱為證書;
- 編譯完一個 APP 后,用本地的私鑰 M(今后你導出的P12) 對這個 APP 進行簽名,同時把第三步得到的證書一起打包進 APP 里;
認證過程
- 在安裝時,iOS 系統取得證書,通過系統內置的公鑰 A,去驗證證書的數字簽名是否正確;
- 驗證證書后確保了公鑰 L 是蘋果認證過的,再用公鑰 L 去驗證 APP 的簽名。
這里就間接驗證了這個 APP 安裝行為是否經過蘋果官方允許。
描述文件
描述文件是在AppleDevelop網站創建,描述文件里面就是 可以安裝的設備有哪些,APP的ID是什么,權限是些什么!
生成簽名
- 在Mac開發機器生成一對公私鑰,這里稱公鑰L,私鑰L;
- 把公鑰L上傳到蘋果后台,用蘋果后台里的私鑰A去簽名公鑰L。得到一份數據包含了公鑰L以及其簽名,把這份數據稱為證書,和一份描述文件;
- 編譯完一個 APP 后,用本地的私鑰M對這個APP進行簽名,同時把從蘋果服務器得到的 Provisioning Profile 文件打包進APP里,文件名為embedded.mobileprovision
認證過程
- 在安裝時,iOS 系統取得證書,通過系統內置的公鑰 A,去驗證證書的數字簽名是否正確;
- 通過系統內置的公鑰 A,解密拿到描述文件,查看里面的設備列表時候包含當前設備;
- 驗證證書后確保了公鑰 L 是蘋果認證過的,再用公鑰 L 去驗證 APP 的簽名;
- 驗證描述文件里的AppID是否與當前App的AppID一致,App申請的功能時候與描述文件一致;
操作流程
- 第 1 步對應的是 keychain 里的 “從證書頒發機構請求證書”,這里就本地生成了一對公私鑰,保存的 CertificateSigningRequest 里面就包含公鑰,私鑰保存在本地電腦里.
- 第 2 步向蘋果申請對應把 CSR 傳到蘋果后台生成證書.
-
第 3 步證書下載到本地.這時本地有兩個證書.一個是第 1 步生成的私鑰,一個是這里下載回來的證書,keychain 會把這兩個證書關聯起來,因為他們公私鑰是對應的,在XCode選擇下載回來的證書時,實際上會找到 keychain 里對應的私鑰去簽名.這里私鑰只有生成它的這台 Mac 有,如果別的 Mac 也要編譯簽名這個 App 怎么辦?答案是把私鑰導出給其他 Mac 用,在 keychain 里導出私鑰,就會存成 .p12 文件,其他 Mac 打開后就導入了這個私鑰.
- 第 4 步都是在蘋果網站上操作,配置 AppID / 權限 / 設備等,最后下載 Provisioning Profile 文件。
- 第 5 步 XCode 會通過第 3 步下載回來的證書(存着公鑰),在本地找到對應的私鑰(第一步生成的),用本地私鑰去簽名 App,並把 Provisioning Profile 文件命名為 embedded.mobileprovision 一起打包進去。所以任何本地調試的APP,都會有一個embedded.mobileprovision(描述文件)從App Store下載的沒有.
說在最后
AppStore的簽名驗證方式有些不一樣,前面我們說到最簡單的簽名方式,蘋果在后台直接用私鑰簽名App就可以了,實際上蘋果確實是這樣做的,如果去下載一個AppStore的安裝包,會發現它里面是沒有embedded.mobileprovision文件的,也就是它安裝和啟動的流程是不依賴這個文件,驗證流程也就跟上述幾種類型不一樣了。
據猜測,因為上傳到AppStore的包蘋果會重新對內容加密,原來的本地私鑰簽名就沒有用了,需要重新簽名,從AppStore下載的包蘋果也並不打算控制它的有效期,不需要內置一個embedded.mobileprovision去做校驗,直接在蘋果用后台的私鑰重新簽名,iOS安裝時用本地公鑰驗證App簽名就可以了。
那為什么發布AppStore的包還是要跟開發版一樣搞各種證書和Provisioning Profile?猜測因為蘋果想做統一管理,Provisioning Profile里包含一些權限控制,AppID 的檢驗等,蘋果不想在上傳AppStore 包時重新用另一種協議做一遍這些驗證,就不如統一把這部分放在 Provisioning Profile里,上傳AppStore時只要用同樣的流程驗證這個 Provisioning Profile是否合法就可以了。
所以 App 上傳到AppStore后,就跟你的 證書 / Provisioning Profile 都沒有關系了,無論他們是否過期或被廢除,都不會影響AppStore 上的安裝包。