欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS 证书签名知识点介绍

程序员文章站 2022-04-15 19:45:32
之前面试了很多 ios 开发工程师,项目做的还可以,但是当聊起证书和签名这些的时候,没有几个能说的头头是道。作为一个ios 开发工程师,每当你配置各种证书忙的焦头烂额的时候,有没有想过这 tm 到底...

之前面试了很多 ios 开发工程师,项目做的还可以,但是当聊起证书和签名这些的时候,没有几个能说的头头是道。作为一个ios 开发工程师,每当你配置各种证书忙的焦头烂额的时候,有没有想过这 tm 到底是为了啥?本文就告诉你这tm 的是为了啥!

why ?

玩儿苹果的都知道,通常情况下我们喜欢的 app 是从 appstore 上下载的。但是,苹果希望在 ios 平台对第三方 app 有绝对的控制权,一定要保证每一个安装到 ios 上的 app 都是经过苹果官方允许的,怎样保证呢?就是通过签名机制。

加密">非对称加密

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

简单说一下常用的非对称加密算法 rsa 的数学原理,理解简单的数学原理,就可以理解非对称加密是怎么做到的,为什么会是安全的:

选两个质数p和q,相乘得出一个大整数n,例如 p=61,q=53,n=pq=3233

选 1-n 间的随便一个质数e,例如 e = 17

经过一系列数学公式,算出一个数字d,满足:

a. 通过n和e这两个数据一组数据进行数学运算后,可以通过 n 和 d 去反解运算,反过来也可以。

b. 如果只知道n和e,要推导出d,需要知道p和q,也就是要需要把 n 因数分解。

上述的(n,e)这两个数据在一起就是公钥,(n,d)这两个数据就是私钥,满足用私钥加密,公钥解密,或反过来公钥加密,私钥解密,也满足在只暴露公钥(只知道n和 e)的情况下,要推导出私钥(n,d),需要把大整数n因数分解。目前因数分解只能靠暴力穷举,而n数字越大,越难以用穷举计算出因数p和q,也就越安全,当n大到二进制 1024 位或 2048 位时,以目前技术要破解几乎不可能,所以非常安全。

数字签名

很多文章都与现实生活中的证件盖章做比喻,我认为不太恰当,容易误导初学者。数据的世界里,不可能像现实生活中那样简单。现在咱们一步一步分析什么是数字签名。
时间:某年某月某日
地点:地球任意有计算机的地方
人物:隔壁老王、东北老铁
事件:隔壁老王要给东北老铁发一个文件(o)。
经过:隔壁老王有一台电脑,这台电脑能够生成一对公钥和私钥。隔壁老王首先将文件(o)用摘要算法进行摘要,生成文件摘要(m)。然后用私钥对文件摘要(m)进行加密,也就是数字签名(以后统称为“签名”),生成一个签名文件(s)。然后隔壁老王将文件(o)、签名文件(s)、公钥一起发给了东北老铁。

东北老铁拿到这三样东西后,首先用公钥对签名文件(s)进行解密,生成文件摘要(m),然后用同样的摘要算法对文件(o)摘要,生成文件摘要(m)。东北老铁只需要对比 m 和 m 是否一样,就知道这个文件有没有被其他人改动。这就是数字加密的用途。
iOS 证书签名知识点介绍

上图的理解:
1.首先用一种算法,算出原始数据的摘要。需满足 a.若原始数据有任何变化,计算出来的摘要值都会变化。 b.摘要要够短。这里最常用的算法是md5。

2.生成一份非对称加密的公钥和私钥,私钥我自己拿着,公钥公布出去。

3.对一份数据,算出摘要后,用私钥加密这个摘要,得到一份加密后的数据,称为原始数据的签名。把它跟原始数据一起发送给用户。

4.用户收到数据和签名后,用公钥解密得到摘要。同时用户用同样的算法计算原始数据的摘要,对比这里计算出来的摘要和用公钥解密签名得到的摘要是否相等,若相等则表示这份数据中途没有被篡改过,因为如果篡改过,摘要会变化。

从 appstore 下载 app

iOS 证书签名知识点介绍

上图说明的就是,苹果官方生成一对公私钥,在 ios 里内置一个公钥,私钥由苹果后台保存,我们传 app 上 appstore 时,苹果后台用私钥对 app 数据进行签名,ios 下载这个 app 后,用公钥验证这个签名,若签名正确,这个 app 肯定是由苹果后台认证的,并且没有被修改过,也就达到了苹果的需求:保证安装的每一个 app 都是经过苹果官方允许的。

从其他途径安装 app

事情没有那么简单,实际上因为除了从 appstore 下载,我们还可以有三种方式安装一个 app:

1.开发 app 时可以直接把开发中的应用安装进手机进行调试。

2.in-house 企业内部分发,可以直接安装企业证书签名后的 app。

3.ad-hoc 相当于企业分发的限制版,限制安装设备数量,较少用。

苹果要对用这三种方式安装的 app 进行控制,就有了新的需求,无法像上面这样简单了。

iOS 证书签名知识点介绍

苹果的方案是双层签名,如下:
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

上述流程只解决了上面第一个需求,也就是需要经过苹果允许才可以安装,还未解决第二个避免被滥用的问题。怎么解决呢?苹果再加了两个限制,一是限制在苹果后台注册过的设备才可以安装,二是限制签名只能针对某一个具体的 app。
iOS 证书签名知识点介绍

可以想到把 允许安装的设备 id 列表 和 app对应的 appid 等数据,都在第三步这里跟公钥l一起组成证书,再用苹果私钥 a 对这个证书签名。在最后第 5 步验证时就可以拿到设备 id 列表,判断当前设备是否符合要求。根据数字签名的原理,只要数字签名通过验证,第 5 步这里的设备 ids / appid / 公钥 l 就都是经过苹果认证的,无法被修改,苹果就可以限制可安装的设备和 app,避免滥用。

到这里这个证书已经变得很复杂了,有很多额外信息,实际上除了 设备 id / appid,还有其他信息也需要在这里用苹果签名,像这个 app 里 icloud / push / 后台运行 等权限苹果都想控制,苹果把这些权限开关统一称为 enments,它也需要通过签名去授权。

限制功能,比如推送

iOS 证书签名知识点介绍

因为步骤有小变动,这里我们不辞啰嗦重新再列一遍整个流程:

1.在你的 mac 开发机器生成一对公私钥,这里称为公钥l,私钥l。l:local

2.苹果自己有固定的一对公私钥,跟上面 appstore 例子一样,私钥在苹果后台,公钥在每个 ios 设备上。这里称为公钥a,私钥a。a:apple

3.把公钥 l 传到苹果后台,用苹果后台里的私钥 a 去签名公钥 l。得到一份数据包含了公钥 l 以及其签名,把这份数据称为证书。

4.在苹果后台申请 appid,配置好设备 id 列表和 app 可使用的权限,再加上第③步的证书,组成的数据用私钥 a 签名,把数据和签名一起组成一个 provisioning profile 文件,下载到本地 mac 开发机。

5.在开发时,编译完一个 app 后,用本地的私钥 l 对这个 app 进行签名,同时把第④步得到的 provisioning profile 文件打包进 app 里,文件名为embedded.mobileprovision,把 app 安装到手机上。

6.在安装时,ios 系统取得证书,通过系统内置的公钥 a,去验证embedded.mobileprovision的数字签名是否正确,里面的证书签名也会再验一遍。

7.确保了embedded.mobileprovision里的数据都是苹果授权以后,就可以取出里面的数据,做各种验证,包括用公钥 l 验证app签名,验证设备 id 是否在 id 列表上,appid 是否对应得上,权限开关是否跟 app 里的 enments 对应等。

从证书颁发机构请求证书

钥匙串程序中,从证书颁发机构请求证书的过程,就是在电脑上生成一对公钥和私钥,文件certificatesigningrequest里面保存的就是公钥。

证书

从苹果开发者平台下载到本地的证书,里面的内容就是公钥或私钥,由其他机构对其签名组成的数据包。

描述文件

provisioning profile,包含了 证书 / enments 等数据,并由苹果后台私钥签名的数据包。