加密算法在 iOS 上的应用
常用加密算法
对称加密算法:AES、DES
加密和解密使用同一密钥。
- 加密速度快
- 密钥管理困难,任意泄密
非对称加密算法:RSA、DSA、ECC
加密和解密使用不同密钥,分为私钥和公钥,私钥加密的数据只有公钥可以解密,反之亦然。私钥一般保存在本地,公钥用于共享。
- 加密速度毕竟慢,适用于数据量小、安全需求高的数据加密
- 不容易泄密
散列算法:MD5、SHA1
又称哈希算法、摘要算法,是将任意长度的数据映射到有限固定长度的域上,是一种单向不可逆算法。
- 签名认证
- 数据的完整性验证
- 不可还原的数据存储,例如密码
信息摘要
将任意长度的数据通过哈希算法得到固定长度的数据,得到的数据就称为原数据的摘要。摘要主要的作用是保证信息完整性。
- 无论数据多长,计算出的摘要长度是固定的
- 摘要看起来是 “随机的”,保证无法逆向,无法从摘要中找到任何与原内容有关系
- 相同内容的摘要是相同的,不同内容的摘要是不同的,极端情况下,不同内容的摘要有可能相同,需要做碰撞处理,越好的算法碰撞的概率越低
数字签名
以前日常生活中,人们通常是用签名、印章之类来证明信息的可靠。随着互联网的普及,越来越多的信息被数据化,那么怎么在网络上确认一份信息的可靠性呢?
加密是个不错的选择,发送者对信息进行加密,接收者对信息进行解密。如果采用对称加密,就会面临密钥管理困难的风险,所以非对称加密是一个不错的选择。
发送者生成一对密钥,私钥自己保存,公钥公开出去。每次发送信息前,用私钥对信息进行加密,接收者用对应公钥进行解密,这样似乎能保证接到信息是可靠的。但是当信息量很大的时候,非对称加密会很慢,而且我们只是想证明信息的来源是可靠的,不一定要去加密整个内容。
这个时候信息摘要显得特别有用,我们只需要计算出原信息的摘要,用私钥对摘要进行加密,这个时候得到的就是数字签名,然后我们把原信息和数字签名一同打包发送出去,接收者收到信息之前,先用公钥解密数字签名,得到摘要,最后用同样的哈希算法计算信息的摘要,对比之前解密出的摘要,就可以得出接收到的信息是否可靠和完整了。
数字签名App 签名
为什么需要 App 签名
iOS 出来之前,各种操作系统安装软件是不需要经过任何认证的,所以软件从哪儿下载都可以安装运行,导致平台对第三方软件难以控制,盗版猖狂,而且会有安全问题。Apple 为了杜绝这种现象,所以采用了 App 签名验证的方式,来保证每个 App 安装到 iOS 上都是经过允许的。
App 签名原理
简单来说,就是在 App 打包的时候加入签名,然后在用户下载启动时校对签名,成功就正常运行,失败则闪退。
一般这种验证都会采用非对称加密算法,Apple 也不例外,Apple 会生成一对密钥:私钥保存在服务器,公钥下发到 iOS 设备。这样开发者将开发好的 App 上传到 Apple 服务器的时候,Apple 服务器会用私钥加密该 App 的摘要从而生成数字签名,用户从 App Store 下载 App 的时候,就会用本地的公钥来校验。
简单流程如下:
app_sign
这样看起很简单的样子,但是这并不能满足所有的场景,试想一下,我们会在哪些场景下有安装 App 的需求?
- 开发 App 时,通过 Xcode 安装到 iPhone
- 发布 App 时,通过上传到 App Store,用户下载安装
- 通过 ad-hoc 的形式分发 App,有数量限制,一般用于平常测试
- 通过 in-house 的形式分发 App,无数量限制,一般用于企业内部大范围测试
除了通过 Apple Store 之外,对于其他几种来说,App 的发布安装是可能不经过 Apple 服务器的,不能都先去 Apple 认证一下吧。既然我们知道校验的方式通常是通过一对密钥来验证的,那我们是否可以在本地生成一对密钥,然后重复上面的步骤呢?这样就可以不用把 App 上传到 Apple 服务器了,但是有两个问题:
- 用户如何拿到我们本地生成的公钥?
- 苹果失去了安装认可的权利?
为了避免上述两个问题,Apple 采用了双重签名的机制。
简单来说:就是由 Apple 生成的一对密钥来验证 App,转变为 Apple 的一对密钥来验证我们本地生成的一对密钥,然后拿我们生成的一对密钥来验证 App。
流程上来说,我们会先把本地生成的 公钥 L 上传到 Apple 服务器,Apple 服务器会使用自己的 私钥 A 对 公钥 L 进行加密签名生成证书提供给我们下载,然后我们用本地的 私钥 L 对 App 进行签名连同下载的证书一起打包成 ipa 文件,提供给用户下载。用户下载的时候,会先用内置的 Apple 公钥 A 去对 ipa 文件里面的证书进行校验,校验成功之后,取出证书里面的 公钥 L ,然后用 公钥 L 去校验 app 的签名,通过后即可安装运行。
我们可以清楚地看出:私钥保存本地用于签名,公钥分发出去用于校验。
上面我们简单描述了双重签名的机制,虽然已经有点复杂了,但是 Apple 对于 App 的权限控制不限于此,Apple 还希望控制:
-
设备列表(允许安装的设备)
-
App ID(App 唯一标识)
-
App 的各种权限(推送、iCloud、后台运行等权限)
这些信息都会同上面我们下载的证书一起打包成 Provisioning Profile,所以流程上就显得更加复杂, 具体流程如下:
app_sign_checkHttps
Https 就是在 http 的基础上添加了一层 SSL / TLS 协议,来保证数据传输的安全性。 而传输的安全性体现在下面几个方面:
- 身份认证
- 内容加密
- 数据完整
这些安全的保证本质上也是通过加密算法来实现的,核心来讲:
通过非对称加密来共享对称加密的密钥,然后通过对称加密来进行通信。
整体流程:
https_flow有关证书 & 密钥流程:
https_cer