欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS App 签名机制的原理介绍

程序员文章站 2022-05-23 21:26:14
很多果粉(非程序员),会有这样的疑问,为什么android、windows、mac os等可以随便在哪里(应用商城)下载一个软件就能安装使用。而iphone (ipad、ipod 等非越狱 ios...

很多果粉(非程序员),会有这样的疑问,为什么android、windows、mac os等可以随便在哪里(应用商城)下载一个软件就能安装使用。而iphone (ipad、ipod 等非越狱 ios 设备)只能在appstore下载软件。其实了解的同学知道,这是苹果爸爸为了保证ios 平台对第三方 app 绝对的控制权和每一个安装到 ios 上的 app 的安全性。而采用的一种签名机制。那么问题来了,什么是签名机制呢?它的原理是什么?

数字签名

通常我们说的签名就是数字签名,它是基于rsa 非对称实现的。对称加密是通过同一份密钥加密和解密数据,而非对称加密则有两份密钥,分别是公钥和私钥,用公钥加密的数据,要用私钥才能解密,用私钥加密的数据,要用公钥才能解密。

那数字签名是怎么一回事呢?

数字签名的作用是我对某一份数据打个标记,表示我认可了这份数据(签了个名),然后我发送给其他人,其他人可以知道这份数据是经过我认证的,数据没有被篡改过。

ios app签名的原理

ios设备安装app 的几种方式

开发 app 时可以直接把开发中的应用安装进手机进行调试。 in-house 企业内部分发,可以直接安装企业证书签名后的 app。 ad-hoc 相当于企业分发的限制版,限制安装设备数量,较少用。 最普遍的从appstore 下载安装。

iosapp的签名流程

ios签名时需要一个证书(这里就不讲述证书的申请过程了),这个证书包含了很多信息,除了 设备 id / appid,还有其他信息也需要在这里用苹果签名,像这个 app 里 icloud / push / 后台运行 等权限苹果都想控制,苹果把这些权限开关统一称为 entitlements,它也需要通过签名去授权。

整个app 签名(正常发布的app)流程大致如下:

iOS App 签名机制的原理介绍

在你的 mac 开发机器生成一对公私钥,这里称为公钥l,私钥l。l:local

苹果自己有固定的一对公私钥,跟上面 appstore 例子一样,私钥在苹果后台,公钥在每个 ios 设备上。这里称为公钥a,私钥a。a:apple

把公钥 l 传到苹果后台,用苹果后台里的私钥 a 去签名公钥 l。得到一份数据包含了公钥 l 以及其签名,把这份数据称为证书。

在苹果后台申请 appid,配置好设备 id 列表和 app 可使用的权限,再加上第③步的证书,组成的数据用私钥 a 签名,把数据和签名一起组成一个 provisioning profile 文件,下载到本地 mac 开发机。

在开发时,编译完一个 app 后,用本地的私钥 l 对这个 app 进行签名,同时把第④步得到的 provisioning profile 文件打包进 app 里,文件名为embedded.mobileprovision,把 app 安装到手机上。

在安装时,ios 系统取得证书,通过系统内置的公钥 a,去验证embedded.mobileprovision的数字签名是否正确,里面的证书签名也会再验一遍。

确保了embedded.mobileprovision里的数据都是苹果授权以后,就可以取出里面的数据,做各种验证,包括用公钥 l 验证app签名,验证设备 id 是否在 id 列表上,appid 是否对应得上,权限开关是否跟 app 里的 entitlements 对应等。


前面以开发包为例子说了签名和验证的流程,另外两种方式 in-house 企业签名和 ad-hoc 流程也是差不多的,只是企业签名不限制安装的设备数,另外需要用户在 ios 系统设置上手动点击信任这个企业才能通过验证。

而 appstore 的签名验证方式有些不一样,前面我们说到最简单的签名方式,苹果在后台直接用私钥签名 app 就可以了,实际上苹果确实是这样做的,如果去下载一个 appstore 的安装包,会发现它里面是没有embedded.mobileprovision文件的,也就是它安装和启动的流程是不依赖这个文件,验证流程也就跟上述几种类型不一样了。

据猜测,因为上传到 appstore 的包苹果会重新对内容加密,原来的本地私钥签名就没有用了,需要重新签名,从 appstore 下载的包苹果也并不打算控制它的有效期,不需要内置一个embedded.mobileprovision去做校验,直接在苹果用后台的私钥重新签名,ios 安装时用本地公钥验证 app 签名就可以了。

那为什么发布 appstore 的包还是要跟开发版一样搞各种证书和 provisioning profile?猜测因为苹果想做统一管理,provisioning profile 里包含一些权限控制,appid 的检验等,苹果不想在上传 appstore 包时重新用另一种协议做一遍这些验证,就不如统一把这部分放在 provisioning profile 里,上传 appstore 时只要用同样的流程验证这个 provisioning profile 是否合法就可以了。

所以 app 上传到 appstore 后,就跟你的 证书 / provisioning profile 都没有关系了,无论他们是否过期或被废除,都不会影响 appstore 上的安装包。