作为一个iOSer,不可避免的会接触到Certificates和profiles,这两个一般也是成对使用的(注意是也有特例,APNs Certificate是不需要用profiles的),常见的使用场景有真机调试的时候使用dev Certificate和dev profile,打app store包的用dis Certificate和dis profiles,其实这两者也是有一定关系的,profiles是由Certification和Identifier构成成的,换句话说就是申请profiles的时候要有Certification和Identifier,dev profile还需要注册过的设备ID(UUID),那么这几个东西到底是啥呢?到底有什么用呢。。
其实这两个文件,或者说这一套签名验证系统是苹果专门设计出来确保只有经过苹果认可或者说是审核过的软件才能安装到苹果手机上,可以保证iOS系统的软件生态圈可控、干净并且可以杜绝盗版软件泛滥,这也是iOS系统受欢迎的一个点,那么这套系统的原理又是啥呢?
说原理之前需要先简单普及(注意是简单普及!简单普及!简单普及!)几个知识点,这些知识点是苹果签名验证系统的基础。
一.加密算法
加密算法分为对称加密算法
和非对称加密算法
,
- 对称加密算法是指加密和解密都是用同一个密钥,所以也称之为单密钥加密,特征有:
- 加密和解密都使用同一个密钥
- 加密速度快,适合较大数据的加密
- 安全性较低,管理较麻烦
常见的对称加密算法有DES
、3DES
、AES
、Blowfish
等
- 非对称加密算法是指加密和解密用的是不同的密钥,也称之为公钥加密,密钥分为公钥和私钥两种,特点有:
- 存在公钥和私钥的密钥对,公钥加密私钥解密或者私钥加密公钥解密
- 加密速度慢,不适合大数据加密,一般用于身份认证或加密对称加密的密钥
- 安全性较高
常见的非对称加密算法有RSA
、DSA
、ECC
等
二.散列算法(摘要算法)
散列算法又称哈希算法,是一种不可逆的单向加密算法,严格上来说不算一种加密算法,说是摘要算法更准确,针对不同长度的内容,生产固定长度的产出,一般用于校验内容的完整性,保证内容不被篡改,特征:
- 不可逆性
- 压缩性:针对任意长度的数据,产出都是固定的
- 抗修改性:原数据的任意改动都会导致产出有特别大的变化
- 抗碰撞性:找出两个产出一直哈希值的数据是非常难的,就像人的指纹一样,找出两个有一样指纹的人很难
常见的散列算法有MD5
、SHA1
、HMAC
等
三.签名和验签
我了解的签名过程和验签过程都是依赖散列算法的,不知道有没有其他类型的签名和验签。
-
签名过程是针对散列算法得出的摘要做加密,摘要长度固定而且短小,一般是使用非对称加密,加密速度快。具体可以根据实际情况而定。
-
验签过程是比较自己用散列算法得出的摘要和解密签名得到的摘要做比较,如果一致验签通过。
苹果签名系统中使用到的知识点简单普及完了,下面就到苹果签名系统的原理了,说到这个系统就不得不提一张网上找的图了,很经典的诠释了原理(这张图做的很漂亮,本人自愧不如,好想知道用的什么工具做的图)。
下面针对途中步骤做出分析,并和申请Certificates, Identifiers & Profiles的步骤对应上
- 这里的一对公钥L和私钥L对(L=Local)是在Mac OS系统中利用钥匙串访问生成的,生成的
.certSigningRequest
文件就是公钥L。
- 苹果公司自己也有一对公钥A和私钥A(A=Apple),公钥A存储在iOS设备中。
- 我们在申请Certificates也就是
.cer
文件的时候,需要把公钥L上传到苹果开发者网站,其实就是利用私钥A对公钥L做了一次签名,查看.cer
文件你会发现有签名和摘要等信息,可以看出有两个不同算法得出的摘要,不知道在签名里面加密的是哪个摘要或者可能两种都有。.cer
文件还包含了很多其他信息像证书签发公司等信息,这些信息也可以用于验签。
- 把
.cer
文件、设备IDs、AppID和Entitlements等数据使用私钥A再做一次签名,这就是申请描述文件Provisioning Profile
那一步了。这也是为什么证书失效或者被修改之后描述文件也会失效的原因。 - 使用Xcode打包的时会利用私钥L对打的包做一次签名,最终的安装包中包含app安装文件、安装文件的签名和描述文件等信息。
- 接下来就是安装App时的验签过程
6.1 先使用公钥A针对描述文件做验签,确保.cer
文件、设备IDs、AppID和Entitlements等数据没有被篡改过,然后对比APP ID和设备ID,对比失败就直接导致App安装不成功。
6.2 然后使用公钥A针对证书.cer
文件做验签,确保公钥L没有被篡改。
6.3 最好使用公钥L针对app安装文件做验签,确保App安装文件没有篡改。
到此签名验签的过程都完成了,最后的验签没问题的话App就可以安装到手机里面了。当然了这也只是苹果签名系统中一个比较全的场景,还有一些其他场景,例如从App Store中下载的App在安装的时候就没这么复杂,最直接的证据就是App Store中App安装包里面没有embedded.mobileprovision
文件,我猜想应该是App Store中App是已经经过审核了,属于可控的所以就不用做这么复杂的校验。
常见问题:
Q:上架审核的appstore包为什么没办法直接安装,和ad_hoc包有啥不一样?
A:上架审核的appstore包使用的描述文件里面是没有设备ID的,所以安装的时候对比设备ID不通过导致安装失败,而ad_hoc包用的描述文件里面是有设备ID的所以正常安装。
Q:.cer
文件安装后,在钥匙串访问里面导出的.p12
文件又是啥?
A:待考究,猜想应该包含了私钥L和.cer
文件。
Q:Entitlements
的作用是什么?体现在什么地方?
A:具体待考究,大概知道Entitlements
用于体现权限的。
关于iOS Certificates, Identifiers & Profiles 原理解析参考文章
1.iOS企业重签名问题及经验