2.假设你或你所在的开发组已加入苹果开发者计划(Enroll in iOS Developer Program to become a member),即已注册开发者账号(Apple Developer Account)。
(1).只有拥有开发者账号,才可以申请开发/发布证书及相关配置授权文件,进而在iOS真机上开发调试Apps或发布到App Store。
(2).开发者账号分为Individual和Company/Organization两种类型。如无特别交代,下文基于$99/Year的普通个人开发者(Individual)账号展开。
3.若要真机调试实践,你必须至少拥有一台装有Mac OS X/Xcode的Mac开发机(iMac or MacBook),其上自带原生的Keychain Access。
一、App ID(bundle identifier)
App ID即Product ID,用于标识一个或者一组App。
App ID应该和xcode中Bundle Identifier是一致(Explicit) 的或匹配(Wildcard)的。
App ID字符串通常以反域名(reverse-domain-name)格式的Company Identifier(Company ID)作为前缀(Prefix/Seed),一般不超过255个ASCII字符。
App ID全名会被追加Application Identifier Prefix(一般为TeamID.),分为两类:
三、开发证书(Certificates)Device就是运行iOS系统用于开发调试App的设备。每台Apple设备使用UDID来唯一标识。
iOS设备连接Mac后,可通过iTunes->Summary或者Xcode->Window->Devices获取iPhone的UDID(identifier)。
Apple Member Center网站个人账号下的Devices中包含了注册过的所有可用于开发和测试的设备,普通个人开发账号每年累计最多只能注册100个设备。
- Apps signed by you or your team run only ondesignated development devices.
- Apps run only on the test devices youspecify.
用户可在网站上注册或启用/禁用(Enable/Disable)已注册的Device。
本文的Devices是指连接到Xcode被授权用于开发测试的iOS设备(iPhone/iPad)。
1.证书的概念
证书是由公证处或认证机关开具的证明资格或权力的证件,它是表明(或帮助断定)事理的一个凭证。证件或凭证的尾部通常会烙印公章。
2.数字证书的概念
数字证书就是互联网通讯中标志通讯各方身份信息的一串数字,提供了一种在Internet上验证通信实体身份的方式,其作用类似于司机的驾驶执照或日常生活中的身份证。它是由一个由权威机构——CA机构,又称为证书授权中心(Certificate Authority)发行的,人们可以在网上用它来识别对方的身份。
3.iOS(开发)证书数字证书是一个经证书授权中心数字签名的包含公开密钥拥有者信息以及公开密钥的文件。最简单的证书包含一个公开密钥、名称以及证书授权中心的数字签名。数字证书中的公开密钥(公钥)相当于公章。
数字证书还有一个重要的特征就是时效性:只在特定的时间段内有效。
某一认证领域内的根证书是CA认证中心给自己颁发的证书,是信任链的起始点。安装根证书意味着对这个CA认证中心的信任。
为了防止GFW进行中间人攻击(MitM),例如篡改github证书,导致无法访问github网站等问题,可选择不信任CNNIC:
在[钥匙串-系统]中双击CNNIC ROOT,在【信任】|【使用此证书时】下拉选择【永不信任】。
在[钥匙串-系统]中双击CNNIC ROOT,在【信任】|【使用此证书时】下拉选择【永不信任】。
在天朝子民的一生中,户籍证明可理解为等效的根证书:有了户籍证明,才能办理身份证;有了上流的身份证,才能办理下游居住证、结婚证、计划生育证、驾驶执照等认证。
下文主要针对iOS App开发调试过程中的开发证书(Certificate for Development)。
那么,iOS开发证书是谁颁发的呢?或者说我们是从哪个CA申请到用于Xcode开发调试App的证书呢?
iOS以及Mac OS X系统(在安装Xcode时)将自动安装AppleWWDRCA.cer这个中间证书(Intermediate Certificates),它实际上就是iOS(开发)证书的证书,即根证书(Apple Root Certificate)。
AppleWWDRCA(Apple Root CA)类似注册管理户籍的公安机关户政管理机构,AppleWWDRCA.cer之于iOS(开发)证书则好比户籍证之于身份证。
如果Mac Keychain Access证书助理在申请证书时尚未安装过该证书,请先下载安装(Signing requires that you have both the signing identity and the intermediate certificate installed in your keychain)。
可以在缺少证书时通过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,以防伪冒。
在Apple开发网站上传包含公钥的CSR文件作为换取证书的凭证(Upload CSR file to generate your certificate),有点类似为github账号添加SSH公钥到服务器上进行授权。
Provisioning Profile文件包含了上述的所有内容:证书、App ID和设备 ID。
首先,需要指明它的App ID,并且验证Bundle ID是否与其一致;Provisioning Profile把这些信息全部打包在一起,方便我们在调试和发布程序打包时使用。这样,只要在不同的情况下选择不同的Provisioning Profile文件就可以了。
其次,需要证书对应的私钥来进行签名,用于标识这个APP是合法、安全、完整的;
然后,如果是真机调试,需要确认这台设备是否授权运行该APP。
(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:包含了可以为使用该配置文件应用签名的所有证书
。
证书是基于Base64编码,符合PEM(PrivacyEnhanced Mail, RFC 1848)格式的,可使用OpenSSL来处理(opensslx509 -text -in file.pem)。
从DeveloperCertificates提取之间的内容到文件cert.cer(cert.perm):
-----BEGIN CERTIFICATE-----
将之间的内容拷贝至此
-----END CERTIFICATE-----`
Mac下右键QuickLook查看cert.cer(cert.perm),在Keychain Access中右键Get Info查看对应证书ios_development.cer,正常情况(公私钥KeyPair配对)应吻合;Windows下没有足够信息(WWDRCA.cer),无法验证该证书。
如果你用了一个不在这个列表中的证书进行签名,无论这个证书是否有效,这个应用都将CodeSign Fail。
(8)Entitlements键
对应的 :
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)ProvisionedDevices:该mobileprovision授权的开发设备的UDID
。
Provisioning Profile被配置到【XcodeTarget|Build Settings|Code Signing|Provisioning Profile】下,然后在Code Signing Identity下拉可选择Identities from Profile "..."(即Provisioning Profile中包含的Certificates)。
每个Apple开发者账号都对应一个唯一的Team ID,Xcode3.2.3预发布版本中加入了Team Provisioning Profile这项新功能。
在Xcode中添加Apple Developer Account时,它将与Apple Member Center后台勾兑自动生成iOS Team Provisioning Profile(Managed by Xcode)。
Add an Apple ID account to Xcode利用Xcode生成和管理的iOS Team Provisioning Profile来进行开发非常方便,可以不需要上网站手动生成下载Provisioning Profile。
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
六.App Group (ID)
1.App Group的概念置于同一App Group下的App IDs必须是唯一的(Explicit,not Wildcard)假如Garageband这个App ID为“com.apple.garageband”,则支持从语音备忘录导入到Garageband应用的插件的App ID可能形如“com.apple.garageband.extImportRecording”。
Extension App ID以Containing App ID为Prefix/Seed
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生成流程。
Xcode中配置的Code Signing Identity(entitlements、certificate)必须与Provisioning Profile匹配,并且配置的Certificate必须在本机Keychain Access中存在对应Public/Private Key Pair,否则编译会报错。
Xcode所在的Mac设备(系统)使用CA证书(WWDRCA.cer)来判断Code Signing Identity中Certificate的合法性:
Xcode使用指定证书配套的私钥进行签名时需要授权,选择【始终允许】后,以后使用该私钥进行签名便不会再弹出授权确认窗口。
上面已经提到,公钥被包含在数字证书里,数字证书又被包含在描述文件(Provisioning File)中,描述文件在应用被安装的时候会被拷贝到iOS设备中。
第一步,App在Mac/iOS真机上启动时,需要对配置的bundle ID、entitlements和certificate与Provisioning Profile进行匹配校验:
若用证书公钥能成功解密出App(executable code)的内容摘要(Signature),证明此App确乃认证开发者发布,即来源可信;小结:
再对App(executable code)本身使用哈希算法计算摘要,若与上一步得到的摘要一致,则证明此App(executable code)未被篡改过,即内容完整。
基于Provisioning Profile校验了CodeSign的一致性;
基于Certificate校验App的可靠性和完整性;
启动时,真机的device ID(UUID)必须在Provisioning Profile的ProvisionedDevices授权之列。
选中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到本地。
其他Mac机器上双击Certificates.p12(如有密码需输入密码)即可安装该共享证书。有了共享证书之后,在开发者网站上将欲调试的iOS设备注册到该开发者账号名下,并下载对应证书授权了iOS调试设备的Provisioning Profile文件,方可在iOS真机设备上开发调试。
九.证书配置常见错误
1.no such provisioning profile was found4.Xcode配置反应有时候不那么及时,可刷新、重置相关配置项开关(若有)或重启Xcode试试。
十. Xcode7 免证书真机调试
在 Xcode 7 中,苹果改变了自己在许可权限上的策略:所谓“免证书”真机调试,并不是真的不需要证书,Xcode真机调试原有的证书配置体系仍在——All iOS, tvOS, and watchOS appsmust be code signed and provisioned to launch on a device. 所以,上文啰嗦几千字还是有点用的。此前 Xcode 只开放给注册开发者下载,现在 Xcode 7 改变了这种惯有的做法,无需注册开发者账号,仅使用普通的Apple ID就能下载和上手体验。
此前开发者需每年支付99美元的费用成为注册开发者才能在 iPhone/iPad 真机上运行调试APP,苹果新的开发者计划则放宽要求,无需购买,只要你感兴趣同样可以在设备上测试app。——Developers would be able to test apps on devices without a paid Apple developer account in Xcode 7.
《iPhone真机调试应用程序》 《iOS Developer:真机测试》 《Xcode5 & iOS 7 及以下版本免证书真机调试记录》
《关于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发布遇到的一些问题》 《Xcode打包ipa包》