前言:对于一个iOS开发入门来说,一定会被一堆诸如:csr文件、私钥、Provisioning Profile、p12等名词搞的一头雾水。当年我也如此,但相信我,iOS的签名机制其实并不复杂,而了解这套机制对于iOS攻防的研究有很大帮助
何为签名
假设A和B进行通讯,A向B发送了一个讯息,B收到后,会有一个问题?如何证明这个信息来自于A?
了解过非对称加密算法的同学应该不难想出解决方法,利用非对称加密算法的特性:私钥加密内容,只有公钥能解密。只要保证私钥不泄露,把公钥发给需要通讯的对象。利用私钥加密数据,而收到数据的人利用公钥去解密,如果能解出正常的内容,那就证明这段讯息是来自对方。
实际上,网络上普遍使用的数字签名技术,就是基于这样的机制实现的:
图片来自于网络:
签名机制根本上要解决两个问题:
- 你正在安装的应用来自苹果授权
- 你正在安装的应用确实是你的应用
基于这两个问题,苹果搞出了一套双签名机制。首先,真对第一个问题,怎么证明应用是经过苹果授权的?这就牵扯出了第二个概念:证书
何为证书
每个iOS开发人员都会接触过发布证书,这东西到底干嘛的?
- 首先,在每一台 Mac 开发机器上,会生成一对公私钥,这里称为公钥Local,私钥Local。
- 苹果自己有固定的一对公私钥,私钥在苹果后台,公钥在每个 iOS 设备上。这里称为公钥Apple,私钥Apple。把公钥Local 传到苹果后台,用苹果后台里的私钥Apple 去签名公钥Local。得到一份数据包含了公钥Local以及其签名,把这份数据称为证书。
还记得我们在发布应用之前,去开发者网站生成发布证书的过程嘛?
每次在申请发布证书时,都会在钥匙串工具里导出一份csr文件(CertificateSigningRequest.certSigningRequest)传到苹果开发者网站上。而这个文件其实就是公钥Local,生成证书请求文件的过程就对应了之前提到的步骤1。
接下来,经过步骤2,我们就得到了发布证书(其中包括了公钥Local和签名Apple)。下载发布证书,安装到钥匙串中。你会发现你的证书和一个私钥进行了映射(这个私钥就是私钥Local,共私钥对应)
何为Provisioning Profile
仔细回想下接下来的流程:把证书安装到Mac后,回到苹果开发者网站,要去获取生产配置文件(Provisioning Profile 又是个老面孔)。生产配置文件除了包含刚才生成的证书,还有允许安装的设备列表(develop、adhoc、distribution的区别)、app id,以及Entitlements(这个大家应该也不陌生,你的App支持的权限:比如推送、内购、game center等)。
签名和验证机制
有了 证书 和 生产配置文件,我们才能打包上架App。在开发时,编译完一个 App 后,用本地的私钥Local 对这个 App 进行签名(签名Local),同时把 Provisioning Profile 文件打包进 APP 里,命名为 embedded.mobileprovision。
接下来是重头戏:应用在在安装时,iOS 系统取得证书,通过系统内置的公钥Apple,去验证 embedded.mobileprovision 的数字签名Apple是否正确。注意刚才的流程,embedded.mobileprovision里有我们从苹果获得的发布证书,由于发布证书是用私钥Apple签名的,还记得我们第一段讲述的,数字签名的机制嘛?这个流程能够验证刚才提到的第一个问题:你正在安装的应用来自苹果授权。
第一步验证完成之后,就能获取到证书内应用发布者的公钥Local,在应用打包时,我们会用私钥Local进行签名(签名Local),第二部验证:用公钥Local去验证签名Local,从而解决刚才提到的第二个问题:你正在安装的应用确实是你的应用。
其实,后面还会验证设备列表、权限开关等,这里就不展开讲了。
最后用一张图来描述下整体流程:
这里有个题外话:
p12到底是什么?
有很多开发人员会有这样的经历:即使从开发者网站上下载了发布证书一样无法发布应用。而是需要从生成发布证书的电脑上导出私钥:即p12文件。了解了整个签名机制应该就能明白,由于下载的证书会和生成证书的私钥建立对应关系,如果没有这个私钥,即使有证书,也无法在最后打包应用时,用私钥Local进行签名。而p12,就是可以导入到其他电脑的私钥Loacal。