> For the complete documentation index, see [llms.txt](https://ryukiedev.gitbook.io/wiki/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ryukiedev.gitbook.io/wiki/ni-xiang/03.ios-ying-yong-qian-ming-yuan-li.md).

# 03.iOS应用签名原理

## 一：代码签名

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

### 1.1 简单的代码签名

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

最简单的方式就是通过：

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

### 1.2 问题

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

### 1.3 苹果的需求

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

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

## 二：双层代码签名

![双层签名](/files/-MZmXRFYsPW5hfZicF5H) 上面的只是简单的一部分，结合描述文件达到更严格的限制

## 三：描述文件

![双层签名和描述文件](/files/-MZmXRFZZN8b7aJbdjd0)

## 四：流程

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