iOS 应用签名原理

欢迎访问个人博客原文ios

很多果粉对 Apple 钟情,与它的纯净、安全有很大关系,咱们发如今苹果的设备上下载应用时,不会出现触发下载一系列垃圾软件的状况,并且用户能够明确 App 的来源——经过官方商店 AppStore 购买、企业证书安装仍是 TestFlight 下载。为了防止盗版软禁、病毒入侵、静默安装以及屏蔽其它不可控因素,并确保每个安装到 iOS 设备上的应用都是被官方容许的,苹果设定了一套应用签名机制算法

数字签名

数字签名,又称公钥数字签名,是只有信息的发送者才能产生的别人没法伪造的一段数字串,发送者对要发送的数据打上签名标记,表示这份通过认证,未被篡改的。安全

数据传输

下面模拟一下数据传输的过程:app

  1. 假如发送方直接将原始数据明文传输给接收方时,数据很是不安全,极易被篡改;测试

  2. 为了提高安全性并同时简化明文,能够对数据进行哈希算法处理,获得原始数据的摘要,而后将摘要发送给接收方。但假如哈希算法被泄漏,依然存在数据被篡改的风险;加密

  3. 引入非对称加密算法,对一份数据,用哈希算法计算出摘要后,再用 RSA 的私钥加密摘要,获得原始数据的数字签名,发送方将数字签名与原始数据一块儿发送给接收方调试

咱们将原始数据进行哈希加密、非对称加密后的数据称为数字签名code

接收方拿到数据后,须要进行签名验证,来确保数据传输过程当中,未被篡改。cdn

数字签名验证

签名验证的具体步骤以下:blog

  1. 接收方拿到数据后,经过一样的哈希加密处理原始数据,获得哈希值(摘要);

  2. 再利用非对称将数字签名中的校验哈希值(摘要)解密出来;

  3. 最后对比两个哈希值是否一致,判断出数据是否被篡改。

用一张图还原数字签名的完整过程:

再来看看如何利用数字签名保证每一个安装到 iOS 上的 App 都被苹果认证容许。

代码签名

代码签名就是对可执行文件或脚本进行数字签名,用来确认软件在签名后未被修改或损坏的措施。它的原理和数字签名相似,只不过把签名的不是数据,而是代码。

简单的代码签名

假如 App 是只能从 App Store 上下载,那么它的验证方式就比较简单了。

由苹果官方生成一对公私钥,在 iOS 系统中内置一个公钥,私钥由苹果后台保存。

咱们把 App 上传到 App Store 时,苹果后台用私钥对 App 数据进行签名,iOS 系统下载这个 App 后,用公钥验证这个签名,若是签名正确则这个 App 确定是由苹果后台认证的,而且没有被修改或损坏。

但 iOS 设备安装 App 并不仅有 App Store 这一个渠道,好比开发者的真机调试、TestFlight 内测、In-House 企业证书分发等,此时简单的代码签名就没法知足对 App 的彻底验证了。

iOS 代码签名的复杂度须要相应增长,因而双层代码签名(双重签名)产生了。

双层代码签名

“双层”意在用两对公私钥作加密验证,它们分别是 Mac 本地的一对和 Apple 服务提供的一对。

双层代码签名的存在是为了知足:

  • App 须要通过苹果容许才能安装;
  • 在 Apple 后台中注册过的设备才能安装,好比在 TestFlight 内测、真机调试模式下;
  • 限制签名只能对应惟一的 App。

为了猜想完整的签名流程,咱们能够解压一个 ipa 文件,在 Payload 目录中有一个 embedded.mobileprovision,咱们称之为描述文件,它对应的是 Apple 后台生成 Provisioning Profile(简称 PP)文件。文件中包括:

  • 证书(公钥、签名)
  • App ID
  • Entitlements(权限)
  • 注册设备列表
  • 其它关乎 App 可否正常启动的全部信息

因此咱们猜想签名的大概流程是这样的:

  1. 在开发设备 Mac 上本地生成一对公私钥。

  2. Apple 有一对公私钥,Apple 私钥在 Apple 后台,Apple 公钥在每台 iOS 设备上。

  3. 把 Mac 公钥上传到 Apple 后台,用 Apple 私钥签名 Mac 公钥,能够获得一份 Mac 公钥和签名的组合数据,咱们把这份数据称为证书

  4. 在 Apple 后台申请 App ID,配置好的 UDID(注册设备) 列表以及 App 申请的权限(Entitlements),再加上步骤3中的证书,组合起来的数据用 Apple 私钥进行签名,把数据和签名一块儿组成 PP 文件,下载到本地的开发设备 Mac 上。

  5. 当咱们编译工程时,Mac 私钥会对 App 进行签名,同时把步骤4获得的 PP 文件打包进去,文件名为 embedded.mobileprovision,准备将 App 安装到手机上。

  6. 安装时,iOS 系统取得证书,经过系统内置的 Apple 公钥,去验证证书里的签名是否正确。

  7. 继续用 Apple 公钥验证描述文件是否正确。

  8. 用 Mac 公钥验证 App 签名是否被篡改。

上面的步骤对应到实际操做和概念是这样的:

第 1 步:Mac 上依次打开“钥匙串访问 → 证书助理 → 从证书颁发机构请求证书...”,作了这一步,就会在本地生成了一对公私钥,导出的 CSR 文件(CertificateSigningRequest.certSigningRequest)就是 Mac 公钥,Mac 私钥也是存储在本地,具体是什么文件看第 3 步。

第 2 步:每台 iOS 设备中都已经有了 Apple 公钥,至于 Apple 私钥是什么,看第 3 步。

第 3 步:在 Apple 后台的 iOS Certificates 模块,经过上传本地导出的 CSR 文件,生成 .cer 证书文件,也就是 Apple 私钥。将 .cer 证书下载到本地,安装证书,在钥匙串中找到证书,就能够导出 Mac 私钥,也就是一个 .p12 文件。它和第 1 步中导出的 Mac 公钥是对应的,钥匙串会把这两个证书关联起来。用.cer 证书去签名 CSR 文件,拿到含有签名的证书。

第 4 步:在 Apple 后台配置 App ID、Entitlements、Devices 等,而后下载 PP 文件。

第 5 步:编译 App 时,XCode 会经过第 3 步下载回来的证书(存着 Mac 公钥),在本地找到对应的 Mac 私钥,而后用 Mac 私钥去签名 App,同时打包,安装包中包含 PP 文件,在 ipa 中的文件名是 embedded.mobileprovision。这里 App 的签名数据被分为两部分,Mach-O 可执行文件会把签名直接写入描述文件里,而资源文件则会保存在 _CodeSignature 目录下,这时准备安装 App。

第 6 步:使用 Apple 公钥验证描述文件签名,对应第 4 步,签名经过,说明证书可用,进入下一步。

第 7 步:使用 Apple 公钥验证证书签名,对应第 3 步,签名经过,说明 Mac 公钥合法,进入下一步。

第 8 步:使用 Mac 公钥验证 App 签名,对应第 4 步,上述验证均经过后,还须要将描述文件中的内容与 App 自己的信息作验证对比,好比验证设备 ID 是否在 UDID 列表上,App ID 是否相同,权限开关是否与 Entitlements 一致,都验证经过,就能够开始安装 App。

前面说了,双层代码签名是针对开发测试包、In-House 企业签名、Ad-Hoc 包为例的签名和验证的流程,只是企业签名不限制安装的设备数,所以描述文件中不会有设备列表,而是一条 <key>ProvisionsAllDevices</key><true/> 记录。

而从 App Store 上下载的安装包,里面是没有描述文件的,但上架以前仍是要配置证书、PP 文件,由于 App ID 和权限的检验仍是须要作的。但 App 上传到 AppStore 之后就跟 PP 文件没有关系了,因此咱们能够理解为 App Store 上包的签名验证采用就是前面说的最简单的签名方式,Apple 后台直接用私钥签名 App 就能够了。

相关文章
相关标签/搜索