Apple App簽名機制


概覽

  • 數字簽名
  • 簽名機制與驗證過程
  • 操作流程

數字簽名

  摘要算法

  1. 將任意長度文本通過一個算法得到一個固定長度的文本。 
  2. 源文本不同,計算結果必然不同 
  3. 無法從結果反推源

  例如,MD5和SHA算法

  非對稱加密

  1. 即加密密鑰與解密密鑰不同,且成對出現 
  2. 對外公開的稱為公鑰,這對密鑰生成者才擁有的稱為私鑰 
  3. 通過私鑰加密的密文只能通過公鑰解密,反之亦然 

  例如,RSA算法,非對稱加密加解密比較耗時,實際使用中,往往與對稱加密和摘要算法結合使用

 

數字簽名的作用是我對某一份數據打了個標記,表示我認可了這份數據(簽了個名),然后我發送給其他人,其他人可以知道這份數據是經過我認證的,數據沒有被篡改過。

哪怎么做呢?

  1. 生成一份非對稱加密的公鑰和私鑰,私鑰自己拿着,公鑰發布出去。
  2. 用一種算法,算出原始數據的摘要。常用的算法是MD5。

對一份數據,算出摘要之后,用私鑰加密這個摘要,得到一份加密后的數據,稱為原始數據的簽名。把它跟原始數據一起發送給用戶。

用戶收到數據和簽名后,用公鑰解密得到摘要,同時用戶用同樣的算法計算原始數據的摘要,比對這里計算出來的摘要和公鑰解密簽名得到的摘要是否相等,若相等則表示這份數據中途沒有被篡改過,因為如果有篡改,摘要會變化。

簽名機制與驗證過程

  最簡單的簽名  

蘋果官方生成一對公私鑰,在iOS里內置一個公鑰,私鑰由蘋果后台保存,我們傳App上AppStore時,蘋果后台用私鑰對App數據進行簽名,iOS系統下載這個App后,用公鑰驗證這個簽名,若簽名正確,這個App肯定由蘋果后台認證的,並且沒有被修改過,也就達到了蘋果的需求:保證安裝的每一個App都是經過蘋果認證允許的。

 
但是實際上開發APP還有其他渠道來安裝。
  • 開發App時可以直接把開發中的應用安裝進手機調試;
  • In-House企業內部分發,可以直接安裝企業證書簽名后的App;
  • AD-Hoc相當於企業分發的限制版,限制安裝設備數量。
 

iOS的雙層代碼簽名

  安裝包不需要傳到蘋果服務器,經過蘋果認證后,可以直接安裝到手機上。

生成簽名

  1. 在Mac開發機器生成一對公私鑰,這里稱公鑰L,私鑰L;
  2. 把公鑰L上傳到蘋果后台,用蘋果后台里的私鑰A去簽名公鑰L。得到一份數據包含了公鑰L以及其簽名,把這份數據稱為證書;
  3. 編譯完一個 APP 后,用本地的私鑰 M(今后你導出的P12) 對這個 APP 進行簽名,同時把第三步得到的證書一起打包進 APP 里;

認證過程

  1. 在安裝時,iOS 系統取得證書,通過系統內置的公鑰 A,去驗證證書的數字簽名是否正確;
  2. 驗證證書后確保了公鑰 L 是蘋果認證過的,再用公鑰 L 去驗證 APP 的簽名。

這里就間接驗證了這個 APP 安裝行為是否經過蘋果官方允許。

但是這種簽名方式並不能解決應用濫用的問題,所以蘋果又加了兩個限制.第一限制在蘋果后台注冊過的設備才可以安裝.第二限制簽名只能針對某一個具體的APP.並且蘋果還想控制App里面的iCloud/PUSH/后台運行/調試器附加這些權限,所以蘋果把這些權限開關統一稱為Entitlements(授權文件).並將這個文件放在了一個叫做Provisioning Profile(描述文件)文件中。

描述文件

描述文件是在AppleDevelop網站創建,描述文件里面就是 可以安裝的設備有哪些,APP的ID是什么,權限是些什么!

加上這個東西后這個簽名機制是什么樣呢?
 

 

生成簽名

  1. 在Mac開發機器生成一對公私鑰,這里稱公鑰L,私鑰L;
  2. 把公鑰L上傳到蘋果后台,用蘋果后台里的私鑰A去簽名公鑰L。得到一份數據包含了公鑰L以及其簽名,把這份數據稱為證書,和一份描述文件
  3. 編譯完一個 APP 后,用本地的私鑰M對這個APP進行簽名,同時把從蘋果服務器得到的 Provisioning Profile 文件打包進APP里,文件名為embedded.mobileprovision

認證過程

  1. 在安裝時,iOS 系統取得證書,通過系統內置的公鑰 A,去驗證證書的數字簽名是否正確;
  2. 通過系統內置的公鑰 A,解密拿到描述文件,查看里面的設備列表時候包含當前設備;
  3. 驗證證書后確保了公鑰 L 是蘋果認證過的,再用公鑰 L 去驗證 APP 的簽名;
  4. 驗證描述文件里的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 上的安裝包。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM