本文參考如下資料(建議閱讀):
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檔案夾中),我們不妨看一個執行個體:
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
- <plist version="1.0">
- <dict>
- <key>files</key>
- <dict>
- <key>[email protected]</key>
- <data>
- eanTrclP/4jBcw+pZZDeVPimJ7g=
- </data>
- <key>[email protected]~ipad.png</key>
- <data>
- eanTrclP/4jBcw+pZZDeVPimJ7g=
- </data>
- <key>[email protected]</key>
- <data>
- xEo0NvwYxXdtywn3iD8yDaF6V1A=
- </data>
- <key>[email protected]~ipad.png</key>
- <data>
- xEo0NvwYxXdtywn3iD8yDaF6V1A=
- </data>
- <key>[email protected]</key>
- <data>
- rMa2+pGtRq8pN4LRcp+dCn5Kai8=
- </data>
- <key>Base.lproj/Main.storyboardc/BYZ-38-t0r-view-8bC-Xf-vdC.nib</key>
- <dict>
- <key>hash</key>
- <data>
- t/7wowkj3how49ccMtcw+bat3sQ=
- </data>
- <key>optional</key>
- <true/>
- </dict>
完整的太大了,我們截取一小段觀摩。
可以看到key就是檔案的名稱,data就是檔案的簽名,由于這個簽名無法被篡改,是以plist檔案本身不加密也無所謂。
2). 用什麼簽名
通過前面的參考資料,我們可以了解實際上簽名唯一需要的就隻是私鑰。但在iOS應用簽名中,這還不夠,我們還需要證書,app id,權限聲明,iOS裝置,而這些材料我們又可以打包到一種叫做Provision Profile的東西中去,我們在簽名的時候(使用mac os x的codesign程式)也隻能提供provision profile來工作。
一個Provision Profile的典型結構:
我們來逐一解析各個材料的作用和擷取途徑(下述内容包含一些臆斷的部分,我會用紅字标出,因為Apple實在是太封閉了,有些東西我還沒沒法了解到)。
a). 私鑰:實際上私鑰和公鑰總是成對工作的,缺失其中任何一個之後另一個也是廢物一個。在生成證書的時候自然而然會生成密鑰對(而且系統會自動關聯它們),是以我們放到證書中具體講述。
b). 證書:為什麼需要證書?在前面參考資料中我們了解到,證書實際上是一種身份驗證的東西,可想而知這個東西實際上隻是iOS系統單方面需要,我們簽名實際上并不會用到。證書分為Development/Production(Development/Production對程式的影響本文不予讨論),這在證書中可以看到:
當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的裝置清單。