iOS開發證書要點詳解,ios證書詳解

iOS開發證書要點詳解,ios證書詳解

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

本文將對相關概念做個系統的梳理串燒。

首先,假設你使用過Apple設備(iMac/iPad/iPhone)且註冊過Apple ID(Apple Account)。

其次,你必須加入蘋果開發者計劃(Enroll in iOS Developer Program to become a member),註冊一個開發者賬號。

只有擁有開發者賬號,纔可以申請開發/發佈證書及相關配置授權文件,進而在iOS真機上開發調試Apps或發佈到App Store。

開發者賬號分爲Individual和Company/Organization兩種類型。如無特別交代,下文基於$99/Year的普通個人開發者(Individual)賬號展開。

.App ID(bundle identifier)

App ID用於標識一個或者一組App,App ID應該和Xcode中的Bundle Identifier是一致的或匹配的。

App ID字符串通常以反域名(reverse-domain-name)格式的Company Identifier(Company ID)作爲前綴(Prefix/Seed)。

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

  • Explicit App ID:唯一的App ID,這種App ID用於唯一標識一個應用程序。例如“com.apple.garageband”這個App ID,用於標識Bundle Identifier爲“com.apple.garageband”的程序。
  • Wildcard App ID:通配符App ID,用於標識一組應用程序。例如“*”(實際上是ApplicationIdentifierPrefix)表示所有應用程序;而“com.apple.*”可以表示以“com.apple.”開頭的所有應用程序。
用戶可在網站上刪除(Delete)已註冊的App IDs。
App ID被配置到【XcodeTarget|Info|Bundle Identifier】下;對於Wildcard App ID,只要bundle identifier包含其作爲Prefix/Seed即可。
.設備(Device)

Device就是運行iOS系統用於開發調試App的設備,每臺設備使用UDID來唯一標識。iOS設備連接Mac後,可通過iTunes->Summary或者Xcode->Window->Devices獲取iPhone的UDID(identifier)。

Apple Member Center網站個人賬號下的Devices中包含了註冊過的所有可用於開發和測試的設備。普通個人開發賬號每年累計最多隻能註冊100個設備,用戶可在網站上啓用/禁用(Enable/Disable)已註冊的Device。

  • Apps signed by you or your team run only on designated development devices.
  • Apps run only on the test devices you specify.
本文的Devices即連接到Xcode被授權用於開發測試的iOS設備(iPhone/iPad)。
.證書(Certificates)

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

證書分爲兩類: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。下文主要針對開發調試階段的Development證書。

首先,iOS以及Mac OS X系統(在安裝Xcode時)將自動安裝AppleWWDRCA.cer(Apple Worldwide Developer Relations Certification Authority)這個中間證書(Intermediate Certificates)。它實際上就是iOS證書的CA,其公鑰用於解密認證證書的可靠性。如果Mac Keychain Access證書助理在申請證書時尚未安裝過該證書,請先下載安裝(Signing requires that you have both the signing identity and the intermediate certificate installed in your keychain)。


通過Keychain證書助理手動申請開發證書時(也可通過Xcode自動請求生成),keychain將生成一個包含開發者身份信息的CSR(Certificate Signing Request)文件;同時,Keychain Access|Keys中將新增一對Public/Private Key Pair(This signing identity consists of a public-private key pair that Apple issues)。


private key用於簽名(CodeSign),始終保存在Mac OS的Keychain Access中;public key一般隨證書散佈出去,對簽名進行校驗認證。用戶必須保護好本地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文件,Apple證書頒發機構WWDRCA將使用private key對CSR中的public key和一些身份信息進行加密簽名生成數字證書(ios_development.cer)並記錄在案(Apple Member Center)。

從Apple Member Center網站下載證書到Mac上雙擊即可安裝。證書安裝成功後,在KeychainAccess|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)。

.供應配置文件(Provisioning Profiles

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

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

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

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

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

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

(1)Name:該mobileprovision的文件名。

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

(3)TeamName:Apple ID賬號名。

(4)TeamIdentifier:Team Identity。

(5)AppIDName:explicit/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-groups:App Group ID(group. com.apple),參見Code Signing Entitlements(*.entitlements)。

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

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

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

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

每個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都可以使用它在這個eam註冊的所有設備上調試所有的應用程序(不管bundleidentifier是什麼)。同時,它還會爲開發者自己創建的Wildcard/Explicit App IDs創建對應的iOSTeam Provisioning Profile。

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】下。

.App Group (ID)

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。

用戶可在網站上編輯Explicit App IDs的App Group Assignment;可以刪除(Delete)已註冊的AppGroup (ID)。

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

假如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)



每個證書(其實是公鑰)對應的私鑰會被用來對內容(executable code,resources such as images and nib files aren’t signed)進行數字簽名(CodeSign)——使用哈希算法生成內容摘要(digest)。上面已經提到,公鑰被包含在數字證書裏,數字證書又被包含在描述文件(Provisioning File)中,描述文件在應用被安裝的時候會被拷貝到iOS設備中。

iOS/Mac機上的ios_development.cer可以被AppleWWDRCA.cer中的 public key解密,從而獲取每個開發證書中可信任的公鑰。

1.iOS/Mac設備(系統)使用CA證書(WWDRCA.cer)來判斷App Provisioning Profile(Code Signing Identity)的合法性:

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

2.iOS/Mac設備(系統)使用AppProvisioning Profile(Code Signing Identity)證書來判斷App的合法性:

  • 若用證書公鑰能成功解密出App(executable code)的內容摘要(Signature),證明此App確乃認證開發者發佈,即來源可信;
  • 再對App(executable code)本身使用哈希算法計算摘要,若與上一步得到的摘要一致,則證明此App(executable code)未被篡改過,即內容完整。
.在多臺機器上實現開發賬戶/證書共享

若在Xcode Preferences添加了該Accounts,選中Team條目|ViewDetails:可以查看Signing Identities和Provisioning Profiles。

  • 選中欲導出的Account,點擊+-之後的☸|ExportAccounts,可導出包含account/code signingidentity/provisioning profiles信息的*.developerprofile(Exporting a Developer Profile)文件供其他機器上的Xcode開發使用(Import該Account)。
  • 選中欲導出的Signing Identity條目,點擊欄底+之後的☸|Export,必須輸入密碼,並需授權exportkey "privateKey" from keychain,將導出Certificates.p12;或在Keychain Access|Certificates中選中欲導出的certificate或其下private key,右鍵Export或者通過菜單File|Export Items導出Certificates.p12

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

九.證書配置常見錯誤

1. 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的provisioningprofile在本地不存在,此時需要更改Provisioning Profile。必要時手動去網站下載或重新生成Provisioning Profile或直接在Xcode中Fix issue予以解決(可能自動生成iOS Team ProvisioningProfile)!

2.Build Settings|CodeSigning的Provisioning Profile中選擇了本地安裝的provisioningprofile之後,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."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.Xcode配置反應有時候不那麼及時,可刷新、重置相關配置項開關(若有)或重啓Xcode試試。


參考:

《iPhone真機調試應用程序》《iOS Developer:真機測試》

《iOS Development--Certificates, Provisioning Profiles》

《關於Certificate、Provisioning Profile、App ID的介紹及其關係》


《iOS keyChain 研究》

《數字簽名和數字證書》

《蘋果開發者賬號那些事兒》

《iOS Code Signing 學習筆記》

《代碼簽名探析/Inside Code Signing》

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

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