iOS開發——高級技術&簽名機制

簽名機制html

最近看了objc.io上第17期中的文章 《Inside Code Signing》 對應的中文翻譯版 《代碼簽名探析》 ,受益頗深,對iOS代碼簽名機制有了進一步的認識。想了解詳細內容建議你們仍是去看原文好了。git

下面是對此文章的理解再結合本身以前對該部分的認識寫出的學習筆記。本文的前提是已經對非對稱加密有了必定的瞭解。算法

1、數字簽名(digital signature)安全

對指定信息使用哈希算法,獲得一個固定長度的信息摘要,而後再使用 私鑰 (注意必須是私鑰)對該摘要加密,就獲得了數字簽名。所謂的代碼簽名就是這個意思。app

2、數字證書(digital certificate)框架

證書生成iphone

開 發者在申請iOS開發證書時,須要經過keychain生成一個CSR文件(Certificate Signing Request),提交給蘋果的 Apple Worldwide Developer Relations Certification Authority(WWDR)證書認證中心進行簽名,最後從蘋果官網下載並安裝使用。這個過程當中還會產生一個私鑰,證書和私鑰在keychain中得位 置如圖:ide

iphone-developer-keychain.png

證書組成工具

通過WWDR數字簽名後的數字證書長這個樣子:學習

20130603170838968.png

其中包含兩大部分:

· 證書自己

包含用戶的公鑰、用戶我的信息、證書頒發機構信息、證書有效期等信息。

· 證書籤名

WWDR將上述證書自己內容的使用哈希算法獲得一個固定長度的信息摘要,而後使用本身的私鑰對該信息摘要加密生成數字簽名,整個過程如圖所示:

20130603170752859.png

證書使用

iOS 系統本來就持有WWDR的公鑰,系統首先會對證書內容經過指定的哈希算法計算獲得一個信息摘要;而後使用WWDR的公鑰對證書中包含的數字簽名解密,從而 獲得通過WWDR的私鑰加密過的信息摘要;最後對比兩個信息摘要,若是內容相同就說明該證書可信。整個過程如圖所示:

20130603170924312.png

在驗證了證書是可信的之後,iOS系統就能夠獲取到證書中包含的開發者的公鑰,並使用該公鑰來判斷代碼簽名的可用性了。

證書存在的意義

經過證書使用過程能夠看出,證書自己只是一箇中間媒介,iOS系統對證書並不關心,它其實只想要證書中包含的開發者的公鑰!!

可是開發者怎麼才能證實公鑰是本身的呢?iOS安全系統怎麼才能相信這個公鑰就是這個開發者的呢?

不 管是哪個開發者對iOS的安全系統說,這個公鑰就是個人,系統是都不相信的,即系統對開發者有着百分之百的不信任感。可是iOS安全系統對自家的 WWDR是可信任的,蘋果將WWDR的公鑰內置在了iOS系統中。有了證書,iOS安全系統只須要經過WWDR的公鑰就能夠獲取到任何一個開發者的可信任 的公鑰了,這就是證書存在的意義!!

3、公鑰(public key)

公鑰被包含在數字證書裏,數字證書又被包含在描述文件(Provisioning File)中,描述文件在應用被安裝的時候會被拷貝到iOS設備中。

iOS安全系統經過證書就可以肯定開發者身份,就可以經過從證書中獲取到的公鑰來驗證開發者用該公鑰對應的私鑰簽名後的代碼、資源文件等有沒有被更改破壞,最終肯定應用可否合法的在iOS設備上合法運行。

4、私鑰(private key)

每一個證書(實際上是公鑰)都對應有一個私鑰,

私鑰會被用來對代碼、資源文件等簽名。只有開發證書和描述文件是沒辦法正常調試的,由於沒有私鑰根本沒法簽名。

此後的內容基本都是從《代碼簽名探析》摘抄過來的筆記,建議你們看原文好了。

5、簽名相關命令

快捷查看系統中能用來對代碼進行簽名的證書

可使用以下命令:

1 $security find-identity -v -p codesigning 2 1) F10B42FFDE18DF28BA21190121439F2E04BEE4B8 "iPhone Developer: weizheng li (P7QJ74LFSA)" 3 1 valid identities found

 

這就說明當前有一個同時有公鑰和私鑰的可用證書。

對未簽名app手動簽名

使用以下命令:

1 $ codesign -s 'iPhone Developer: Thomas Kollbach (7TPNXN7G6K)' Example.app

對已簽名app從新簽名

爲了從新設置簽名,你必須帶上 -f 參數,有了這個參數,codesign 會用你選擇的簽名替換掉已經存在的那一個:

1 $ codesign -f -s 'iPhone Developer: Thomas Kollbach (7TPNXN7G6K)' Example.app

查看指定app的簽名信息

codesign 還能夠爲你提供有關一個可執行文件簽名狀態的信息,這些信息在出現不明錯誤時會提供巨大的幫助:

1 $ codesign -vv -d Example.app

會列出如下有關 Example.app 的簽名信息:

複製代碼
 1 Executable=/Users/toto/Library/Developer/Xcode/DerivedData/Example-cfsbhbvmswdivqhekxfykvkpngkg/Build/Products/Debug-iphoneos/Example.app/Example  2 Identifier=ch.kollba.example  3 Format=bundle with Mach-O thin (arm64)  4 CodeDirectory v=20200 size=26663 flags=0x0(none) hashes=1324+5 location=embedded  5 Signature size=4336  6 Authority=iPhone Developer: Thomas Kollbach (7TPNXN7G6K)  7 Authority=Apple Worldwide Developer Relations Certification Authority  8 Authority=Apple Root CA  9 Signed Time=29.09.2014 22:29:07 10 Info.plist entries=33 11 TeamIdentifier=DZM8538E3E 12 Sealed Resources version=2 rules=4 files=120 13 Internal requirements count=1 size=184
複製代碼

 

驗證簽名文件的完整性

檢查已簽名的文件是否完整可使用以下命令:

1 $ codesign --verify Example.app

就像大多數 UNIX 工具同樣,沒有任何輸出表明簽名是無缺的。若是修改一下這個二進制文件:

1 $ echo 'lol' >> Example.app/Example 2 $ codesign --verify Example.app 3 Example.app: main executable failed strict validation

和預料中的同樣,修改已經簽名的應用會致使數字簽名驗證不經過。

6、資源文件簽名

iOS 和 OS X 的應用和框架則是包含了它們所須要的資源在其中的。這些資源包括圖片和不一樣的語言文件,資源中也包括很重要的應用組成部分例如 XIB/NIB 文件,存檔文件(archives),甚至是證書文件。因此爲一個程序包設置簽名時,這個包中的全部資源文件也都會被設置簽名。

爲了達到爲 全部文件設置簽名的目的,簽名的過程當中會在程序包(即Example.app)中新建一個叫作 _CodeSignatue/CodeResources 的文件,這個文件中存儲了被簽名的程序包中全部文件的簽名。你能夠本身去查看這個簽名列表文件,它僅僅是一個 plist 格式文件。

這 個列表文件中不光包含了文件和它們的簽名的列表,還包含了一系列規則,這些規則決定了哪些資源文件應當被設置簽名。伴隨 OS X 10.10 DP 5 和 10.9.5 版本的發佈,蘋果改變了代碼簽名的格式,也改變了有關資源的規則。若是你使用10.9.5或者更高版本的 codesign 工具,在 CodeResources 文件中會有4個不一樣區域,其中的 rules 和 files 是爲老版本準備的,而 files2 和 rules2 是爲新的第二版的代碼簽名準備的。最主要的區別是在新版本中你沒法再將某些資源文件排除在代碼簽名以外,在過去你是能夠的,只要在被設置簽名的程序包中添 加一個名爲 ResourceRules.plist 的文件,這個文件會規定哪些資源文件在檢查代碼簽名是否無缺時應該被忽略。可是在新版本的代碼簽名中,這種作法再也不有效。全部的代碼文件和資源文件都必須 設置簽名,再也不能夠有例外。在新版本的代碼簽名規定中,一個程序包中的可執行程序包,例如擴展 (extension),是一個獨立的須要設置簽名的個體,在檢查簽名是否完整時應當被單獨對待。

7、受權文件(entitlements)

在 iOS 上你的應用能作什麼依然是沙盒限制的,這些限制大多狀況下都由受權文件(entitlements)來決定。受權機制決定了哪些系統資源在什麼狀況下容許被一個應用使用,簡單的說它就是一個沙盒的配置列表。

運行以下命令:

1 $ codesign -d --entitlements - Example.app

會獲得相似的結果:

複製代碼
 1 <!--?xml version="1.0" encoding="UTF-8"?-->  2  3 <plist version="1.0">  4 <dict>  5 <key>application-identifier</key>  6 <string>7TPNXN7G6K.ch.kollba.example</string>  7 <key>aps-environment</key>  8 <string>development</string>  9 <key>com.apple.developer.team-identifier</key> 10 <string>7TPNXN7G6K</string> 11 <key>com.apple.developer.ubiquity-container-identifiers</key> 12 <array> 13 <string>7TPNXN7G6K.ch.kollba.example</string> 14 </array> 15 <key>com.apple.developer.ubiquity-kvstore-identifier</key> 16 <string>7TPNXN7G6K.ch.kollba.example</string> 17 <key>com.apple.security.application-groups</key> 18 <array> 19 <string>group.ch.kollba.example</string> 20 </array> 21 <key>get-task-allow</key> 22 <true> 23 </true></dict> 24 </plist version="1.0">
複製代碼

 

在 Xcode 的 Capabilities 選項卡下選擇一些選項以後,Xcode 就會生成這樣一段 XML。 Xcode 會自動生成一個 .entitlements 文件,而後在須要的時候往裏面添加條目。當構建整個應用時,這個文件也會提交給 codesign 做爲應用所須要擁有哪些受權的參考。這些受權信息必須都在開發者中心的 App ID 中啓用,而且包含在後文介紹的描述文件中。在構建應用時須要使用的受權文件能夠在 Xcode build setting 中的 code signing entitlements中設置。

在新版本的 Xcode 6 以後,受權信息列表會以 Example.app.xcent 這樣的名字的文件形式包含在應用包中。這麼作或許是爲了在出現配置錯誤時提供更加有用的錯誤信息。

8、描述文件(provisioning file)

在整個代碼簽名和沙盒機制中有一個組成部分將簽名,受權和沙盒聯繫了起來,那就是描述文件 (provisioning profiles)。

OS X中保存目錄

Xcode 將從開發者中心下載的所有配置文件都放在了這裏:

1 ~/Library/MobileDevice/Provisioning Profiles

文件格式

描述文件並非一個普通的plist文件,它是一個根據密碼訊息語法 (Cryptographic Message Syntax) 加密的文件。

以XML格式查看該文件的命令:

1 $ security cms -D -i example.mobileprovision

文件內容

描述文件主要包含如下內容:

· UUID

每個配置文件都有它本身的 UUID 。Xcode 會用這個 UUID 來做爲標識,記錄你在 build settings 中選擇了哪個配置文件。

· ProvisionedDevices

記錄全部可用於調試的設備ID。

· DeveloperCertificates

包含了能夠爲使用這個配置文件的應用簽名的全部證書。全部的證書都是基於 Base64 編碼符合 PEM (Privacy Enhanced Mail, RFC 1848) 格式的。

· Entitlements

有關前面講到的配置文件的全部內容都會被保存在這裏。

相關文章
相關標籤/搜索