不少果粉对 Apple 钟情,与它的纯净、安全有很大关系,我们发现在苹果的设备上下载应用时,不会出现触发下载一系列垃圾软件的情况,而且用户可以明确 App 的来源——通过官方商店 AppStore 购买、企业证书安装还是 TestFlight 下载。为了防止盗版软禁、病毒入侵、静默安装以及屏蔽其它不可控因素,并确保每一个安装到 iOS 设备上的应用都是被官方允许的,苹果设定了一套 应用签名机制 。 数字签名数字签名,又称公钥数字签名,是只有信息的发送者才能产生的别人无法伪造的一段数字串,发送者对要发送的数据打上签名标记,表示这份经过认证,未被篡改的。 数据传输下面模拟一下 数据传输 的过程:
我们将 原始数据进行哈希加密、非对称加密后的数据 称为 数字签名 。 接收方拿到数据后,需要进行签名验证,来确保数据传输过程中,未被篡改。 数字签名验证签名验证的具体步骤如下:
用一张图还原数字签名的完整过程: 再来看看如何利用数字签名保证每个安装到 iOS 上的 App 都被苹果认证允许。 代码签名代码签名就是对可执行文件或脚本进行数字签名,用来确认软件在签名后未被修改或损坏的措施。它的原理和数字签名类似,只不过把签名的不是数据,而是代码。 简单的代码签名假如 App 是只能从 App Store 上下载,那么它的验证方式就比较简单了。 由苹果官方生成一对公私钥,在 iOS 系统中内置一个公钥,私钥由苹果后台保存。 我们把 App 上传到 App Store 时, 苹果后台用私钥对 App 数据进行签名 ,iOS 系统下载这个 App 后, 用公钥验证这个签名 ,如果签名正确则这个 App 肯定是由苹果后台认证的,并且没有被修改或损坏。 但 iOS 设备安装 App 并不只有 App Store 这一个渠道,比如开发者的真机调试、TestFlight 内测、In-House 企业证书分发等,此时简单的代码签名就无法满足对 App 的完全验证了。 iOS 代码签名的复杂度需要相应增加,于是双层代码签名(双重签名)产生了。 双层代码签名“双层”意在用 两对 公私钥做加密验证,它们分别是 Mac 本地的一对和 Apple 服务提供的一对。 双层代码签名的存在是为了满足:
为了猜测完整的签名流程,我们可以解压一个 ipa 文件,在 Payload 目录中有一个 embedded.mobileprovision ,我们称之为 描述文件 ,它对应的是 Apple 后台生成 Provisioning Profile (简称 PP)文件。文件中包括:
所以我们猜测签名的大概流程是这样的:
上面的步骤对应到实际操作和概念是这样的: 第 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 包为例的签名和验证的流程,只是企业签名不限制安装的设备数,因此描述文件中不会有设备列表,而是一条 而从 App Store 上下载的安装包,里面是没有描述文件的,但上架之前还是要配置证书、PP 文件,因为 App ID 和权限的检验还是需要做的。但 App 上传到 AppStore 以后就跟 PP 文件没有关系了,所以我们可以理解为 App Store 上包的签名验证采用就是前面说的最简单的签名方式,Apple 后台直接用私钥签名 App 就可以了。 |