一、什么是AES加密?
常见的加密主要分为两类:对称加密和非对称加密,AES加密就是对称加密的一种,即加密和解密使用相同的一把密钥。它的全称是Advanced Encryption Standard(高级加密标准),主要是用来取代DES加密算法,目前已经被全世界广泛采用,各大处理器厂商也在各自的CPU中,集成了专门的AES指令集,从而在硬件层面提升了AES加解密的速度。
1.对称加密相关概念
-
明文P(plainText):未经加密的数据
-
密钥K(key):用来加密明文的密码。在对称加密算法中,加密与解密的密钥是相同的,由双方协商产生,绝不可以泄漏
-
密文C(cipherText): 经过加密的数据
-
加密函数E(encrypt):C = E(K, P),即将明文和密钥作为参数,传入加密函数中,就可以获得密文
-
解密函数D(decrypt):P = D(K, C),即将密文和密钥作为参数,传入解密函数中,就可以获得明文
说到这里,你可能会觉得加解密函数很神奇,他们是如何实现数据转换的呢?一种简单的做法是XOR运算(异或运算),XOR运算的神奇之处是:如果对一个值连续做两次XOR,会返回这个值本身
2.AES加密相关概念 -
分组(或者叫块):AES是一种分组加密技术,分组加密就是把明文分成一组一组的,每组长度相等,每次加密一组数据,直到加密完整个明文。那你可能要问:为何要进行分组呢?比如一个应用程序总共就只能获得3M的内存空间来执行,而需要加密的文件是100M,这个时候就不得不进行文件拆解加密。在AES标准规范中,分组长度只能是128 bits,也就是每个分组为16个bytes
-
密钥长度:AES支持的密钥长度可以是128 bits、192 bits或256 bits。密钥的长度不同,推荐加密轮数也不同,如下表:
-
加密轮数越多,当然安全性越好,但也更耗费时间
-
加密模式:因为分组加密只能加密固定长度的分组,而实际需要加密的明文可能超过分组长度,此时就要对分组密码算法进行迭代,以完成整个明文加密,迭代的方法就是加密模式。它有很多种,常见的工作模式如下图:
-
-
初始向量(IV,Initialization Vector):它的作用和MD5的“加盐”有些类似,目的是防止同样的明文块,始终加密成同样的密文块,以CBC模式为例:
-
在每一个明文块加密前,会让明文块和一个值先做异或操作。IV作为初始化变量,参与第一个明文块的异或,后续的每一个明文块和它前一个明文块所加密出的密文块相异或,从而保证加密出的密文块都不同。
-
填充方式(Padding):由于密钥只能对确定长度的数据块进行处理,而数据的长度通常是可变的,因此需要对最后一块做额外处理,在加密前进行数据填充。常用的模式有PKCS5, PKCS7, NOPADDING
-
附加消息(AAD,Additional Authenticated Data):附加消息不是重要数据,它只是可以包含在协议中的纯数据,需要对其进行完整性保护,但不需要加密。一个很好的例子是加密IP数据包的标头。如果对它进行加密,则不能将其用于路由;如果不保护它的完整性,则攻击者可能会更改消息的长度或源地址,而收件人却不知道
CTR模式(计数器):
在计数器模式下,我们不再对密文进行加密,而是对一个逐次累加的计数器进行加密,用加密后的比特序列与明文分组进行 XOR得到密文。过程如下图:
计数器模式下,每次与明文分组进行XOR的比特序列是不同的,因此,计数器模式解决了ECB模式中,相同的明文会得到相同的密文的问题。CBC,CFB,OFB模式都能解决这个问题,但CTR的另两个优点是:1)支持加解密并行计算,可事先进行加解密准备;2)错误密文中的对应比特只会影响明文中的对应比特等优点。
但CTR仍然不能提供密文消息完整性校验的功能。
有的人可能会想到,如果将密文的hash值随密文一起发送,密文接收者对收到的密文计算hash值,与收到的hash值进行比对,这样是否就能校验消息的完整性呢?
再仔细想想,就能发现这其中的漏洞。当篡改者截获原始的密文消息时,先篡改密文,而后计算篡改后的密文hash, 替换掉原始消息中的密文hash。这样,消息接收者仍然没有办法发现对源密文的篡改。可见,使用单向散列函数计算hash值仍然不能解决消息完整性校验的问题。
MAC ( Message Authentication Code, 消息验证码)
想要校验消息的完整性,必须引入另一个概念:消息验证码。消息验证码是一种与秘钥相关的单项散列函数。
密文的收发双发需要提前共享一个秘钥。密文发送者将密文的MAC值随密文一起发送,密文接收者通过共享秘钥计算收到密文的MAC值,这样就可以对收到的密文做完整性校验。当篡改者篡改密文后,没有共享秘钥,就无法计算出篡改后的密文的MAC值。
如果生成密文的加密模式是CTR,或者是其他有初始IV的加密模式,别忘了将初始的计时器或初始向量的值作为附加消息与密文一起计算MAC。
GMAC ( Galois message authentication code mode, 伽罗瓦消息验证码 )
对应到上图中的消息认证码,GMAC就是利用伽罗华域(Galois Field,GF,有限域)乘法运算来计算消息的MAC值。假设秘钥长度为128bits, 当密文大于128bits时,需要将密文按128bits进行分组。应用流程如下图:
GCM模式:
GCM中的G就是指GMAC,C就是指CTR。
GCM可以提供对消息的加密和完整性校验,另外,它还可以提供附加消息的完整性校验。在实际应用场景中,有些信息是我们不需要保密,但信息的接收者需要确认它的真实性的,例如源IP,源端口,目的IP,IV,等等。因此,我们可以将这一部分作为附加消息加入到MAC值的计算当中。下图的Ek表示用对称秘钥k对输入做AES运算。最后,密文接收者会收到密文、IV(计数器CTR的初始值)、MAC值。
先对块进行顺序编号,然后将该块编号与初始向量(IV)组合,并使用密钥k,对输入做AES加密,然后,将加密的结果与明文进行XOR运算来生成密文。像CTR模式下一样,应该对每次加密使用不同的IV。对于附加消息,会使用密钥H(由密钥K得出),运行GMAC,将结果与密文进行XOR运算,从而生成可用于验证数据完整性的身份验证标签。最后,密文接收者会收到一条完整的消息,包含密文、IV(计数器CTR的初始值)、身份验证标签(MAC值)。
AES-GCM加密后的密文大小总是等于明文大小,因为 AES-GCM 内部使用 CTR 模式进行加密,不需要填充。