天天看點

iOS Code Signing到底什麼鬼

本文參考如下資料(建議閱讀):

a). 公鑰加密算法到底什麼鬼

b). The ins and outs of code signing an iOS app

c). 代碼簽名探析

我們先從code signing的作用說起吧

1. 作用

code signing的最終作用就是保證我們在iOS上的應用從開發者機器上build出來後,到最終安裝到使用者的iOS裝置上,不會被篡改。

至于權限控制,也是基于code signing來保證的。

2. 怎麼做到的

下文的内容需要我們對公鑰加密算法有所了解,這在參考資料a中有述。

1). 如何簽名

根據參考資料b中的簽名技能,對app中的binary、script以及其他資源一一進行簽名(計算每個檔案的摘要,然後将摘要使用私鑰加密),然後把簽名過的檔案放到一個CodeResources的plist檔案中。(這個檔案存放在_CodeSignature檔案夾中),我們不妨看一個執行個體:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3. <plist version="1.0">
  4. <dict>
  5. <key>files</key>
  6. <dict>
  7. <key>[email protected]</key>
  8. <data>
  9. eanTrclP/4jBcw+pZZDeVPimJ7g=
  10. </data>
  11. <key>[email protected]~ipad.png</key>
  12. <data>
  13. eanTrclP/4jBcw+pZZDeVPimJ7g=
  14. </data>
  15. <key>[email protected]</key>
  16. <data>
  17. xEo0NvwYxXdtywn3iD8yDaF6V1A=
  18. </data>
  19. <key>[email protected]~ipad.png</key>
  20. <data>
  21. xEo0NvwYxXdtywn3iD8yDaF6V1A=
  22. </data>
  23. <key>[email protected]</key>
  24. <data>
  25. rMa2+pGtRq8pN4LRcp+dCn5Kai8=
  26. </data>
  27. <key>Base.lproj/Main.storyboardc/BYZ-38-t0r-view-8bC-Xf-vdC.nib</key>
  28. <dict>
  29. <key>hash</key>
  30. <data>
  31. t/7wowkj3how49ccMtcw+bat3sQ=
  32. </data>
  33. <key>optional</key>
  34. <true/>
  35. </dict>

完整的太大了,我們截取一小段觀摩。

可以看到key就是檔案的名稱,data就是檔案的簽名,由于這個簽名無法被篡改,是以plist檔案本身不加密也無所謂。

2). 用什麼簽名

通過前面的參考資料,我們可以了解實際上簽名唯一需要的就隻是私鑰。但在iOS應用簽名中,這還不夠,我們還需要證書,app id,權限聲明,iOS裝置,而這些材料我們又可以打包到一種叫做Provision Profile的東西中去,我們在簽名的時候(使用mac os x的codesign程式)也隻能提供provision profile來工作。

一個Provision Profile的典型結構:

iOS Code Signing到底什麼鬼

我們來逐一解析各個材料的作用和擷取途徑(下述内容包含一些臆斷的部分,我會用紅字标出,因為Apple實在是太封閉了,有些東西我還沒沒法了解到)。

a). 私鑰:實際上私鑰和公鑰總是成對工作的,缺失其中任何一個之後另一個也是廢物一個。在生成證書的時候自然而然會生成密鑰對(而且系統會自動關聯它們),是以我們放到證書中具體講述。

b). 證書:為什麼需要證書?在前面參考資料中我們了解到,證書實際上是一種身份驗證的東西,可想而知這個東西實際上隻是iOS系統單方面需要,我們簽名實際上并不會用到。證書分為Development/Production(Development/Production對程式的影響本文不予讨論),這在證書中可以看到:

iOS Code Signing到底什麼鬼

當app安裝到iOS上時,iOS系統将取用provision profile中的DeveloperCertificates中的證書來結合CodeResource對app中的檔案進行簽名驗證(證書中的公鑰可以解密簽名,具體請看參考資料中的『公鑰加密算法到底什麼鬼』),以確定app中的檔案沒有被篡改過。

通過參考資料我們了解到生成一個證書檔案需要送出一個CSR檔案到Apple,然後Apple生成證書給我們,而生成CSR檔案的時候就需要我們有密鑰對,是以生成證書的時候我們要麼會用一個已存在的密鑰對,要麼就會生成一個新的密鑰對。

c). app id:app id用于唯一辨別一個應用,一個app在生成的時候會有這個屬性,而provision profile中的application-identifier也必須與這個相比對,值得注意的是比對并不代表相等,比較貼切的比喻是大于,例如provision profile中的app id如果是*,那将可用于給任何一個app進行簽名。但當我們需要用到一些比較特殊的服務的時候就需要provision profile中的app id和app中的app id相等了,比如Apple Push Notification Service。

d). 權限聲明:provision profile中的Entitlements和app中的權限聲明必須要比對。

c). iOS裝置:ProvisionedDevices包含了使用Development證書或者Ad-hoc證書發行app時可以運作app的裝置清單。