今天起正式进入鸿蒙安全模块的总分析!
首先我们需要梳理一下藏在代码间琐碎的知识点,了解了这些之后我们能够更好的从全局的眼光来审视整个鸿蒙的安全模块
1. Parcel类的作用
首先我们需要解决服务器和客户端传输的数据用什么包装起来呢?——答案就是这个Parcel类。
在进程进行通讯的时候,发送方可以通过Parcel提供的写入方法将要发送的数据以特定格式写入Parcel对象中,接收方再通过封装号的读取方法读取特定结构的数据
在安全模块中使用了继承该类的MessageParcel
2. KDF是什么?
KeyDerivationFunction——也就是密钥派生函数
在安全模块中我们常见的派生模式:masterKey---->deriveKey
mainKey---->deriveKey
使用的算法依然是椭圆曲线算法
需要Spec封装参数(比如salt)
作用:增强密钥的安全性
3. 数据切分
在BigData时代,大数据已经非常常见,当我们将要将一个较大的文件进行加密传输时,势必会遇到无法一次性读取完或者加密完的文件这时候就需要有DataSlice了
根据特定的模式我们需要将大块的数据按照一定标准均分——就像切蛋糕的时候我们想要每块都尽量一致一样——这就会导致一个问题——我们定义了一个切分的标准,但是蛋糕的大小不一样,那么势必切到最后的时候,我们无法保证最后的蛋糕大小跟前面的一致,也就是说得到最后一块的小朋友可能会吃亏了
回到数据切分,如何解决这个问题呢?
第一种方法:按照百分比切分,那不就可以保证每块一样大小了?
看起来完美的解决了问题,但是在实际的应用中,我们使用的切分方法是通过offset进行数据拷贝的方法来进行切割——这样就无法按照百分比切分,再者我们定义好的用于盛放切分好的数据块的数据结构的bufferSize大小也是固定的——换句话说装蛋糕的盘子大小都是一致的,无法根据百分比来进行改变——当然要改变也是可以的,这样需要每次分割数据传入都需要重新进行size大小分配,开销较大,并不划算——就像每次蛋糕来的时候,我们都要定制盘子的大小——我们并不会这么做
第二种方法:我们特殊处理最后切分的数据即可——而鸿蒙的工程师也是这么做的,所以在DataSlice的模块下我们可以看到:
ProcessDataOnce() //如果数据大小能够一次性处理完则调用该函数
SliceData() //否则调用该函数进行数据的切分
//然后就会出现两种处理函数:
SliceDataUpdate() //根据固定的offset进行数据的划分——根据统一盘子的大小划分蛋糕
SliceDataFinal() //当切分到最后的数据块时单独处理——最后一块较小的蛋糕单独处理
4. 密钥存储的序列化
密钥的serialization
所谓序列化就是将一个对象永久存储到介质上
安全模块为什么要进行密钥的serialization呢?
首先我们知道进程一旦结束那么OS就会释放起PCB(进程控制模块)和内存中对应的程序段和数据,那么我们创建的对象就会丢失,下次打开程序,旧的实例化对象就不在了——我们如果保存对象以便下次程序开启还能够使用呢?——答案就是序列化
当然除了存储的功能序列化一般还有以下功能:
- 将对象用于网络环境中传输
- 在进程间传递对象
5. OpenSSL VS Mbedtls
在安全模块中我们看到了两个安全算法实现框架:OpenSSL和Mbedtls,那么在实际的应用场景中我们该如何选择呢?
其实鸿蒙已经给出了答案:lite版本中主要调用了mbedtls框架,standard版本中主要调用了OpenSSL框架,那么我们看看它们两个各自的特点吧!
OpenSSL
OpenSSL主要实现了三类算法:
-
对称算法比如经典的AES,然后实现了四种主要的加密模式:
- 电子密码本模式(ECB):将加密数据分成若干组,每组的大小跟加密密钥长度相同,然后每组使用相同的密钥进行加密
- 加密块链模块(CBC):同样时将明文分成固定长度的块,然后将前面一个加密快输出和下一个要加密的明文进行异或操作,以此类推,由于第一明文加密时没有前面加密的密文,所以需要一个初始化向量,也就是我们在代码中可以看到的参数 IV(init vector)
- 加密反馈模式(CFB):面向字符的应用程序要使用流加密法则可以使用CFB模式
- 输出反馈模式(OFB):与CFB类似
-
摘要算法
- 能够产生特殊输出格式的算法——也就是固定长度的输出,无论输入字串的长度如何。根据一定的运算规则对原始数据进行某种形式的提取得到摘要,原数据变化则摘要必然变化,理论上信息摘要算法不可逆,所以一般用来做数据完整性的验证
- SHA族算法:SHA1输出结果为20字节
- MD族算法:MD5输出为8字节
-
公钥算法——也称非对称算法比如著名的RSA算法,既能够应用于数据加密也能够应用于数字签名
- RSA:基于数论的非对称密码体制,是一种分组密码体制
- DSA:数字签名算法,其安全性基于解离散对数的困难性
- DH:密钥交换算法,其安全性基于有限域上计算离散对数的困难性
- ECC:椭圆曲线密码体制,依据是定义在椭圆曲线点群上的离散对数问题的难解性
OpenSSL的另一特点就是回调函数——一般定义在数据结构中,是一个函数指针。通过回调函数——让openSSL的函数来调用它,即用户调用库中函数,而库中函数又调用用户提供的函数,方便用户对OpenSSL函数的操作
其实现的功能:
- SSL协议的实现
- 对称、非对称和摘要算法的实现
- 大数运算的实现
- 非对称密钥的生成
- 证书请求(PKCS10)编解码
- 数字证书编解码
- 数字证书验证
- PKCS7标准实现
- PKCS12个人证书格式实现等
从代码目录中我们也可以看到在鸿蒙的安全模块中,实现了那些功能:
1. aes
2. curve25519
3. ecc
4. ed25519tox25519
5. hash
6. hmac
7. kdf
Mbedtls
主要面向嵌入式产品,加入加密和SSL/TLS功能
从功能的角度来看,大致分为三个部分:
- SSL/TLS协议实施
- 加密库
- X509证书处理库
为什么会广泛应用于轻量级领域呢?——因为它足够小但是全而且提供了强大的API,即开即用
同样我们可以在安全模块的代码中看到实现了的算法和功能:
1. ed25519
2. aes
3. bn
4. ecc
5. ecdh
6. ecdsa
7. hash
8. hmac
9. kdf
10. rsa
11. x25519
这里两个框架有个共同点——都应用了X509证书标准,为统一进行数据处理提供了方便
注:
SSL:Secure socket layer 由SSL记录协议和握手协议组成
TLS:Transport layer security
TLS与SSL在传输层与应用层之间对网络连接进行加密,保证数据的安全
当然OpenSSL和Mbedtls都实现了它们
文章中有任何疑惑和不对的地方欢迎指正!
下一篇正式开始CS的那些事!