前言
以下是
iOS签名原理系列的文章链接
本篇是这个系列的最后一篇,下面进入正题
1. 名词介绍
在网络中,我们通过对信息进行数字签名,来验证信息的真实性、完整性。如果将数字签名运用到代码中,即对可执行文件(Mach-O)或脚本(代码)进行数字签名,便可保证app在签名后不被修改或损坏,保护app代码的完整性和安全性,这就是 代码签名。基于代码签名的这个特点,几乎所有的软件公司在发布app时都会对其进行代码签名,苹果公司也不例外。苹果的app签名机制能确保安装到用户苹果设备(如iPhone、iPad等)上的app都是经过苹果官方允许的。接下来,我们来详细介绍一下iOS签名原理。
数字签名是 非对称加密技术 与 数字摘要技术(Hash) 的应用。
先了解几个iOS签名相关的名词
1.1 App ID
App ID用于标识一个或者一组App。主要有两种:
- Explicit App ID:是app的唯一标识符,它由苹果为开发者创建的
team id和app的bundle id组成。每个app都会有且仅有一个明确的Explicit App ID。 - Wildcard App ID:即通配符App ID,用于标识一组app,以
*结束,如com.company.*标识以com.company开头的所有应用程序。
1.2 Certificate(即证书)
Certificate是用来给应用程序签名的,只有经过签名的应用程序才能保证他的来源是可信任的,并且代码是完整的、未经修改的。证书的后缀为.cer
在我们申请证书前,需要先申请一个
CSR(即Certificate Signing Request)文件,此过程实际上是生成一对密钥(即公钥和私钥),这对密钥将保存在开发者Mac电脑的Keychain(即钥匙串访问)中,CSR文件中则包含公钥。
证书类型有很多种,这里简单介绍一下常见的:
iOS App Development(即开发证书),用于开发和真机调试appiOS Distribution (App Store and Ad Hoc)(即分发证书),用于苹果应用市场(App Store)和内部分发渠道(Ad Hoc)APNS(Apple Push Notification Service,即苹果推送证书),用于推送通知到app。- 与开发证书和分发证书不同的是,
APNS与App ID有关。 APNS有两种证书,分别是用于开发环境的iOS Apple Push Notification service SSL (Sandbox),以及用于生产环境的Apple Push Notification service SSL (Sandbox & Production)。如果你的app有推送服务,这两种推送证书都是需要创建的。
- 与开发证书和分发证书不同的是,
1.3 p12文件
也叫做p12证书,因为其本身就是一个加密的证书,后缀为.p12。开发者将CSR文件发给苹果服务器,由此苹果服务器会生成Certificate文件(含公钥),接着开发者将其下载到本地,再导入钥匙串中后,就可以从钥匙串中导出p12证书。显然,p12文件里面有匹配的公钥和私钥。
注意:
p12文件一般是给开发团队的其他人使用的。当别人拿到p12文件和描述文件(后面会讲到),输入正确的密码后,就可以将p12导入到他的Mac设备的钥匙串中,然后再双击描述文件,即可添加到XCode中,从而参与团队开发。
1.4 Device(即设备)
Devices中包含了苹果开发者账号中所有可用于开发和测试的设备,每台设备使用UDID来唯一标识。在苹果开发者账户每年的会员期内,你能为每个产品添加最多100 个设备。
获取UDID的方法有很多种,作者常用的是在
iPhone的Safari浏览器中打开 fir.im/udid 网站即可获取设备的UDID。
1.5 Provisioning Profile(即描述文件)
一个描述文件包含了App ID、Certificate、Device,其后缀为.mobileprovision。常用的有:
- iOS App Development,用于开发时的真机调试,包含App ID、证书和设备
- Ad Hoc,用于分发时的真机调试,同样包含App ID、证书和设备
- App Store,用于分发到苹果应用市场,包含App ID和证书,与设备无关,且所有能访问App Store的苹果设备均可下载安装app。
描述文件的作用主要是:
- 限制只有在苹果后台注册过的设备才可以安装
- 限制签名只能针对某一个具体的App
描述文件中还包含
Entitlements(权限信息),权限信息指明了app使用的苹果服务,如iCloud权限、推送、苹果内购等。
2. iOS签名原理
2.1 真机调试
相信大多数开发者都实际操作过【申请证书和真机调试】(网上教程也多),那么问题来了,在【开发者用XCode打包app,并将其安装到手机】的过程中,苹果具体做了什么?这就要说到苹果的iOS签名流程了,可以用这幅图概括:

说明:苹果官方有一对密钥,即私钥和公钥,私钥在苹果后台,公钥在iOS系统中(如
iPhone手机在出厂后,其中就保存有苹果官方的公钥);在Mac系统打包app时也会生成一对密钥(私钥、公钥),并保存在钥匙串中。为了区分这两对密钥,将苹果官方的那对密钥记为A,即私钥A、公钥A;将Mac系统生成的那对密钥记为M,也就是私钥M、公钥M。
下面我们分析一下 iOS的签名原理(包括签名与验证):
-
XCode在向苹果服务器申请证书前,会先向钥匙串申请一个
CSR文件,同时生成一对非对称加密密钥,也就是私钥M和公钥M,并将公钥M放在CSR中。 -
XCode把
CSR文件发送给苹果服务器,用于申请证书。 -
苹果服务器用
私钥A对收到的公钥M进行签名,生成Certificate文件(即证书,后缀名为.cer,里面有公钥M)。接着对Certificate、Devices、App ID以及Entitlements一起组成的数据用私钥A进行签名,生成Provisioning Profile(即描述文件),并将它发给XCode。 -
iOS项目在编译完成之后会生成
.app文件,你可以在XCode的Project中找到它。有了.app文件,XCode先使用私钥M对.app进行签名,然后,把.app和描述文件一起压缩成安装包.ipa文件。
以上为
签名过程。补充说明:XCode用
私钥M对.app的签名分为两部分。
- 是对资源文件的签名,生成的签名文件名为
CodeResources,存放在.app目录下的_CodeSignature文件夹中。- 是对app的签名,其签名信息存放在
Mach-O的Code Signature中。(ps:关于Mach-O,作者以后会专门写一篇博文讲解)
-
XCode准备把安装包安装在苹果设备(如iPhone)上。
-
iPhone对安装包进行验证,即用
公钥A验证描述文件中的签名。验证通过则说明描述文件里的数据是苹果授权的。 -
当第【6】步验证通过后,再用
公钥A验证证书中的签名。验证通过则说明公钥M是安全可信任的。 -
第【7】步验证通过后,就可以取出描述文件里的数据做各种验证,包括用
公钥M验证App签名,验证iPhone是否在设备列表中,App ID是否对得上,使用的权限是否跟Entitlements对应等。当这些全部验证通过,iPhone就可以安装app了。
以上就是iOS签名的流程分析了,也就是iOS签名原理。显然,苹果用了两对非对称加密密钥,进行的是双重验证,基本保证了XCode真机调试的安全性,确保app的安装行为是受到苹果管控的。
理解
iOS签名原理后,再去对照实际申请证书的操作流程,相信你会有新的体会。
引申:
Ad Hoc分发流程与上述真机调试流程基本一致。In House企业分发流程也是大同小异,只是企业签名不限制安装的设备数,只要用户在iOS系统中信任企业证书,即可安装该企业证书签名的app了。
2.2 App Store签名验证
最后说一下App Store的签名验证,它与前面提到的签名验证有所不同。当开发者将ipa包上传到App Store后,苹果后台只需要用私钥A对其签名即可。当苹果设备(如iPhone)安装从App Store下载的安装包时,会自动用设备中的公钥A对app的签名进行验证,通过后即可正常安装。
感兴趣的同学可以去
App Store下载ipa包,看看里面是否有描述文件。
思考:为什么发布App Store的安装包时需要用到描述文件?如果证书和描述文件过期或被废除,会影响App Store上的安装包吗?