前言
iOS真机调试、App打包等过程涉及到各种证书,CertificateSigningRequest、p12、Provisioning Profile。这些证书是什么,为什么需要这么做,相信很多同学是模糊的。本文从原理出发,一步步推出为什么会有这么多概念,有助于理解iOS App签名的原理和流程。
签名目的
在iOS出来之前,以前的主流操作系统(Mac/Windows)软件随便从哪里下载都能运行,系统安全存在隐患,盗版软件,病毒入侵,静默安装等等。那么苹果希望解决这样的问题,要保证每一个安装到 iOS 上的 APP 都是经过苹果官方允许的,怎样保证呢?就是通过代码签名。
非对称加密RSA原理
RSA 算法的可靠性基础:对极大整数做因数分解是很困难的。RSA 是非对称算法,加解密使用不同的密钥。
两个密钥都可以用于加密,解密时需要使用另一个密钥。但是,通常用公钥加密私钥解密,因为公钥是近乎完全公开的,对于私钥加密的数据,有太多的人可以解密了。理论上 A 和 B 之间要通过 RSA 实现保密通信,需要 A 和 B 各自生成一组密钥,同时保管好自己的私钥;用对方的公钥加密要发送的消息,用自己的私钥解密对方发送过来的消息。
在签名的场景下,用私钥签名,公钥验签。
苹果的需求
安装包不需要传到苹果服务器,可以直接安装到手机上。如果你编译一个App到手机前要先传到苹果服务器签名,这显然是不能接受的。
苹果必须对这里的安装有控制权,包括:
a.经过苹果允许才可以这样安装;
b. 不能被滥用导致非开发App也能这样安装;
为了实现这些需求,苹果这里给出的方案是使用了双层签名,流程大概是这样的:
1.在你的 Mac 开发机器生成一对公私钥,这里称为Mac公钥,Mac私钥。
2.苹果自己有固定的一对公私钥,私钥在苹果后台,公钥在每个iOS设备上。这里称为Apple公钥,Apple私钥。
3.把Mac公钥传到苹果后台,用苹果后台里的Apple私钥去签名Mac公钥。得到一份数据包含Mac公钥以及其签名,把这份数据称为证书。
4.在苹果后台申请AppID,配置好设备ID列表和APP可使用的权限,再加上第③步的证书,组成的数据用Apple私钥签名,把数据和签名一起组成一个Provisioning Profile文件,下载到本地Mac开发机。
5.在开发时,编译完一个APP后,用本地的Mac私钥对这个APP进行签名,同时把第④步得到的Provisioning Profile文件打包进APP里,文件名为embedded.mobileprovision,把APP安装到手机上。
6.7.安装时,通过系统内置的Apple公钥,去验证 embedded.mobileprovision的数字签名是否正确,里面的证书签名也会再验一遍。
8.确保了embedded.mobileprovision里的数据都是苹果授权以后,就可以取出里面的数据,做各种验证,包括用Mac公钥验证APP签名,验证设备ID是否在ID列表上,AppID是否对应得上,权限开关是否跟APP里的Entitlements对应等。
其他发布方式
另外两种方式In-House企业签名和AD-Hoc流程也是差不多的,只是企业签名不限制安装的设备数,另外需要用户在iOS系统设置上手动点击信任这个企业才能通过验证。
而AppStore的签名验证方式有些不一样,如果去下载一个AppStore的安装包,会发现它里面是没有embedded.mobileprovision文件的,也就是它安装和启动的流程是不依赖这个文件。