iOS APP 开发 OC 第十四天,打包签名,你真的懂吗? 阅读笔记

iOS APP 开发 OC 第十四天,签证

tags: OC 30 day


资料来源:iOS 打包签名,你真的懂吗?-一意孤行的程序员

iOS 为什麽需要签名?

为了保证App的分发平台是可控的,以及保证所有安装到iOS设备上的App都是经过苹果官方允许的,苹果建立了iOS签名打包机制。要了解iOS签名机制的实现,我们首先从签名机制的原理说起。

对称加密

对称加密是指数据发送者(A)和接收者(B)双方进行加解密的密钥是一致的,但这样会增加密钥自身分发的不安全性:比如要如何保证密钥在传递过程中不被泄露。

不对称加密

不对称加密则由A、B持有一对公私钥进行加解密,公私钥钥匙是成对出现的。对於一个私钥,有且只有一个与其对应的公钥,私钥保密、公钥公开,但是不能通过公钥推导出私钥,使用私钥加密的文件可用公钥解密,反过来公钥加密的文件也只能用私钥进行解密。加密过程如下:

发送方(A)首先生成一对公私钥钥匙对,私钥自己保管,公钥则任意分发出去(每台iOS设备终端其实已经包含Apple的公钥)。
发送数据时,发送方使用私钥对原数据加密成密文传输(加密打包ipa);
接收方(B)收到密文後,使用之前已经获取到的公钥进行解密得到数据内容(iOS设备验证安装ipa)。

笔记:
对称加密:只要拿到密钥,我就可以随意的加密解密。
不对称加密:外部只可以拿到公钥,我拿到公钥,也只能对私钥加密的文件解密。另外外部拦截到公钥加密的密文,我也无法解密。

数据签名

这里主要解决了两个问题,一个是加密数据大小的问题,另一个是如何验证公钥的有效性。

信息摘要

前面已经讲到,iOS打包安装的过程中会对ipa包进行加解密验证。然而ipa安装包大小动辄就有十几M,大的有好几G,那如果对这麽大的数据量进行加解密,肯定效率是非常低的。而信息摘要则是解决了加密数据过大的问题,其原理是对信息内容通过一个很难被逆向推导的公式计算得到一段哈希数值,它具有以下特点:

计算得到的哈希值大小固定,不受原本信息内容大小的影响;
不可逆,根据哈希值无法推断得到原本信息(实际上MD5以及SHA-1算法已经被证明可以被破解);
唯一性,原本信息内容一致,那麽哈希值也一致;原数据不同,也不会存在重复的哈希结果。
使用信息摘要技术在数据加密传输时,发送方先对文件内容使用哈希算法进行信息摘要计算,再对摘要内容进行加密,之後将文件内容以及摘要内容(已加密)发送出去。

接收方收到数据後,先解密得到摘要内容,再依据相同的哈希算法对文件内容进行信息摘要计算,最後匹配接收到的哈希值与计算得到的哈希值是否一致,如果一致那就说明传输过程是安全的。

这样也就避免了对整体原数据加解密的计算过程,从而提高了验证效率。

签名证书

不对称加密中的公钥是公开的,谁都可以得到,这样也就存在了不安全性。比如主动攻击者C冒充数据发送者A,将自己伪装後的公钥分发给数据接收者B,从而达到监听A、B之间通信的目的,又或者是对A、B之间的通信数据进行注入攻击。

那为了保证获取公钥的安全性,这里引入CA认证(Certificate Authority)。CA是证明公钥合法性的权威机构(Apple就属於CA认证机构),它为每个使用公开密钥的用户发放一个数字证书,数字证书的作用是证明证书中列出的用户合法拥有证书中列出的公开密钥。用户使用CA的公钥对数字证书上的签名进行验证,如果验证通过,也就认为证书内包含的公钥是有效的。

CA认证确保了用户公钥使用过程中的安全性,iOS打包需要向苹果开发者中心上传.certSigningRequest文件,然後配置得到各种.cer证书,这些流程中便包括了开发者向Apple CA认证中心注册公钥的过程。

笔记:
CA认证发布了一份数字证书,可以保证获取公钥的安全性

iOS签名

概念要点

.certSigningRequest文件。从Mac的钥匙串访问中生成.certSigningRequest文件,这个过程会从Mac终端生成一对钥匙对,私钥存储在Mac中,公钥则包含在.certSigningRequest中。再将.certSigningRequest文件上传到Apple後台即苹果开发者中心,则可以对应生成开发证书或者发布证书(.cer文件)。

.cer文件:Apple後台使用Apple私钥对Mac公钥进行签名後生成的证书。
.p12文件:Mac本地生成的钥匙对私钥。由於私钥是本地私有的,但你可以使用.p12将私钥导出给其他团队成员使用。
Identifiers。Identifiers是iOS设备安装应用时用来识别不同App的唯一标识,点击创建App IDs,同时勾选app所包含的权限:APNs、HealthKit、iCloud等。
entitlements。App使用到的各种权限(APNs、HealthKit、iCloud等),也是需要Apple验证通过後才能生效的,Apple将这些权限开关统一称为Entitlements。当第一次在Xcode中勾选权限时,项目中会自动生成一个.entitlements後缀的文件,里面记录了App所拥有的权限。
Profiles。.cer文件只是声明了证书的类型,比如Apple Development、Apple Distribution、APNs推送等等,而至於使用什麽证书打包、AppID是什麽、打包的App包含了哪些功能、可以在哪些设备上安装,则是通过Provisioning Profile描述文件(.mobileprovision後缀)来说明的,苹果後台将所有这些信息组合後再使用Apple私钥进行签名,最後生成Provisioning Profile描述文件:

APPStore签名

发布App至AppStore之前需要经过苹果後台审核,审核通过苹果後台会用Apple私钥对App数据进行加密签名生成ipa包;用户从AppStore下载App後,使用设备内置的Apple公钥解密验证,验证通过安装成功。由於AppStore分发的过程中上传审核、下载安装的整个过程都处在苹果的生态链内,所以只需要一次验证就能保证安全性。

其他签名

从AppStore下载安装App只需要一次数字签名就足以保证安全性,但除了这种途径苹果还有其他的安装方式:

开发中连接设备到Xcode进行调试安装
AD-Hoc内部测试安装,需要先获取设备UDID并注册,并且有最多100台设备的限制
In-House企业内部分发,安装设备数量无限制,但安装後需主动在设置中选择信任证书
那这些安装App的过程中苹果又是怎样保证流程安全性的呢?答案就是双重签名机制,苹果使用前面讲到的Mac本地钥匙对以及Apple後台钥匙对进行多次数字签名,从而保证整体流程的可控。

Mac钥匙串访问在本地生成一对公私钥钥匙对,下面默认为公钥L、私钥L(L:Local)。
Apple已有一对公私钥钥匙对,私钥A在Apple後台,公钥A内置到每一台iOS设备终端(A:Apple)。
上传公钥L至Apple後台,使用私钥A对公钥L进行数字签名生成签名证书.cer,同时使用私钥L对额外信息(使用什麽证书打包、AppID、打包的App包含了哪些功能、可以在哪些设备上安装)进行签名生成描述文件Provisioning Profile,之後将.cer和Provisioning Profile下载安装到Mac机器上。
编译打包app,选择签名证书.cer,打包指令会自动找到该证书对应的私钥L(能匹配是因为钥匙对是成对出现的,前提是本地必须已经存在L私钥,也就是p12的安装),然後使用私钥L对app进行签名。
这些签名数据包含两部分:Mach-O可执行文件会把签名直接写入这个文件中,其他资源文件则会保存在_CodeSignature目录下。你可以将打包生成的.ipa文件另存为.zip,解压後对Payload文件夹中的.app文件右键、显示包内容,就可以看到签名数据。
另外签名过程中对於App内包含的动态库以及插件(Plugins、Watch、Frameworks文件夹),每一个都会单独进行一次签名,并生成各自的Mach-O可执行文件和_CodeSignature。
签名数据指代码内容、App包含的所有资源文件,只要其中有任何改动,都必须重新签名才有效。

打包的过程中会将描述文件Provisioning Profile命名为embedded.mobileprovision放入到打包app中。
安装/启动,iOS设备使用内置的公钥A验证embedded.mobileprovision是否有效(设备是否在允许安装列表内),同时再次验证里面包含的.cer证书签名是否有效(证书过期与否)并取出公钥L。
embedded.mobileprovision验证通过,就使用公钥L解密验证app签名信息:AppID是否对应、权限开关是否跟app里的entitlements一致等等。
所有验证通过,安装/启动完成。

以上流程便是开发调试、AD-Hoc、In-House等方式打包安装App的过程,区别只在於第⑤步中设备IDs的匹配规则不一致。开发调试只安装当前联调的设备;AD-Hoc允许安装到已在开发者账号下注册过的设备,且每年最多允许100台;In-House无设备数量限制,常用於企业内部App的分发。

ipa 重包签名

ipa包重签名主要针对的是非App Store的安装包,App Store分发最终是上传ipa文件到苹果後台审核,通过後使用Apple私钥加密,然後才能发布安装,不存在重签入侵的可能。而开发调试、AD-Hoc、In-House等分发途径生成的ipa包不存在苹果後台验证的步骤,这也就意味着你可以对任意的.app、 .ipa文件进行重签名。

回顾前面讲到的签名流程,真正对ipa包进行签名的关键步骤(④⑤)是在Mac本地进行的,签名过程中需要满足三个条件:App即软件代码编译生成的产物、p12证书以及Provisioning Profile配置文件。其中App的内容是动态变动的,Apple不会去验证它,实际上也无需验证,因为在开发调试过程中,所开发的App肯定是不停的迭代变化的,如果需要上线App Store那Apple只需在审核阶段对App内容进行把关验证即可,而其他分发渠道它则管不了。p12以及Provisioning Profile则是下载後主动安装的,大部分情况下都是由管理员创建下载好之後,导出分发给团队成员。


<<:  Day [3] — this:建构物件 — JS之浸猪笼系列

>>:  手机审验与资安认证

Day39. 建造者模式

本文同步更新於blog Builder Pattern 将复杂对象的构建与其表示分离。 建造者模式...

D21: 工程师太师了: 第11话

工程师太师了: 第11话 杂记: 前阵子跟朋友讨论到绿色金刚战士。 小时候在看金刚战士的时候, 有个...

[13th][Day18] try nginx

使用 docker build 并测试一个 web server 使用 docker 测试静态网站 ...

Laravel 实战经验分享 - Day29 剩下最後的两篇,该讲些什麽呢?

到了倒数第二天,一直在想自己该写什麽,在参加这个比赛之前,自己常埋首在自以为是的开发中,无论遇到什麽...

DAY 4- 对称式、非对称式加密概要

你的心脏不是对称的,就跟你的脸一样。 Alice and Bob 首先要隆重介绍,密码学永远的男主角...