iOS App的签名原理

概念

  • 证书:内容是公钥或私钥,由其他机构对其签名组成的数据包。
  • Entitlements:包含了 App 权限开关列表。
  • CertificateSigningRequest:本地公钥。
  • p12:本地私钥,可以导入到其他电脑。
  • Provisioning Profile:包含了证书/Entitlements等数据,并由苹果后台私钥签名的数据包

目的

  • 在iOS出来之前,在主流操作系统(Mac/Windows/Linux)上开发和运行软件是不需要签名的,软件随便从哪里下载都能运行,导致平台对第三方软件难以控制,盗版流行。苹果希望解决这样的问题,在 iOS 平台对第三方 APP 有绝对的控制权,一定要保证每一个安装到 iOS 上的 APP 都是经过苹果官方允许的,怎样保证呢?就是通过签名机制

非对称加密

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

数字签名

  • 数字签名的作用是我对某一份数据打个标记,表示我认可了这份数据(签了个名),然后我发送给其他人,其他人可以知道这份数据是经过我认证的,数据没有被篡改过。
iOS App的签名原理_第1张图片
签名.png
  • 首先用一种算法,算出原始数据的摘要。需满足:
    a.若原始数据有任何变化,计算出来的摘要值都会变化
    b.摘要要够短。这里最常用的算法是MD5
  • 生成一份非对称加密的公钥和私钥,私钥我自己拿着,公钥公布出去。
  • 对一份数据,算出摘要后,用私钥加密这个摘要,得到一份加密后的数据,称为原始数据的签名。把它跟
    原始数据一起发送给用户。
  • 用户收到数据和签名后,用公钥解密得到摘要。同时用户用同样的算法计算原始数据的摘要,对比这里计
    算出来的摘要和用公钥解密签名得到的摘要是否相等,若相等则表示这份数据中途没有被篡改过,因为如
    果篡改过,摘要会变化。

最简单的签名(AppStore)

  • 怎样通过数字签名的机制保证每一个安装到 iOS 上的 APP 都是经过苹果认证允许的

  • 要实现这个需求很简单,最直接的方式,苹果官方生成一对公私钥,在 iOS 里内置一个公钥,私钥由苹果后台保存,我们传 App 上 AppStore 时,苹果后台用私钥对 APP 数据进行签名,iOS 系统下载这个 APP 后,用公钥验证这个签名,若签名正确,这个 APP 肯定是由苹果后台认证的,并且没有被修改过,也就达到了苹果的需求:保证安装的每一个 APP 都是经过苹果官方允许的。

iOS App的签名原理_第2张图片
image.png

但实际上因为除了从 AppStore 下载,我们还可以有三种方式安装一个 App:

  1. 开发 App 时可以直接把开发中的应用安装进手机进行调试。
  2. In-House 企业内部分发,可以直接安装企业证书签名后的 APP。
  3. AD-Hoc 相当于企业分发的限制版,限制安装设备数量。

新的需求

  • 数字我们先来看第一个,开发时安装APP,它有两个个需求:
  1. 安装包不需要传到苹果服务器,可以直接安装到手机上。如果你编译一个APP到手 机前要先传到苹果服务器签名,这显然是不能接受的。
  2. 苹果必须对这里的安装有控制权,包括:
    • a. 经过苹果允许才可以这样安装。
    • b. 不能被滥用导致非开发app也能被安装。
      为了实现这些需求,iOS 签名的复杂度也就开始增加了

双层签名方案

iOS App的签名原理_第3张图片
image.png
  1. 在你的 Mac 开发机器生成一对公私钥,这里称为公钥L,私钥L。L:Local
  2. 苹果自己有固定的一对公私钥,跟上面 AppStore 例子一样,私钥在苹果后台, 公钥在每个 iOS 设备上。这里称为公钥A,私钥A。A:Apple
  3. 把公钥 L 传到苹果后台,用苹果后台里的私钥 A 去签名公钥 L。得到一份数据 包含了公钥 L 以及其签名,把这份数据称为证书。
  4. 在开发时,编译完一个 APP 后,用本地的私钥 L 对这个 APP 进行签名,同时 把第三步得到的证书一起打包进 APP 里,安装到手机上。
  5. 在安装时,iOS 系统取得证书,通过系统内置的公钥 A,去验证证书的数字签名 是否正确。
  6. 验证证书后确保了公钥 L 是苹果认证过的,再用公钥 L 去验证 APP 的签名, 这里就间接验证了这个 APP 安装行为是否经过苹果官方允许。(这里只验证安装 行为,不验证APP 是否被改动,因为开发阶段 APP 内容总是不断变化的,苹果不 需要管。)

避免滥用

  • 限制在苹果后台注册过的设备才可以安装
  • 限制签名只能针对某一个具体的 APP
iOS App的签名原理_第4张图片
image.png

最终方案

  • APP里iCloud/push/后台运行等权限苹果都想控制,苹果把这些权限开关统一称为Entitlements,它也需要通过签名去授权
iOS App的签名原理_第5张图片
image.png

一些疑问

  • 前面以开发包为例子说了签名和验证的流程,另外两种方式 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 上的安装包。

文章转载自传送门

你可能感兴趣的:(iOS App的签名原理)