详解iOS打包、发布与证书体系

一个iOS应用最终能在用户的设备上使用,是经过了开发 -> 打包 -> 发布 -> 下载安装过程的。为了更易于理解,以及避免从一开始就陷入细节,本文将逆序讲述整个过程。

一、背景

在iOS开发中,大概每个新手都被各种配置、证书、打包和发布等事情折腾过,我亦如此。

教程一搜一大堆,照着教程1234也能做下来。但是在这个过程中,我会产生很多问号:

  • 为什么程序能在模拟器上运行,却无法在真机上运行?
  • 为什么不是每个人都能在本地打包?具备什么条件才能打包?
  • 为什么需要证书,描述文件?
  • 生成证书的原理是怎样的?
  • ... ...

很多事情是知其然而不知其所以然。

为了解决心中的疑惑,我借着项目的机会,研究了一番整个打包发布的流程,以及流程中每一步操作的背后都发生了什么。

之后便总结成了这篇文章,分享给大家,希望能使新手iOS开发同学对iOS的打包、发布和证书体系有更直观的了解。

一个iOS应用最终能在用户的设备上使用,是经过了开发 -> 打包 -> 发布 -> 下载安装的过程的。

为了更易于理解,以及避免从一开始就陷入细节,本文将逆序讲述整个过程。

二、iOS应用的安装方式

作为一个iOS用户,我能通过哪些途径安装app?

  1. App Store

    App Store是Apple官方的App发布平台。在App Store中搜索并安装App,也是作为一个普通用户最常用的安装方式。

  2. TestFlight

    TestFlight是Apple官方的App测试平台。在上架到App Store之前,可以通过TestFlight邀请一部分用户参与测试,类似于网络游戏的公测。

  3. App Center, FIR...

    除了官方的Apple Store之外,市面上还存在着App Center, FIR等非Apple官方的App管理平台。在开发过程中,我们通常会将各个环境的App上传到这些非官方的平台中,用于日常测试;另外,我们也会将其作为企业级应用的最终发布平台。

  4. 通过Xcode安装到真机

  5. 通过Xcode安装到模拟器

    在开发过程中,DEV们作为特殊的iOS用户,也会通过IDE直接在真机或模拟器上进行开发和测试。这里把真机和模拟器分开,是因为它们确有不同。关于不同之处,我们将会在后文中谈到。

上面列出的,是用户,以及DEV、QA同学最常用的5种安装方式。那么这篇文章是要讲打包和发布,为什么我们要了解这些安装方式呢?

是因为不同的安装方式本身,背后就对应着不同类型的发布方式。

或者更严谨的说,不同类型的发布方式,就决定了用这种发布方式打出来的app,最终能通过哪种安装方式安装到机器上。

三、iOS应用的发布方式

作为打包的那个人,我能通过选择发布方式,来决定我的应用能让哪些用户、通过何种安装方式下载安装

虽然我们有着以上不同的安装方式,但其实本质上都是从某个平台上,下载一个软件包到本地并安装(Xcode除外)。

不同的平台做的也是同样的事情,即提供一个存放软件包的仓库,可供用户下载软件包。

发布,就是把软件包上传到发布平台。这步就无需赘述了。

那么我们再往前一步:打包

简单来说,所谓打包,就是将源码转换成iOS系统的软件包-ipa文件iPhone application archive

对于一个iOS应用,它的打包过程包括:

  1. 选择发布方式
  2. 选择证书和描述文件
  3. 编译 & 签名
  4. 导出ipa文件

本节我们关注第一步:选择一个发布方式。

Apple提供了4种发布方式:

图1 iOS应用的发布方式

图1 iOS应用的发布方式

  1. App Store Connect -上架App Store以及TestFlight的app,用于生产环境发布
  2. Ad Hoc - 部分机器可安装的app,用于非生产环境的测试
  3. Enterprise - 企业级应用发布
  4. Development - 与Ad Hoc类似,只有后续步骤所需要的证书和描述文件不同

结合上文,安装方式和发布方式之间的关系可以表示成:

安装方式和发布方式之间的关系

图2 安装方式和发布方式之间的关系

我们再对比它们之间的主要区别:

安装方式和发布方式之间的区别

图3 安装方式和发布方式之间的区别

从上图中我们能得出一些结论:

  • 能从App Store和TestFlight上安装使用的,一定是App Store Connect的发布方式。
  • 只有App Store中app和企业级应用没有安装数量上的限制。
  • 只要向真机上安装app,无论选择哪种安装方式或发布方式,都需要证书,签名,描述文件。

这里我自己的一些额外猜想是,Apple通过发布方式上的限制,确保真正public的应用只能通过Apple审核 ,App Store下载安装。

但大家可能会发现,企业级应用也没有任何安装数量上的限制,甚至不需要审核。那是否可以把企业级应用public的发布呢?

答案是否定的。

首先,企业级应用需要Apple企业账号,Apple对于企业级账号的发放是非常严格的。

其次,Apple规定企业级应用的下载途径不可公开,若发现公开则会有封号,应用失效的后果。

因此,虽然从能力上看企业级应用能被安装在任意一台机器上,但是从途径上Apple限制了可能性。

至于只要向真机上安装app,都需要证书,签名,描述文件,我猜测这是对每一台设备负责吧。

现在我们讲完了打包的第一步发布方式,下一步就是选择证书和描述文件。

我们已经知道,只要向真机上安装app,哪怕是Xcode直接运行,就都需要证书,签名,描述文件。

那么这些资源从哪来、怎么来,就是我们接下来的话题。

四、Apple Developer Account和Member Center

作为负责打包发布的人,我要如何、在哪管理开发和发布所需要的资源?

证书、描述文件等资源被维护在Member Center中。它是开发者的资源管理中心,可以全生命周期管理:

  • 证书,签名,描述文件等资源
  • TestFlight、Apple Store上的应用
  • ... ...

登陆Member Center需要开发者账号Apple Developer Account

开发者账号有不同的类型。不同类型的开发者账号对应的Member Center拥有不同的能力。

1. 开发者账号的种类

开发者账号的种类

图4 开发者账号的种类

从大类上,开发者账号分为三种:个人、组织和教育机构。教育机构这个类别我并没有接触过,也就不在这里深入。

在4个小类中,公司和个人类型的账号只有能否有团队成员这一个区别。因此实际上很多开发者会把个人类型的账号转为公司类型,便于团队协作。

也正是因为大多数应用都需要不止一个DEV来开发,所以比较常用的开发者账号类型就是支持development team的公司和企业级应用。

对于公司和企业级应用,二者之间除了账号的年费不一样之外,最重要的区别在于,它能否将应用上架App Store

那么为什么企业级账号无法将应用上架App Store呢?

这里大概解释一下:

从前文我们已经知道,想要上架App Store,就必须选择App Store Connect的发布方式。

选了某种发布方式之后,后续步骤所需要的证书,描述文件等的类型也是不一样的。

在Member Center中,企业级账号只能生成发布企业应用所需的证书,无法生成App Store Connect的发布方式所需的证书,当然也就没有上架App Store的能力。

同样,公司账号也无法生成企业级证书,无法发布企业级应用。

2. Member Center的用途之:管理ID、设备、证书、描述文件

全生命周期管理ID、设备、证书、描述文件,是Member Cente最重要的功能之一。

下面,我们分别看看它们的概念、用途和生成方式。

(1)ID - 唯一标识符,根据用途分为App ID、Music ID、Merchant IDs等

目前我们只考虑最简单的情况,就只介绍iOS应用必须的,用于标识一个或一组应用的App ID。

下图即用公司类型的开发者账号注册一个App ID的过程:

注册一个App ID

图5 注册一个App ID

从图中我们可以的看出:

  • App ID需要指定应用平台
  • App ID与Team ID绑定在一起。即,Apple知道一个应用的ID是注册在哪个开发者账号下的,也只允许这个账号内的成员在真机上调试或打包。
  • App ID指定了应用的capabilities,如:获取WI-FI信息、使用钱包、健康、SIRI....

(2)设备 - 能安装该开发者账号下的应用的设备

设备的概念就更简单了。每个苹果设备都有一个唯一标识符UDID - Unique Device Identifier

将某个设备注册到开发者账号下,就是在注册时将该设备的UDID填入。同一台设备可以被注册到多个开发者账号下。

可以理解为开发者账号通过UDID列表,形成自己的设备资源池。

(3)证书 - 由Apple 证书认证中心颁发的,用于确保应用内容可靠性和完整性的凭证

证书分为两种:

  1. 开发证书,用于日常开发;
  2. 发布证书,用于应用发布。

生成一个证书的步骤也很简单:

只需要在借助keychain在本地生成一个CSR文件,然后通过开发者账号上传,成功后就会存在于证书资源池中,在失效前可随时使用下载(这里我们只需要了解生成证书的步骤,至于这个过程中都发生了什么,以及证书如何能确保应用的可靠性,我们后面会详述)。

生成一个证书

生成一个证书

图6 生成一个证书

(4)描述文件 - 一个ID,设备,证书的集合

你可能已经发现了,前面的ID,设备和证书的都是各自独立的,我们看不到它们之间有任何的联系。

而描述文件正是把这些资源整合到一起的集合。

一个描述文件包含:

  • 一个App ID
  • 开发或发布证书
  • 一组可安装该应用的设备列表(非必有)

描述文件会被打包到应用中,描述该应用的App ID、持有的发布证书、以及能被哪些设备安装。

描述文件与证书一样,也分开发发布两大类型。其中,发布又被细分为Ad HocApp StoreEnterprise类型。

还记得前面说的4种发布方式吗?它们和描述文件的类型是一一对应的。

在打包的第一步选择了一个发布方式后,第二步就必须要选择相应的描述文件。

生成一个描述文件的步骤,就是选择一个类型,然后在开发者账号下的ID、设备、证书资源池中选出资源,将它们整合到一起。

最后,我们用更直观的图来表述描述文件与安装方式、发布方式之间的关系:

描述文件与安装方式、发布方式之间的关系

图7 描述文件与安装方式、发布方式之间的关系

至此,我们已经大致了解了开发者账号和它管理的App ID、证书、设备和描述文件,能够完成打包的第二步了。

接下来就是第三步编译和签名,我们重点关注签名。

签名与证书紧密相关。

为了更好的了解签名的原理和作用,我们将从证书开始讲起。

五、证书的生成

上一节讲过证书的生成步骤:

  1. 借助keychain在本地生成一个CSR文件

  2. 通过开发者账号将CSR上传至Member Center

  3. 从Member Center下载证书

但看这个描述,我们根本无法得知每一步的原理和目的。比如:CSR是什么,有什么用;上传CSR成功为什么能生成一个证书?这中间Apple又做了什么?

相信这些问题在这一小节结束后,你会知道答案。

1. 生成CSR文件: Keychain -> 证书助理 -> 从证书颁发机构请求证书

生成CSR文件

图8 生成CSR文件

CSR(Certificate Signing Request)文件是用keychain生成的,包含了请求证书者的个人信息的,用于向Apple证书颁发机构(Apple Worldwide Developer Relations Certification Authority,为了简单理解,后文统称Apple Root CA)申请证书的一个文件。

CSR文件的内容

图9 CSR文件的内容

想象一个场景:如果你去银行办理一张储蓄卡,那么银行就会要求你提供身份证,并填一份申请单,添上姓名、籍贯、常用住址等个人信息。

我们简单做一下类比:Apple Root CA就相当于银行,证书相当于储蓄卡,CSR文件就相当于储蓄卡的申请单。

生成CSR的时候发生了什么?

  1. 通过非对称加密,在本地生成了证书的公钥和私钥,保存在Keychain中(虽然与非对称加密的方式并不一致,但为了便于理解,我们把私钥类比成储蓄卡密码)
  2. 将公钥和个人信息一起组合形成了CSR

这里插播一点对非对加密的简单理解:通过非对称加密生成的一对公钥和私钥,它们能互相解密出经过对方加密后的信息,并且也只有它们才能解密。

如果我们将+和-分别定义为加密和解密,那么:

非对称加密

图10 非对称加密

2. 通过开发者账号将CSR上传至Member Center

成功后,我们就能在Member Center上下载证书了。

回到办理银行卡的流程:你将身份证、申请单交给工作人员,工作人员确认你本人和身份证相符,然后经过一系列的操作,最终会把办理好的银行卡交给你。

银行卡中是包含了你的个人信息的,因为办理很多的业务,都需要你本人携带身份证,并保证和开户信息一致。

这正是对应了当前这一步。

类比于银行工作人员的一系列操作,Apple Root CA在从CSR到证书的过程中做了什么呢?

首先,Apple Root CA是有一个由自己颁发的证书的(CA证书)。同样,这个证书也有它对应的公钥和私钥。

当我们将CSR传给Apple Root CA,它会在验证身份之后,后用CA证书的私钥,对公钥和部分个人信息做加密,然后连同CSR中的公钥一起,形成证书,并记录在Member Center中。

证书生成的原理

图11 证书生成的原理

3. 从Member Center下载证书

下载证书到本地并安装。由于证书中包含证书的公钥,我们本地保存着证书的私钥,所以它们在Keychain中可以匹配得上:

安装证书到本机

图12 安装证书到本机

六、签名

加密应用的内容

打包的第三步:编译和签名。对应用签名,就是用证书的私钥加密应用的内容。签名会一并打包到应用中。

签名是打包的必需步骤。

签名需要证书的私钥。

证书的私钥保存在证书申请人的keychain中。

App的签名

图13 App的签名

因此:

  • 作为非证书申请人,如果你想在本地打包,则需要向证书申请人请求私钥。
  • 作为证书申请人,请像保护银行卡密码一样保护私钥,尽量不分发私钥。分发私钥意味着其他人可以以你的名义打包和发布应用。

至此,我们已经介绍完了打包的核心步骤。

那么我们为什么需要证书和签名呢?

七、证书和签名的作用

用证书验证签名,从而保证App来源可信

前面我们讲了签名和证书的生成过程,这里终于到了展现它们用处的时候了。

我们将通过2步验证,最终相信应用的可靠。

首先我们来回顾前面的内容:

  • 描述文件中包含有证书
  • App中包含有描述文件和签名

除此之外,iOS设备默认装有并信任Apple Root CA证书。

iOS 设备上的App和Apple Root CA证书

图14 iOS 设备上的App和Apple Root CA证书

下面我们开始验证:

1. 用Apple Root CA证书,验证应用证书的有效性

应用证书的签名,是由Apple Root CA的私钥加密应用证书的公钥和一些个人信息得到的。

如果用Apple Root CA证书中的公钥,能解密应用证书的签名得到应用证书上公钥,则能证明应用证书是由Apple颁发的。

验证App证书的有效性

图15 验证App证书的有效性

2. 用验证过的应用证书,验证应用签名的有效性

应用签名,是由应用证书的私钥加密应用内容得到的。

如果用应用证书中的公钥,能解密应用签名得到应用的内容,则能证明签名有效,应用可信。

验证App签名的有效性

图16 验证App签名的有效性

八、不是总结的总结

通过以上内容,我们了解到iOS应用打包发布的流程,和证书体系。

在这里,我刻意的没做总结。

开篇的那些问题,大家找到答案了吗?


更多精彩洞见,请关注微信公众号:ThoughtWorks洞见

Share

One Comment

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据