前言
以下是
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
上的安装包吗?