iOS Provisioning Profile(Certificate)與Code Signing詳解

引言

        關於開發證書配置(Certificates & Identifiers & Provisioning Profiles),相信做 iOS 開發的同學沒少被折騰。對於一個 iOS 開發小白、半吊子(比如像我自己)抑或老兵,或多或少會有或曾有過以下不詳、疑問、疑惑甚至困惑:

  1. 什麼是App ID?Explicit/Wildcard App ID有何區別?什麼是App Group ID?
  2. 什麼是證書(Certificate)?如何申請?有啥用?
  3. 什麼是Key Pair(公鑰/私鑰)?有啥用?與證書有何關聯?
  4. 什麼是簽名(Signature)?如何簽名(CodeSign)?怎樣校驗(Verify)?
  5. 什麼是(Team)Provisioning Profiles?有啥用?
  6. Xcode如何配置才能使用iOS真機進行開發調試?
  7. 多臺機器如何共享開發者賬號或證書?
  8. 遇到證書配置問題怎麼辦?
  9. Xcode 7免證書調試真機調試

本文將圍繞相關概念及背景做個系統的梳理串燒,於條分縷析中對證書體系進行抽絲剝繭,逐步揭開簽名機制的神祕面紗。圖窮匕首見,水落而石出,包教不包會,不會請再來。

從 Xcode 7 開始支持普通 Apple 賬號進行免證書真機調試,詳情參考最新官方文檔《Launching Your App on Devices》,或參考本文最後一節簡介。

寫在前面

1.假設你使用過 Apple 設備(iMac/iPad/iPhone)且註冊過 Apple ID(Apple Account),詳情參考《創建和開始使用 Apple ID》。

2.假設你或你所在的開發組已加入蘋果開發者計劃(Enroll in iOS Developer Program to become a member),即已註冊開發者賬號(Apple Developer Account)。

  • 只有擁有開發者賬號,纔可以申請開發/發佈證書及相關配置授權文件,進而在 iOS 真機上開發調試 Apps 或發佈到 App Store。
  • 開發者賬號分爲 Individual 和 Company/Organization 兩種類型。如無特別交代,下文基於 $99/Year 的普通個人開發者(Individual)賬號展開

3.若要真機調試實踐,你必須至少擁有一臺裝有 macOS/Xcode 的 Mac 開發機(iMac or MacBook),其上自帶原生的 Keychain Access。

.App ID(bundle identifier)

在蘋果官方的開發者計劃(Apple Developer Member Center層面,App ID 即 Product ID,用於標識一個或者一組 App。

在 Mac/iOS 開發語境中,bundle捆綁) 是指一個內部結構按照標準規則組織的特殊目錄。在 Mac OS 應用程序目錄下的某個 *.app 上可右鍵顯示包內容(Contents),其本質上就是可執行二進制文件(MacOS/)及其資源(Resources/)的打包組合

App ID 字符串通常以反域名(reverse-domain-name)格式的 Company Identifier(Company ID)作爲前綴(Prefix/Seed),一般不超過 255 個 ASCII 字符。

App ID 全名會被追加 Application Identifier Prefix(一般爲 TeamID.),分爲兩類:

  • Explicit App ID:唯一的 App ID,用於唯一標識一個應用程序。例如“com.apple.garageband”這個 App ID,用於標識 Bundle Identifier 爲“com.apple.garageband”的 App——GarageBand;com.tencent.mqq”則爲iPhoneQQ 的 App ID
  • Wildcard App ID:含有通配符的 App ID,用於標識一組應用程序。例如“*”(實際上是 Application Identifier Prefix)表示所有應用程序;而“com.apple.*”可以表示 Bundle Identifier 以“com.apple.”開頭(蘋果公司)的所有應用程序。
用戶可在 Developer Member Center 網站上註冊(Register)或刪除(Delete)已註冊的 App IDs。
在 Xcode 中 配置到XcodeTarget|Info|Bundle Identifier】中的 Bundle Identifier 必須和 App ID 是一致(Explicit)或匹配(Wildcard)。對於 Wildcard App ID,只要 bundle identifier 包含其作爲 Prefix/Seed 即可。

.設備(Device)

Device 就是運行 iOS 系統用於開發調試 App 的設備。每臺 Apple 設備使用 UDID (Unique Device Identifier)唯一標識。

iOS 設備連接 Mac 後,可通過 iTunes->Summary 或者 Xcode->Window->Devices 查看其 UDID

Apple Member Center 網站個人賬號下的 Devices 中包含了註冊過的所有可用於開發和測試的設備,普通個人開發賬號每年累計最多隻能註冊100個設備。

  • Apps signed by you or your team run only on designated development devices.
  • Apps run only on the test devices you specify.
用戶可在網站上註冊或啓用/禁用(Enable/Disable)已註冊的 Device。
本文的 Devices 是指連接到 macOS/Xcode 被授權用於開發測試的 iOS 設備(iPhone/iPad)。

.開發證書(Certificates)

1.證書的概念

證書是由公證處或認證機關開具的證明資格或權力的證件,它是表明(或幫助斷定)事理的一個憑證。證件或憑證的尾部通常會烙印公章

每個中國人一生可能需要70多個證件,含15種身份證明。證件中“必需的”有30到40個。將這些證件按時間順序鋪開,那就是一個天朝子民的一生——持準生證許可落地,以戶籍證明入籍,以身份證認證身份,持結婚證以合法同居,最終以死亡證明註銷。

2.數字證書的概念

數字證書就是互聯網通訊中標誌通訊各方身份信息的一串數字,提供了一種在 Internet 上驗證通信實體身份的方式,其作用類似於日常生活中的身份證或司機的駕駛執照。

注意:本文討論的數字證書是基於 X.509 公共密鑰體系(PKI,Public key infrastructure)的公鑰證書(Public key certificate

數字證書是由權威的CA機構Certificate authority數字證書認證機構或數字證書授權中心頒發發行)的,人們可以在網上用它來識別對方的身份。


  • 數字證書是一個經 CA 數字簽名的包含公開密鑰擁有者信息以及公開密鑰的文件。最簡單的證書包含一個公開密鑰、名稱以及 CA 的數字簽名。
  • 數字證書還有一個重要的特徵就是時效性:只在特定的時間段內有效。
關於數字證書的構成要素,參考 X.509 § Structure of a certificate

數字證書中的公開密鑰(公鑰)相當於公章

3.根證書的概念

證書的信任鏈條(Chain of trust)是環環相扣的,根證書(Root certificate)就是一開始就被信任的證書,是信任源(trust anchor),即信任鏈的起點

根證書是被嚴格限制和確認的,根證書的頒發者被稱之爲 Root Certificate Authority(Root CA)某一認證領域內的根證書是 CA 認證中心自行簽名給自己頒發的證書(Self-signed certificate),安裝根證書意味着對這個 CA 認證中心的信任。

> 在天朝子民的一生中,戶籍證明爲證源(根證書,Root certificate);有了戶籍證明,才能辦理身份證(中間證書,Intermediate certificate);有了上流的身份證,才能辦理下游特定領域(End-entity)所需的居住證、結婚證、計劃生育證、駕駛執照等認證(葉子證書,leaf certificate)。

這裏首當其衝需要解決的問題是:由誰來保證根證書作爲信任鏈起點的安全?

現代網絡操作系統都會內置一份可信的根證書列表(Firefox 的根證書列表獨立於操作系統之外):操作系統發行廠商通過嚴格地審覈,將安全可靠、可被信任的第三方機構(TTP,trusted third party)納入白名單,並將這些權威可信 CA 的根證書 預裝內置 到系統中。

》在 Windows Internet Explorer 中,通過菜單【工具 | Internet 選項 | 內容 | 證書】可以查看受信任的根證書頒發機構(或中間證書頒發機構):

》在 macOS Keychain Access 中,可查看系統根證書(或系統證書):


常見的權威 CA 根證書有

  • AddTrust External CA Root(The USERTrust Network™)
  • Baltimore CyberTrust Root(DigiCert Baltimore Root)
  • DigiCert Global Root CA(DigiCert)
  • DigiCert High Assurance EV Root CA(DigiCert)
  • DST Root CA X3
  • GeoTrust Global CA
  • GeoTrust Primary Certification Authority
  • GlobalSign(頒發者:GlobalSign Root CA - R3;簽名算法:sha256RSA——帶 RSA 加密的 SHA-256)
  • GlobalSign(頒發者:GlobalSign Root CA - R2;簽名算法:sha1RSA——帶 RSA 加密的 SHA-1)
  • GlobalSign Root CA(組織:GlobalSign nv-sa)
  • Go Daddy Class 2 Certification Authority(組織:The Go Daddy Group, Inc.)
  • Go Daddy Root Certificate Authority - G2(組織:GoDaddy.com, Inc.)
  • QuoVadis Root Certification Authority(組織:QuoVadis Limited)
  • Starfield Class 2 Certification Authority
  • Starfield Services Root Certificate Authority( - G2)(組織:Starfield Technologies, Inc.)
  • StartCom Certification Authority(簽名算法:sha1RSA——帶 RSA 加密的 SHA-1)
  • thawte Primary Root CA
  • thawte Primary Root CA - G3
  • UTN-USERFirst-Object(組織:The USERTRUST Network)
  • VeriSign Universal Root Certification Authority(組織單位:VeriSign Trust Network)
  • VeriSign Class 3 Public Primary Certification Authority - G5(組織單位:VeriSign Trust Network)

--------------------------------------------------------------------------------
Windows 下微軟頒發的證書
--------------------------------------------------------------------------------

  • Microsoft Root Authority
  • Microsoft Root Certificate Authority
  • Symantec Enterprise Mobile Root for Microsoft

--------------------------------------------------------------------------------
macOS 下蘋果頒發的證書
--------------------------------------------------------------------------------
  • Apple Root CA
  • Apple Root Certificate Authority
  •     Developer ID Certification Authority(系統根證書)
  •     Apple Worldwide Developer Relations Certification Authority(系統證書)
橢圓曲線公共密鑰
  1. 簽名算法:帶 SHA-256 的 ECDSA 簽名;公共密鑰算法:橢圓曲線公共密鑰;參數爲[橢圓曲線 secp256r1]
  2. 簽名算法:帶 SHA-384 的 ECDSA 簽名;公共密鑰算法:橢圓曲線公共密鑰;參數爲[橢圓曲線 secp384r1]
macOS 預裝了 Apple Root CA、GlobalSign、GeoTrust、Symantec、thawte、VeriSign 等權威機構的包含橢圓曲線公共密鑰的根證書:
  • GlobalSign(組織單位:GlobalSign ECC Root CA - R4;帶 SHA-256 的 ECDSA 簽名)
  • GlobalSign(組織單位:GlobalSign ECC Root CA - R5;帶 SHA-384 的 ECDSA 簽名)
  • Apple Root CA - G3(組織單位:Apple Certification Authority;帶 SHA-384 的 ECDSA 簽名)
  • GeoTrust Primary Certification Authority - G2(組織:GeoTrust Inc.;帶 SHA-384 的 ECDSA 簽名)
  • Symantec Class 1/2/3 Public Primary Certification Authority - G4(組織單位:Symantec Trust Network;帶 SHA-384 的 ECDSA 簽名)
  • thawte Primary Root CA - G2(組織:thawte, Inc.;帶 SHA-384 的 ECDSA 簽名)
  • VeriSign Class 3 Public Primary Certification Authority - G4(組織單位:VeriSign Trust Network;帶 SHA-384 的 ECDSA 簽名)

爲了防止 GFW 進行中間人攻擊(MitM),例如篡改 github 證書,導致無法訪問 github 網站等問題,可選擇不信任 CNNIC

  • 在[鑰匙串-系統]中雙擊 CNNIC ROOT,在【信任】|【使用此證書時】下拉選擇【永不信任】。


4.iOS(開發)證書

iOS 證書是用來證明 iOS App 內容(bundle with executable and resources)的合法性和完整性的數字證書。對於想安裝到真機或發佈到 AppStore 的應用程序(App),只有經過簽名驗證(Signature Validated)才能確保來源可信,並且保證 App 內容是完整、未經篡改的。

iOS 證書分爲兩類:Development 和 Production(Distribution)

  • Development 證書用來開發和調試應用程序:A development certificate identifies you, as a team member, in a development provisioning profile that allows apps signed by you to launch on devices. 
  • Production 主要用來分發應用程序(根據證書種類有不同作用):A distribution certificate identifies your team or organization in a distribution provisioning profile and allows you to submit  your app to the store. Only a team agent or an admin can create a distribution certificate.

普通個人開發賬號最多可註冊 iOS Development/Distribution 證書各2個,用戶可在網站上刪除(Revoke)已註冊的 Certificate。

下文主要針對 iOS App 開發調試過程中的開發證書(Certificate for Development)。

5.iOS(開發)證書的根證書

那麼,iOS 開發證書是誰頒發的呢?或者說我們是從哪個 CA 申請到用於 Xcode 開發調試 App 的證書呢?

iOS 以及 Mac OS X 系統(在安裝 Xcode 時)將自動安裝 AppleWWDRCA.cer 這個中間證書(Intermediate Certificates),它實際上就是 iOS(開發)證書的證書,即開發根證書

AppleWWDRCA.cer 是由蘋果公司一級認證中心 Apple Certification Authority(Apple Root CA)給下屬的 Apple Worldwide Developer Relations Certification Authority 這個二級證書機構(subordinate CA)頒發的證書。而蘋果根證書則是被默認預裝到 macOS 系統中的,在 Keychain Access 系統根證書中可以找到 Apple Root CA 爲自己頒發的根證書。

Apple Root CA 之於  AppleWWDRCA 好比戶籍證之於身份證AppleWWDRCA 之於 iOS(開發)證書則好比身份證之於駕駛證




如果 Mac Keychain Access 證書助理在申請證書時尚未安裝過 AppleWWDRCA.cer 證書,請先下載安裝(Signing requires that you have both the signing identity and the intermediate certificate installed in your keychain)。

下載到本地後,手動點擊 *.cer 安裝證書到 macOS 時,Keychain Access 追溯其簽發 CA 爲 Apple Root CA,利用 Apple Root CA 證書公鑰對其數字簽名進行解密和校驗。校驗成功會標記此證書有效(This certificate is valid)。


二級證書路徑爲:

Apple Root CA
└── Apple Worldwide Developer Relations Certification Authority

6.申請 iOS 開發證書(CSR:Certificate Signing Request)

可以在缺少證書時通過 Xcode Fix Issue 自動請求證書,但是這會掩蓋其中的具體流程細節。這裏通過 Keychain 證書助理從證書頒發機構請求證書:填寫開發賬號郵件和常用名稱,勾選【存儲到磁盤】。


Keychain Access|Keys 中將新增一對非對稱密鑰對 Public/Private Key Pair(This signing identity consists of a public-private key pair that Apple issues)。同時,keychain 將生成一個包含開發者身份信息公鑰CSR(Certificate Signing Request)文件——CertificateSigningRequest.certSigningRequest。


私鑰 private key 始終保存在 Mac OS 的 Keychain Access 中,用於簽名(CodeSign)本機對外發布的 App公鑰 public key 一般隨證書(隨Provisioning Profile,隨 App 安裝)散佈出去,對 App 簽名進行校驗認證。用戶必須妥善保存本地 Keychain 中的 private key,以防僞冒。

  • Keep a secure backup of your public-private key pair. If the private key is lost, you’ll have to create an entirely new identity to sign code. 
  • Worse, if someone else has your private key, that person may be able to impersonate you.

在 Apple 開發網站上傳包含公鑰的 CSR 文件作爲換取證書的憑證(Upload CSR file to generate your certificate),有點類似爲github賬號添加SSH公鑰到服務器上進行授權。

Apple Developer 開發證書頒發機構 WWDRCA 將使用其 private key 對 CSR 中的 public key 和一些身份信息進行加密簽名生成數字證書(ios_development.cer)並記錄在案(Apple Member Center)。


從 Apple Member Center 網站下載證書到 Mac 上雙擊即可安裝(當然也可在 Xcode 中添加開發賬號自動同步證書和[生成]配置文件)。

手動點擊 *.cer 安裝證書到 macOS 時,Keychain Access 追溯其簽發 CA 爲 AppleWWDRCA(Apple Worldwide Developer Relations Certification Authority),利用 AppleWWDRCA 證書公鑰對該開發證書數字簽名進行解密和校驗。校驗成功會標記此證書有效(This certificate is valid)。

三級開發證書路徑爲:

Apple Root CA
└── Apple Worldwide Developer Relations Certification Authority
    └── iPhone Developer: *@gmail.com (**********)

在 Keychain Access 的 Login | My Certificates 可查看到安裝成功的證書。



Keychain Access 的 Login | Keys 中展開創建 CSR 時生成的 Key Pair 中的私鑰前面的箭頭,可以查看到包含其對應公鑰的證書(Your requested certificate will be the public half of the key pair.);

在 Keychain Access|Certificates 中展開安裝的證書(ios_development.cer)前面的箭頭,可以看到其對應的私鑰



Certificate 應被配置到Xcode Target|Build Settings|Code Signing|Code Signing Identity】下,下拉選擇 Identities from Profile "..."(一般先配置 Provisioning Profile)。以下是 Xcode 配置示例:


.供應配置文件(Provisioning Profiles

1.Provisioning Profile 的概念

Provisioning Profile 文件包含了上述的所有內容:證書、App ID 和 設備 ID


一個 Provisioning Profile 對應一個 Explicit App ID 或 Wildcard App ID(一組相同 Prefix/Seed 的 App IDs)。在網站上手動創建一個 Provisioning Profile 時,需要依次指定 App ID(單選)、證書(Certificates,可多選)和設備(Devices,可多選)。用戶可在網站上刪除(Delete)已註冊的 Provisioning Profiles。

Provisioning Profile 決定 Xcode 用哪個證書(公鑰)/私鑰組合(Key Pair/Signing Identity)來簽署應用程序(Signing Product),並將在應用程序打包時嵌入到 .ipa 包裏。安裝應用程序時,Provisioning Profile 文件被拷貝到 iOS 設備中,運行該 iOS App 的設備通過它來認證安裝的程序。

如果要打包到真機上運行一個APP,一般要經歷以下三步:

  • 首先需要指明它的 App ID,並且驗證 Bundle ID 是否與其一致;
  • 其次需要證書對應的私鑰來進行簽名,用於標識這個 APP 是合法、安全、完整的;
  • 然後,如果是真機調試,需要確認這臺設備是否授權運行該 APP。

Provisioning Profile 把這些信息全部打包在一起,方便我們在調試和發佈程序打包時使用。這樣,只要在不同的情況下選擇不同的 Provisioning Profile 文件就可以了。

Provisioning Profile 也分爲 Development 和 Distribution 兩類,有效期同 Certificate 一樣。Distribution 版本的 ProvisioningProfile 主要用於提交 App Store 審覈,其中不指定開發測試的Devices(0,unlimited)。App ID 爲 Wildcard App ID(*)。App Store 審覈通過上架後,允許所有 iOS 設備(Deployment Target)上安裝運行該App。

Xcode 將全部供應配置文件(包括用戶手動下載安裝的和 Xcode 自動創建的 Team Provisioning Profile)放在目錄 ~/Library/MobileDevice/Provisioning Profiles 下。

2.Provisioning Profile的構成

以下爲典型供應配置文件 *.mobileprovision 的構成簡析

1)Name:該mobileprovision的文件名。

2)UUID:該mobileprovision文件的真實文件名。

3)TeamNameApple ID賬號名。

4)TeamIdentifierTeam Identity。

5)AppIDNameexplicit/wildcard App ID name(ApplicationIdentifierPrefix)。

6)ApplicationIdentifierPrefix:完整App ID的前綴(TeamIdentifier.*)。

7)DeveloperCertificates:包含了可以爲使用該配置文件應用簽名的所有證書<data><array>。

證書是基於 Base64 編碼,符合 PEM(PrivacyEnhanced Mail, RFC 1848) 格式的,可使用 OpenSSL 來處理(opensslx509 -text -in file.pem)。

從 DeveloperCertificates 提取 <data></data> 之間的內容到文件 cert.cer(cert.perm):

-----BEGIN CERTIFICATE-----

<data></data>之間的內容拷貝至此

-----END CERTIFICATE-----`

Mac 下右鍵 QuickLook 查看 cert.cer(cert.perm),在 Keychain Access 中右鍵 Get Info 查看對應證書 ios_development.cer,正常情況(公私鑰 KeyPair 配對)應吻合;Windows 下沒有足夠信息(WWDRCA.cer),無法驗證該證書。

如果你用了一個不在這個列表中的證書進行簽名,無論這個證書是否有效,這個應用都將 CodeSign Fail。

8)Entitlements <key>對應的<dict>:

keychain-access-groups$(AppIdentifierPrefix),參見Code Signing Entitlements(*.entitlements)。

每個應用程序都有一個可以用於安全保存一些如密碼、認證等信息的 keychain,一般而言自己的程序只能訪問自己的 keychain。通過對應用簽名時的一些設置,還可以利用keychain的方式實現同一開發者簽證(就是相同bundle seed)下的不同應用之間共享信息的操作。比如你有一個開發者帳戶,並開發了兩個不同的應用A和B,然後通過對A和B的 keychain access group 這個東西指定共用的訪問分組,就可以實現共享此 keychain 中的內容。

application-identifier:帶前綴的全名,例如$(AppIdentifierPrefix)com.apple.garageband。

com.apple.security.application-groupsApp Group ID(group. com.apple),參見Code Signing Entitlements(*.entitlements)。

com.apple.developer.team-identifier:同Team Identifier。

9)ProvisionedDevices:該mobileprovision授權的開發設備的UDID <array>。

Provisioning Profile被配置到XcodeTarget|Build Settings|Code Signing|Provisioning Profile】下,然後在Code Signing Identity下拉可選擇Identities from Profile "..."(即Provisioning Profile中包含的Certificates)

.開發組供應配置文件(Team Provisioning Profiles

1.Team Provisioning Profile的概念

每個 Apple 開發者賬號都對應一個唯一的 Team ID,Xcode3.2.3 預發佈版本中加入了 Team Provisioning Profile 這項新功能。

在 Xcode 中添加 Apple Developer Account 時,它將與 Apple Member Center 後臺勾兌自動生成 iOS Team Provisioning Profile(Managed by Xcode)。


Team Provisioning Profile 包含一個爲 Xcode iOS Wildcard App ID(*) 生成的 iOS Team Provisioning Profile:*(匹配所有應用程序),賬戶裏所有的 Development Certificates 和 Devices 都可以使用它在這個 team 註冊的所有設備上調試應用程序(不管bundle identifier是什麼)。同時,它還會爲開發者自己創建的 Wildcard/Explicit App IDs 創建對應的 iOS Team Provisioning Profile。


2.Team Provisioning Profile 生成/更新時機

  • Add an Apple ID account to Xcode
  • Fix issue "No Provisioning Profiles with a valid signing identity" in Xcode
  • Assign Your App to a Team in Xcode project settings of General|Identity
  • Register new device on the apple development website or Xcode detected new device connected

利用 Xcode 生成和管理的 iOS Team Provisioning Profile 來進行開發非常方便,可以不需要上網站手動生成下載 Provisioning Profile。

Team Provisioning Profile 同 Provisioning Profile,只不過是由 Xcode 自動生成的,也被配置到XcodeTarget|Build Settings|Code Signing|Provisioning Profile】下,同時需要在XcodeTarget|General|Identity】下指定 Team 賬號 ID。

.App Group (ID)

1.App Group 的概念

WWDC14 除了發佈了 OS X v10.10 和 switf 外,iOS 8.0 也開始變得更加開放了。說到開放,當然要數應用擴展(App Extension)了。顧名思義,應用擴展允許開發者擴展應用的自定義功能和內容,能夠讓用戶在使用其他應用程序時使用該項功能,從而實現各個應用程序間的功能和資源共享。可以將擴展理解爲一個輕量級(nimble and lightweight)的分身。

擴展和其 Containing App 各自擁有自己的沙盒,雖然擴展以插件形式內嵌在 Containing App 中,但是它們是獨立的二進制包,不可以互訪彼此的沙盒。爲了實現 Containing App 與擴展的數據共享,蘋果在 iOS 8 中引入了一個新的概念——App Group,它主要用於同一 Group 下的 APP 實現數據共享,具體來說是通過創建使用以 App Group ID 標識的共享資源區——App Group Container 來實現的。

App Group ID 同 App ID 一樣,一般不超過255個ASCII字符。用戶可在網站上編輯 Explicit App IDs,將其納入 App Group(Assignment);也可刪除(Delete)已註冊的App Group (ID)。

2.App Group 的配置

Containing App 與 Extension 的 Explicit App ID 必須 Assign 到同一 App Group 下才能實現數據共享,並且 Containing App 與 Extension 的 App ID 命名必須符合規範:

  1. 置於同一App Group 下的 App IDs 必須是唯一的(Explicit,not Wildcard)
  2. Extension App ID 以 Containing App ID 爲前綴(Prefix/Seed)

假如 Garageband 這個 App ID 爲“com.apple.garageband”,則支持從語音備忘錄導入到 Garageband 應用的插件的 App ID 可能形如“com.apple.garageband.extImportRecording

 

App(ex)

 

App Group ID

Provisioning Profile

Code Signing Identity

Certificate Key Pair

App ID

bundle identifier

Devices

test

GarageBand

置於同一分組:

group.com.apple

1)共用同一證書:ios_development.cer

2)共用證書Key Pair中的Private Key進行CodeSign

com.apple.garageband

授權開發測試設備的UDIDs

GarageBand擴展插件

com.apple.garageband.extImportRecording

關於Provisioning Profile,可以使用自己手動生成的,也可以使用 Xcode 自動生成的 Team Provisioning Profile。

App Group 會被配置到Xcode Target|Build Settings|Code Signing|Code Signing Entitlements】文件(*.entitlements)的鍵com.apple.security.application-groups下,不影響 Provisioning Profile 生成流程。

.證書與簽名Certificate& Signature)

1.Code Signing Identity


Xcode 中配置的 Code Signing Identity(entitlements、certificate)必須與 Provisioning Profile 匹配,並且配置的 Certificate 必須在本機 Keychain Access 中存在對應 Public/Private Key Pair,否則編譯會報錯。

Xcode 所在的 Mac 設備(系統)使用 CA 證書(WWDRCA.cer)來判斷 Code Signing Identity 中 Certificate 的合法性:

  • 若用 WWDRCA 公鑰能成功解密出證書並得到公鑰(Public Key)和內容摘要(Signature),證明此證書確乃 AppleWWDRCA 頒佈,即證書來源可信;
  • 再對證書本身使用哈希算法計算摘要,若與上一步得到的摘要一致,則證明此證書未被篡改過,即證書完整。

2.Code Signing

每個證書(其實是公鑰)對應 Key Pair 中的私鑰會被用來對內容(executable code,resources such as images and nib files aren’t signed)進行數字簽名(CodeSign)——使用哈希算法生成內容摘要(digest)。

Xcode 使用指定證書配套的私鑰進行簽名時需要授權,選擇【始終允許】後,以後使用該私鑰進行簽名便不會再彈出授權確認窗口。


3.Verify Code Signature with Certificate

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

第一步,App 在 Mac/iOS 真機上啓動時,需要對配置的 bundle ID、entitlements 和 certificate 與 Provisioning Profile 進行匹配校驗:


第二步,iOS/Mac 真機上的 ios_development.cer 被 AppleWWDRCA.cer 中的 public key 解密校驗合法後,獲取每個開發證書中可信任的公鑰對 App 的可靠性和完整性進行校驗。

iOS/Mac 設備(系統)使用 App Provisioning Profile(Code Signing Identity)中的開發證書來判斷App的合法性:

  • 若用證書公鑰能成功解密出 App(executable bundle)的內容摘要(_CodeSignature),證明此 App 確乃認證開發者發佈,即來源可信;
  • 再對 App(executable bundle)本身使用哈希算法計算摘要,若與上一步得到的摘要一致,則證明此 App 未被篡改過,即內容完整。
小結:
  • 基於 Provisioning Profile 校驗了 CodeSign 的一致性;
  • 基於 Certificate 校驗 App 的可靠性和完整性;
  • 啓動時,真機的 device ID(UUID)必須在 Provisioning Profile 的 ProvisionedDevices 授權之列。
  • 無論是 Xcode 對 APP 進行簽名打包還是真機運行 APP 進行校驗,都使用了非對稱加密機制Apple Root CA - G3 根證書定義了 帶 SHA-384 ECDSA 簽名的橢圓曲線 ECC 公共密鑰)。

.在多臺機器上共享開發賬戶/證書

1.Xcode 導出開發者賬號(*.developerprofile) 或 PKCS12 文件(*.p12)

進入 Xcode Preferences|Accounts:

  • 選中 Apple IDs 列表中對應 Account 的 Email,點擊+-之後的☸|Export Accounts,可導出包含 account/code signing identity/provisioning profiles 信息的 *.developerprofile(Exporting a Developer Profile)文件供其他機器上的 Xcode 開發使用(Import 該 Account)。
選中右下列表中某行 Account Name 條目|ViewDetails,可以查看 Signing Identities 和 Provisioning Profiles。
  • 選中欲導出的 Signing Identity 條目,點擊欄底+之後的☸|Export,必須輸入密碼,並需授權 export key "privateKey" from keychain,將導出 Certificates.p12
點擊左下角的刷新按鈕可從 Member Center 同步該賬號下所有的 Provisioning Profile 到本地。
選中右擊列表中某個 Provisioning Profile 可以【Show in Finder】到[~/Library/MobileDevice/Provisioning\ Profiles]目錄,其中 Provisioning Profile 的真實名稱爲 $(UUID).mobileprovision,名如"2488109f-ff65-442e-9774-fd50bd6bc827.mobileprovision",其中<key>Name</key>中爲 Xcode 中看到的描述性別名。

2.Keychain Access 導出 PKCS12 文件(*.p12)

在 Keychain Access|Certificates 中選中欲導出的 certificate 或其下 private key,右鍵 Export 或者通過菜單 File|Export Items 導出 Certificates.p12——PKCS12 file holds the private key and certificate

其他 Mac 機器上雙擊 Certificates.p12(如有密碼需輸入密碼)即可安裝該共享證書。有了共享證書之後,在開發者網站上將欲調試的 iOS 設備註冊到該開發者賬號名下,並下載對應證書授權了 iOS 調試設備的 Provisioning Profile 文件,方可在 iOS 真機設備上開發調試。

九.證書配置常見錯誤

1.no such provisioning profile was found

Xcode Target|Genera|Identity Team下提示"Your build settings specify a provisioning profile with the UUID "xxx",howerver, no such provisioning profile was found."

Xcode Target|BuildSettings|Code Signing|當前配置的指定UDID的provisioning profile在本地不存在,此時需要更改Provisioning Profile。必要時手動去網站下載或重新生成Provisioning Profile或直接在Xcode中Fix issue予以解決(可能自動生成iOS Team ProvisioningProfile)!

2.No identities from profile

Build Settings|CodeSigning的Provisioning Profile中選擇了本地安裝的provisioning profile之後,Code Signing Identity中下拉提示No identities from profile “…”or No identities from keychain.

Xcode配置指定UDID的provisioning profile中的DeveloperCertificates在本地KeyChain中不存在(No identities are available)或不一致(KeyPair中的Private Key丟失),此時需去網站檢查ProvisioningProfile中的App ID-Certificate-Device配置是否正確。如果是別人提供的共享賬號(*.developerprofile)或共享證書(*.p12),請確保導出了對應Key Pair中的Private Key。必要時也直接在Xcode中Fix issue予以解決(可能自動生成iOS Team ProvisioningProfile)。

3.Code Signing Entitlements file do not match profile

"Invalid application-identifier Entitlement" or "Code Signing Entitlements file do not match those specified in your provisioning profile.(0xE8008016)."

1)檢查對應版本(Debug)指定的*.entitlements文件中的“Keychain Access Groups”鍵值是否與ProvisioningProfile中的Entitlements項相吻合(後者一般爲前者的Prefix/Seed)。

2)也可以將Build Settings|Code Signing的Provisioning Profile中對應版本(Debug)的Entitlements置空。

4.The app ID cannot be registered to your development team


出現該問題通常是 app ID 衝突,即該 app ID 已經有人註冊過,此時可以按照提示換一個 app ID或基於已有app ID添加後綴——Change your bundle identifier to a unique string to try again。

5.The 'In-App Purchase' feature is only available to users enrolled in Apple Developer Program

只有開發者賬號才能真機調試 'In-App Purchase' 特性,所以需要在工程配置(Capabilities)中禁用普通Apple ID不支持的特性。



同樣,在 Xcode 8 中,也只有開發者賬號才能真機調試The 'Siri' feature,否則也會報錯“The 'Siri' feature is only available to users enrolled in Apple Developer Program.”而無法完成簽名認證


解決方法

在Xcode的 Project Navigator 中點擊*.xcodeproj ,在右側的 Targets 下選擇點擊目標 Target,在【Capabilities】中禁用“Push Notifications”、“In-App Purchase”、“Siri”。


如果找不到這些配置項,可嘗試直接修改項目配置文件中相應feature的配置開關,步驟如下

關閉 Xcode 正在打開的 Project,在 Finder 中右鍵項目配置文件 *.xcodeproj 顯示包內容,使用文本編輯器(例如 Sublime Text)打開 project.pbxproj 文件,搜索“SystemCapabilities”,依次找到“com.apple.Push”、“com.apple.InAppPurchase”、“com.apple.Siri”將其 enabled 鍵值從1修改爲0,關閉退出使用 Xcode 重新打開該項目。


6.Xcode配置反應有時候不那麼及時,可刷新、重置相關配置項開關(若有)或重啓Xcode試試。

十. Xcode7+ 免證書真機調試

在 Xcode 7 中,蘋果改變了自己在許可權限上的策略:

  1. 此前 Xcode 只開放給註冊開發者下載,現在 Xcode 7 改變了這種慣有的做法,無需註冊開發者賬號,僅使用普通的Apple ID就能下載和上手體驗。
  2. 此前開發者需每年支付99美元的費用成爲註冊開發者才能在 iPhone/iPad 真機上運行調試APP,蘋果新的開發者計劃則放寬要求,無需購買,只要你感興趣同樣可以在設備上測試app。——Developers would be able to test apps on devices without a paid Apple developer account in Xcode 7.

所謂“免證書”真機調試,並不是真的不需要證書,Xcode真機調試原有的證書配置體系仍在——All iOS, tvOS, and watchOS appsmust be code signed and provisioned to launch on a device. 所以,上文囉嗦幾千字還是有點用的。

自 Xcode7 開始,原來基於付費開發者賬號及自助生成證書及配置文件的繁瑣過程被蘋果簡化,Xcode將針對任何普通賬號自動爲聯調真機生成所需相關的證書及配置文件。當你打算向 App Store 提交發佈應用,才需要付費。

第一步進入 Xcode Preferences|Accounts,添加自己的 Apple ID 賬號。

第二步Build Settings|Code Signing 下的 Provisioning Profile 選擇 Automatic,Code Signing Identity 選擇 Automatic 下的iOS Developer

第三步:General 配置 Bundle identifier,Team 下拉選擇蘋果Member Center自動爲你的賬號生成的Personal Team ID。

自己的賬號在調試公司或其他第三方APP代碼時,若填寫 Bundle identifier 爲他人賬號註冊的 APP ID(例如蘋果相機應用 com.apple.camera),會報錯:

No provisioning profiles with a valid signing identity (i.e. certificate and private key pair) matching the bundle identifier “com.apple.camera” were found.

即使編譯通過了,可能運行時APP自身與服務器校驗也可能會報簽名錯誤,腫麼辦???

Her skill:此時,可以在他人原有App ID基礎上添加後綴(例如com.apple.camera.extension),配置成應用的衍生插件(相當於置於同一 App Group 下)就可以快樂的玩耍了。

解決了所有的開發配置問題,Xcode 8 Automatically manage signing 配置成功應該是這樣子的:


如果啓動APP時,Xcode報錯“process launch failed: Security”或iPhone報錯【不受信任的開發者】。


此時需要到iPhone通用配置中的描述文件(最新系統中可能叫設備管理)中,在描述文件(開發商應用)中選擇對應的描述文件(你的Apple ID)點擊 信任 或 驗證 即可。


OK,All Done!


參考:

iPhone真機調試應用程序》《iOS Developer:真機測試》《Xcode5 & iOS 7 及以下版本免證書真機調試記錄

iOS Development--Certificates, Provisioning Profiles關於Certificate、Provisioning Profile、App ID的介紹及其關係


數字簽名和數字證書iOS keyChain 研究

蘋果開發者賬號那些事兒iOS關於Provisioning Profiles這些事

iOS Code Signing 學習筆記代碼簽名探析/Inside Code Signing

iOS Code Signing: 解惑/iOS Code Signing: Under The Hood


iOS行貨自動打包解決Xcode無法生成Archive的問題iOS程序完成後如何生成ipa進行真機測試

發佈iOS應用程序(Application Loader)》《iOS發佈遇到的一些問題

Xcode打包ipa包》《iOS程序生成ipa進行真機測試


發佈了123 篇原創文章 · 獲贊 422 · 訪問量 381萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章