木匣子

Web/Game/Programming/Life etc.

理解 iOS 开发证书

正式工作两年了,就在上个月,我换了份新工作,也换了个环境。从 Cocos2d-x + js 转战 Unity3d + ulua,于是又有很多东西要重头学起。在小创业团队跟大公司还是有很多不一样的,需要接触并掌握更多的东西,例如参与产品发布之类的环节。所以近来一段时间研究了一下苹果开发者计划,理解了一下它的工作机制。

0x00 Apple Developer Program

为了能够让自己开发的 App 发布到 App Store,苹果开放了 iOS 开发者计划 Apple Developer Program 。这个计划有四种类型:个人、公司、企业及高校。前两者的授权费用都是 $99 一年,适合个人或团队开发者。区别是,个人开发者以自己的名义发布 App,而公司则是以团体名义发布 App。此外公司是以法人(Agent)帐号注册 iOS 开发者计划,并且可以邀请其它开发者加入团队。其它人加入后,可以共同进行 App 开发。更多的细节可以参考 苹果开发者账号那些事儿 [1] [2] [3]

这里我并不记录这些帐号及证书的申请过程,有兴趣可以细读上面的链接。我更感兴趣的是这些东西是如何协作起来的。

0x01 Certificates

Development Certificate

当你拥有一个开发者帐号后,你需要申请一个「开发者证书」。根据证书创建的流程,首先需要在 Keychain Access 生成一个「证书签名请求」文件提交到苹果开发者中心,然后苹果开发者中心会生成一个「开发者证书」,下载这个证书并导入到 Keychain 之后,你就能将 APP 运行到真机上进行测试了。

可以简单将这个证书视为你参与开发者计划的证明,但是它是如何工作的呢?这是一个非对称加密体系的过程,如果你不了解 RSA,可以先看看这几篇介绍 RSA算法原理 [1] [2] 以及 现代密码学:RSA加密 [1] [2] [3]

当 Keychain 创建证书签名请求文件(CertificateSigningRequest.certSigningRequest)的时候,实际上在本地创建了一个私钥,然后将你填写的信息(邮件地址和用户名)带上公钥生成 CSR 文件(注意 CSR 并不包含私钥)。接下来将这个 CSR 文件提交到苹果开发者中心——其本质是一个证书颁发机构(CA),它会将 CSR 包含的信息与你的开发者帐号关联起来用 CA 的私钥签名并生成证书文件。这样一来,任何具有 CA 公钥的一方(例如未越狱的 iOS 设备)就能验证你所签名的 APP 确实是来自一个合法的开发者。

BTW:非苹果开发者在越狱设备调试 APP,正是利用自签名证书并替换或禁用设备上的CA公钥来绕开认证。

Distribution Certificate

当 APP 开发完成后,需要提交到 App Store 进行审核,或者打 ipa 包(ad hoc)在公司内部进行测试。这时候需要用「发行证书」对 APP 进行签名。其原理与「开发者证书」相似,证书的分离能让开发与部署在不同的环境下进行,对公司来说也更好管理不同开发人员的职能。

注意:备份好私钥及 CSR 文件,以便在证书过期或不同设备间协同开发/发布 APP 的时候使用。

0x02 APP IDs

每一个 APP 都有一个唯一的 ID 标识,一般格式为 com.company.product 。这一标识与 xcode 中的 Bundle Id 对应。在开发者中心的 Identifiers 频道可以对单个或多个 APP 设置相应的权限,例如启用/关闭「推送(Push Notifications)」功能。

Push Notifications

推送功能是很常用的一个功能。有趣的是,启用这个功能后也需要申请证书才能使用这个功能。苹果通过同样的机制来确保推送的信息来自合法的私钥持有方。如果使用第三方SDK,他们会要求你将私钥提提交给他们。一个 APP 可以有多个推送证书,且随时可以撤消该证书。

0x03 Devices

每个开发者帐户能够添加 99 台用于测试的 iOS 设备。只需要将设备的 Unique Device Identifier(UDID,可在 xcode > devices 中查看)添加到列表中即可,在最新版本的 xcode 中,第一次使用新设备时会自动完成添加。

0x04 Provisioning Profiles

配置文件用于管理特定的设备能否运行指定的证书签名的 APP 。同样分为 Development 和 Distribution 两种类型,xcode 会自动管理配置文件,并安装到开发设备上。但在国内常常会因为网络问题,xcode 没能及时地与苹果开发者中心同步配置文件,导致各种异常,这时可以到 xcode > preferences… > accounts 进行手工刷新。

其它参考资料

  1. iOS 开发流程笔记
  2. HTTPS 安全: 安全术语简介