iOS 证书签名知识点介绍
之前面试了很多 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 是否一样,就知道这个文件有没有被其他人改动。这就是数字加密的用途。
上图的理解:
1.首先用一种算法,算出原始数据的摘要。需满足 a.若原始数据有任何变化,计算出来的摘要值都会变化。 b.摘要要够短。这里最常用的算法是md5。
2.生成一份非对称加密的公钥和私钥,私钥我自己拿着,公钥公布出去。
3.对一份数据,算出摘要后,用私钥加密这个摘要,得到一份加密后的数据,称为原始数据的签名。把它跟原始数据一起发送给用户。
4.用户收到数据和签名后,用公钥解密得到摘要。同时用户用同样的算法计算原始数据的摘要,对比这里计算出来的摘要和用公钥解密签名得到的摘要是否相等,若相等则表示这份数据中途没有被篡改过,因为如果篡改过,摘要会变化。
从 appstore 下载 app
上图说明的就是,苹果官方生成一对公私钥,在 ios 里内置一个公钥,私钥由苹果后台保存,我们传 app 上 appstore 时,苹果后台用私钥对 app 数据进行签名,ios 下载这个 app 后,用公钥验证这个签名,若签名正确,这个 app 肯定是由苹果后台认证的,并且没有被修改过,也就达到了苹果的需求:保证安装的每一个 app 都是经过苹果官方允许的。
从其他途径安装 app
事情没有那么简单,实际上因为除了从 appstore 下载,我们还可以有三种方式安装一个 app:
1.开发 app 时可以直接把开发中的应用安装进手机进行调试。
2.in-house 企业内部分发,可以直接安装企业证书签名后的 app。
3.ad-hoc 相当于企业分发的限制版,限制安装设备数量,较少用。
苹果要对用这三种方式安装的 app 进行控制,就有了新的需求,无法像上面这样简单了。
苹果的方案是双层签名,如下:
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。
可以想到把 允许安装的设备 id 列表 和 app对应的 appid 等数据,都在第三步这里跟公钥l一起组成证书,再用苹果私钥 a 对这个证书签名。在最后第 5 步验证时就可以拿到设备 id 列表,判断当前设备是否符合要求。根据数字签名的原理,只要数字签名通过验证,第 5 步这里的设备 ids / appid / 公钥 l 就都是经过苹果认证的,无法被修改,苹果就可以限制可安装的设备和 app,避免滥用。
到这里这个证书已经变得很复杂了,有很多额外信息,实际上除了 设备 id / appid,还有其他信息也需要在这里用苹果签名,像这个 app 里 icloud / push / 后台运行 等权限苹果都想控制,苹果把这些权限开关统一称为 enments,它也需要通过签名去授权。
限制功能,比如推送
因为步骤有小变动,这里我们不辞啰嗦重新再列一遍整个流程:
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 等数据,并由苹果后台私钥签名的数据包。
上一篇: 大黄鱼价格多少?听这名字好像会有点贵
下一篇: 镜面蛋糕是什么?会反光吗?它咋来的