# 03.iOS应用签名原理

## 一：代码签名

代码签名是对可执行文件或脚本进行数字签名，用来确认软件在签名后未被修改或者损坏的措施。和数字签名原理一样，只不过签名的数据是代码而已。

### 1.1 简单的代码签名

在iOS系统出来之前，以前主流的操作系统软件随便从哪里下载都能运行。存在安全隐患。苹果为了保证每一个安装到iOS设备上的App都是经过苹果允许的，设计了代码签名。

最简单的方式就是通过：

* 苹果官方生成非对称加密的一堆公私钥。
* 在iOS系统中内置一个公钥，私钥由苹果后台保存。
* 我们将App传到AppStore后
* 苹果后台用私钥对App进行签名
* iOS系统下载这个App后，用公钥验证这个签名。

### 1.2 问题

如果只能从AppStore安装App的话问题就简单了，但是实际上还是有很多渠道的。比如开发者调试安装，企业安装。这些就无法通过简单的代码签名来办到了。

### 1.3 苹果的需求

* 安装包不用上传AppStore，可以直接安装到手机上
* 苹果为了保证系统的安全性，必须对安装的App拥有绝对的控制权
  * 经过苹果允许才能安装
  * 不能被滥用导致开发者App也能被安装

为了达到上述目的苹果的方案是双层签名

## 二：双层代码签名

![双层签名](https://4193904735-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MI8JgbGh3U6X_oedqkm%2Fsync%2Fbfa5bc1a379215c07ec1bd5bf67240a70583e51e.png?generation=1620050563294229\&alt=media) 上面的只是简单的一部分，结合描述文件达到更严格的限制

## 三：描述文件

![双层签名和描述文件](https://4193904735-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MI8JgbGh3U6X_oedqkm%2Fsync%2Fbf9cdd299601e800db92d21a3d9b3da5913f3a14.png?generation=1620050564858219\&alt=media)

## 四：流程

* Mac电脑有一对密钥`公钥A`+`私钥A`
* 苹果服务器有一个`私钥B`
* iPhone有一个`公钥B`
* 电脑生成`CSR`文件（`公钥A`及`一些组织信息`），向苹果请求`描述文件`
  * 描述文件
    * 可安装的设备IDs
    * AppID
    * 应用权限
    * 证书
      * 被`私钥B`加密
      * `公钥A`
      * 公钥A的`hash`值
* 电脑打包出App
  * MachO文件
  * App的签名（用`公钥A`签名）
  * 证书
* 安装到iPhone上
  * `公钥B`解出证书中的`公钥A`
  * 用解出的`公钥A`验证App签名
  * 验证成功就可以安装了
