在设计安全协议或其他使用加解密算法的场景中,经常会用到AES算法。关于在什么样的场景下使用AES可能不是一个值得深入讨论的问题,但是在如何选择加密模式的问题上,笔者认为需要反复思量。
知所先后,则近道矣!
想要区分不同加密模式的适用场景,首先需要对加密模式的原理有一定的了解。而要想了解加密模式,最合适的切入点便是最原始、最简单的ECB模式。
(图片来自维基百科)
ECB模式全程电子密码本模式,其原理如上图所示。使用ECB模式,首先需要将明文分组,每个分组长度与密钥Key的长度相同,然后每个分组使用相同的密钥进行AES加密。在了解了ECB模式的基本原理之后,我们至少应该提出如下两个问题:
1)明文为什么要分组?
2)何为加密模式?
之所以要对明文进行分组,是因为AES只能加密固定长度的数据,为16个字节,128个比特位。所以我们对明文进行分组,就是将明文数据分割成固定的长度,以满足AES对输入数据的要求。这也引出了我们需要思考的第三个问题:
3)最后一个分组不足16个字节的时候怎么办?
答案是填充,将最后一个分组填充为16个字节长度,关于填充的方式,笔者打算写一篇专题进行讨论,但本文不打算就此展开。(实际上,当最后一个分组长度刚好为16字节时,也会进行填充,即增加一个分组的填充)
在回答完第一个问题和第三个问题之后,我们自然可以推导出第二个问题的答案——加密模式就是在进行加解密计算的过程中,对明文和相关信息进行处理的方式。
现在我们对分组加密模式有了初步的认识,但是这还远远不够,因为分组加密模式多达十几二十种,我们仅仅了解了最原始的ECB模式。话说至此,问题又来了:
4)为什么需要这么多的加密模式?ECB不够香吗?
从前,车马很慢,书信很远,一生只够爱一人。如今,高铁飞快,微信咫尺,一天能约几个妹。车马当然不香了,所有落后了的技术,都将被新的技术以效率、安全和方便的名义取而代之。
ECB被取而代之的重要名目就是不够安全,因为每个分组的加密方式和Key完全相同,在明文相同的情况下,密文将会完全一样,这便是攻击者手里的刀,防御者眼里的沙子,当然需要改进,而CBC就是ECB的改进版本。
(图片来自维基百科)
CBC全称密文分组链接模式,在CBC模式中,明文分组不会直接进行加密,而是经过一次异或之后再进入加密流程。第一个分组的明文与初始向量(IV)进行异或,然后使用AES加密,加密的结果与下一个明文分组异或,如此向下进行链式传导。因为在算法中引入了IV,相同的明文不再会得到相同的密文,安全性得到了很大的提升,CBC模式也因此成为最常用的分组加密模式。
甘瓜苦蒂,天下物无全美!
CBC也不是万能膏药,哪里痛都能贴。比如如下几个痛点便是CBC也无法解决的:
看来,CBC不适用的场景还是蛮多的。针对第一个问题,我们可以使用CFB模式:
(图片来自维基百科)
CBC与ECB模式一脉相承,它们都需要将明文分组成16字节的数据块,然后进行填充,即密文长度始终大于明文。为解决这个问题,CFB模式弃用了直接加密明文的方式,转而将加密作用在IV和Key上,再将结果与明文进行异或,所以这个时候明文不必再满足16字节的要求,因为异或运算的输入可以是任意长度,这就引出同时回答了本文关心的第五个问题:
5)CFB模式是如何将块密码转换成流密码的?
因为明文分组可以是任意长度,所以我们可以将明文分组长度设为1个字节,让加解密过程看起来像是流式运算。而最最重要的,此时明文不再需要填充了,密文长度完全与明文长度一致。
地形有通者、有挂者、有支者、有隘者、有险者、有远者。
AES的运用场景之多决定了加密模式不会仅限于如上三种,当我们使用多处理器实现带硬件加速功能的SE芯片时,便会想到CTR模式,即计数器模式。
(图片来自维基百科)
计数器模式通过递增一个加密计数器以产生连续的密钥流。其中,计数器即可实现为递增的函数,也可实现为随机函数。由于加密和解密过程中,计数器序列可以预生成,因此均可以进行并行处理,特别适合运用于多处理器的硬件上。CTR的另一个优点是密文中的错误位不会传播,解密时仅影响对应的明文位。
如果需要进一步保证密文的完整性,单纯只是用加密就不能解决问题了,而GCM模式就是用来满足这种需求的:
GCM可以理解为在CTR模式的基础上增加了一个GMAC算法,因此在生成的密文后将会附加一个Auth Tag,用来保证传输过程中的完整性。
到此为止我们一共介绍了五种常用的加密模式,最后我们将介绍的几乎是一个专用的加密模式——XTS,XTS基本专为存储加密设计,在磁盘加密的实现中运用广泛,比如linux上赫赫有名的dm-crypt机制,便是使用XTS实现。
关于XTS的原理我们将不再深入探讨,介绍它是因为加密磁盘的应用场景十分普遍,我们需要了解,但是却很少存在直接使用的场景。
道阻且长,行则降至。
关于原理的介绍且告一段落,笔者结合自己实际运用的经验和业内人士的分享,整理了一份最常用加密模式的对照表:
如上表格高度概括了ECB、CBC、CFB、CTR、XTS和GCM六种主流加密模式的原理、优缺点和应用范围,作为原理的总结。
相信绝大多数读者学习加解密算法的目的都是为了最终能够运用,也只有在实际运用中才能够真正领悟每种加密模式的特点,对其适用场景有更加深刻的理解。为了帮助大家进行选择,笔者作了一张加密模式选择的参考图:
该选择方案仅供参考,至于如何选择最佳的加密模式,还需要根据具体的场景和要求进一步判断。
纸上得来终觉浅,绝知此事要躬行