由 HTTPS 理解 iOS 代码签名
January 18, 2018
参考:
平时在做 Android 开发的同时,偶尔做做 iOS 开发,同样是代码签名,Android 并不需要向 Google 申请什么证书,但对于 iOS APP 来说,需要向 Apple 申请证书,为了生成证书,又要生成公钥和私钥,我对这个流程一直搞不清,为什么需要这些证书,这些证书是用来做什么的?
直到无意间看了刘欣的公众号上的一篇文章 一个故事讲完 https,明白了 HTTPS 的工作机制后,恍然大悟,原来 iOS 的这一套流程和 HTTPS 的流程是几乎一样的。
先来看一下对比图:
在 HTTPS 体系中:
- 网站为了布署 HTTPS,需要生成公钥和私钥,然后向 CA 申请证书。
- CA 用自己的私钥为网站的公钥及其它信息进行数字签名,将网站的公钥及其它信息,和数字签名打包成数字证书,网站将数字证书存在服务器上。
- 浏览器首次访问 https 网站时得到其数字证书,用内置在浏览器中 CA 公钥进证书进行验证,验证 OK 说明证书中包含的网站公钥是信赖的,于是用网站公钥加密随机生成的对称密钥,发送给服务器。验证失败就提示警告信息,禁止继续访问。
- 服务器用私钥解密,得到对称密钥,随后双方用对称密钥进行对称加密通信。
而在 iOS 的体系中:
- Apple 扮演的正是 CA 的角色
- iOS APP 正如网站 - Website
- iOS 设备 (如 iPhone) 正如浏览器,内置了 Apple 的公钥
流程是这样的:
- 开发者首先为 iOS APP 在本地生成公钥私钥对,然后向 Apple 申请证书。
- Apple 用自己的私钥为 APP 的公钥及其它信息进行数字签名,然后 APP 的公钥及其它信息,和数字签名打包成数字证书,数字证书将会在 APP 编译打包时,把证书也打包进去。
- iOS APP 在打包时,同时将 APP 数据进行 Hash 后,用自己的私钥对 Hash 值进行数字签名,这个签名就是真正的代码签名,这个签名也会打包进 APP,它是用来在安装时校验 APP 数据的完整性。所以这里有双重签名。
- iOS 设备在安装 APP 时,首先用内置在设备中的 Apple 公钥,对 APP 中的证书进行验证,验证 OK 说明证书中包含的 APP 公钥是信赖的。验证失败,则不允许安装。
- iOS 设备取出证书中的 APP 公钥,用这个 APP 公钥继续对第二重签名,即代码签名进行验证,验证 OK 说明这个 APP 是完整的,没有被人篡改过。验证失败,则不允许安装。
来自 iOS App 签名的原理 的一张流程图:
HTTPS 和 iOS 代码签名的流程,在最后一步有较大的区别:
- HTTPS 中,浏览器用网站的公钥加密对称密钥,服务端用网站的私钥解密。
- iOS 代码签名中,APP 用自己的私钥对 APP Hash 值签名,iOS 设备用 APP 的公钥验证代码签名。
可见:
- 签名用私钥,加密用公钥。
- 签名的主要目的是为了验证其正确性,并非加密,因为它可以用公钥解密,而公钥人人皆知。
另外,HTTPS 的普及,让曾经在对安全要求比较高的网站 (比如银行网站) 上大行其道的各种安全插件就此下岗了。
对于 Android 的代码签名来说,由于在这个体系中,并没有 CA 的角色,因此它只有一重签名,即代码签名。