与流密码基于随机种子可以派生出任意长度的伪随机数密钥流用于对明文信息进行异或加密的方式不同,分组密码算法本身通常只能处理固定长度的消息分组。例如AES,SM4等分组密码算法的分组长度均为128比特,这意味着算法本身每次最多只能处理16个字节。网络流量加密和文件加密等场景,均要求处理更长的消息,利用分组密码算法完成信息加密时,必须借助分组密码算法的工作模式,常见的工作模式有ECB、 CBC、CTR、 CFB、 OFB、GCM、CCM、FPE等:
- ECB:Electronic Codebook Mode,也即电子密码本模式
- CBC:Cipher Block Chaining Mode,也即密文分组链接模式
- CTR:Counter Mode,也即计数器模式
- CFB:Cipher Feedback Mode,也即密文反馈模式
- OFB:Output Feedback Mode,也即输出反馈模式
- GCM:Galois/Counter Mode,也即伽罗瓦计数器模式
- CCM:Counter with CBC-MAC,也即带CBC-MAC的技术器模式
- FPE:Format-Preserving Encryption Mode,也即保留格式加密模式
本文讨论在面对具体的工程实现任务时如何从中选用合适的工作模式,而来自笔者的一句话结论是,默认采用GCM。
密码工程的最佳实践通常要求在保证机密性的同时也要保证密文的完整性,也即要同时满足密码学的基本目标CIA中的机密性(Confidentiality)和完整性(Integrity)。网络流量和文件的机密性保护基于性能的考虑通常采用流密码或者分组密码算法,而完整性保护方面,则通常依赖于消息认证码(Mac Authentication Code,MAC)。机密性方面采用分组密码算法时,要选用合适的工作模式,用于完整性保护的MAC计算则可以基于哈希函数构建(如HMAC),也可以基于分组密码算法(如CBC-MAC)构建或者设计专门的MAC算法(如GMAC)。
消息加密与MAC码计算的组合方式有以下三种,上图中也给出了三种组合方式的图示.
1.加密并认证(Encrypt-and-MAC,EaM): 对明文“P”的加密得到密文“C”以及并对明文进行MAC码计算得到“T”.
2.先认证后加密(MAC-then-Encrypt,MtE): 对明文“P”计算MAC码“T”,随后将明文“P”和MAC一起加密得到密文“C”
3.先加密后认证(Encrypte-then-MAC,EtM): 对明文“P”加密得到密文“C”,对密文”C”执行MAC码计算得到“T”
其中至少在理论层面,EaM当属安全性最弱的组合方式,因为MAC码是直接根据明文计算得到的,有可能泄露明文的部分信息。但是根据选用的MAC算法的属性,也可以酌情采用,SSH协议中网络流量加密选用了EaM的组合方式。MtE中的MAC码虽然也是直接根据明文计算得到的,但是MAC又被进一步加密保护,所以不会因为MAC码泄露明文的任何信息,从这一个角度看,MtE要比EaM安全性更好一些。采用MtE组合模式进行解密时,为了判断消息完整性,需要将明文和MAC全部解密出来才能进一步判断,这样的过程也成为不推荐使用MtE组合模式的原因。广泛部署的TLS协议曾经采用了MtE的组合模式,但是在最新的TLS1.3协议中,MtE模式被弃用。EtM组合模式对应的解密过程,不需要整个解密密文“C”就可以根据MAC码“T”判断收到的消息是否有被篡改过。该过程带来的一个好处是,攻击者无法迫使消息接收方解密已经被篡改过的消息,也因此就安全性而言,EtM比EaM和MtE更好。安全通信协议IPSec中采用了EtM的组合模式。如果EtM是最安全的组合模式,为什么SSH和TLS协议中没有采用EtM? 因为在这些协议创建时,EaM和MtE的理论上的弱点看起来似乎并不会影响安全性。
前面提到TLS1.3中弃用了MtE的方式,但并没有提及TLS 1.3中采用的新的方式。根据前面的分析,合情推理应该是用EtM代替MtE。该合情推理基本正确,但是由于消息加密与MAC码计算两种需求基本上总是需要同时满足,并且组合在组合过程中总会出现各种误用导致安全事件频发,迫使密码学界给出了更好的解决方案: 可认证加密算法(Authenticated Cipher)。前述的组合方式要求首先选择分组密码的工作模式,然后选择具体的MAC码算法,最后选择组合模式如EtM完成消息计算。这一过程中很容易出现各种安全性问题,如分组密码算法和MAC算法不恰当地使用相同的密钥。相比之下,可认证算法直接在一个算法过程中完成了消息加密和MAC计算两种过程,使用者无需再操心前述过程中各种细节。从这一角度出发,可以将前述的7种工作模式进行分成两类,一类仅执行消息加密操作,另一类则属于可认证加密算法的范畴。前一类包括ECB,CBC,CTR,CFT,OFB以及FPE,后一类包括GCM和CCM。TLS1.3中启用MtE之后,在用分组密码算法进行流量加密时选用的就是GCM和CCM模式。GCM和CCM模式可以看作是遵循EtM方式在一个算法内部同时完成消息加密和MAC码计算的可认证加密模式,其中GCM模式内部组合了CTR模式和GMAC算法,而CCM模式内部则组合了CBC模式和CBC-MAC算法。
因此在使用前一类时,除了工作模式本身还需要选用合适的MAC算法,商密领域推荐使用基于SM3的MAC算法: HMAC-SM3,非商密领域也可以采用基于SHA256的MAC算法: HMAC-SHA256。不推荐基于分组密码算法的MAC算法,如基于CBC模式构建出来的CBC-MAC或者CMAC等方案,基于分组密码算法的MAC算法难以安全实现并且在使用中容易出错。另外也可以使用专门构建的MAC算法,如GCM中使用的GMAC算法,或者配合Chacha20流密码算法的Poly1305算法。商密合规领域,根据目前的商密标准进展,GMAC应当是可以使用的。也因此,如果工程允许,优先推荐使用SM4-GCM模式。GCM模式是遵循EtM模式在算法内部组合了CTR模式和GMAC算法的可认证加密算法,下图中给出了GCM加密和解密过程的示意图。
当无法选用GCM模式时,在非商密领域可以考虑使用CCM模式,例如AES-CCM。这是因为目前多数平台上都支持AES算法的硬件指令,使得AES-CCM具有较高的性能。但是在商密领域,由于多数平台目前并不支持SM4的硬件加速,所以SM4-CCM的运行效率会比较差。因为当前的SM4算法的软件实现优化主要是通过SIMD指令并行处理多个分组来达到速度提升的,而这一优化策略无法应用于CBC模式当中,目前即使是优化过的SM4软件实现,在大多数计算环境中CBC模式下能够处理的数据量不超过100MB,而CTR模式等可以兼容分组并行处理的工作模式,则甚至可以达到600MB/s以上的处理速度(单线程下),因此SM4-CCM模式中,CBC-MAC的计算会成为整个算法甚至整个业务场景的性能瓶颈。考虑到优化过后的SM3算法的软件实现由于SM4-CBC,因此在商密领域,当不具备采用SM4-GCM模式的条件时,推荐优先考虑基于EtM的组合模式,组合SM4的工作模式和HMAC-SM3。
接下来讨论,如何在ECB、CBC、CTR、CFB、OFB以及FPE选用合适的工作模式。ECB模式由于无法隐藏消息的模式,天然具有不安全的属性,因此通常不应当采纳ECB模式。FPE保留格式加密模式,仅适用于对密文格式有要求的场景,例如身份证或者手机号加密之后的密文仍然保持相应的数字格式。如果业务系统的数据存储方面有这种限制,则使用FPE即可,注意使用FPE时要认真研读NIST的FPE标准,以确保使用场景符合FPE的安全性要求。在同样数据加密场景下,仅需要从CBC、CTR、CFB、OFB这4个模式中进行选择。
CBC模式要求待处理的消息的长度都是分组长度的整数倍,对于不满足这一要求的消息,首先需要通过padding补齐。CBC模式的加解密图示如下。可以看到在加密过程中,下一个分组的加密过程依赖于上一个分组的加密结果,这种链式结果导致通过使用SIMD技术并行处理多个分组的以提升SM4算法软件执行效率的策略无法应用于CBC加密过程中,也因此导致SM4-CBC加密过程的执行效率难以提升。值得注意的是CBC的解密过程可以通过多个分组的并行处理提升执行效率。
CFB模式与CBC模式类似,加密过程中也会产生链式的相互依赖,因此同样难以用并行手段提速,而解密时则可以使用并行手段提速。CFB模式的好处是,不要求明文一定是分组长度的整数倍,也不需要对消息进行padding补齐。
OFB模式通过对Nonce的循环加密产生伪随机密钥流,然后通过异或操作对消息进行加解密,对消息长度没有要求,也因此无需padding补齐。但是这种方式在加密和解密过程中都引入了链式的前后依赖,导致无法使用并行手段进行加速。
CTR模式与OFB模式类似,都是通过产生伪随机密钥流,然后通过异或操作对消息进行加解密。但是与OFB不同的是,CTR模式是对递增的计数器进行加密产生相应的密钥流,不需要padding,也没有在加解密过程中引入链式的前后依赖,因此CTR模式的加解密均可以使用并行手段进行提速。
除了上面的讨论之外,CBC模式的加解密很难做到常量时间实现,这一点已经在OpenSSL中得到证实,而由于CBC模式引发的TLS的安全问题,也备受瞩目。另外CBC模式的加密过程无法通过并行手段进行加速,对业务系统性能方面也不有好。 CFB,OFB以及CTR都遵循一个思路,将分组密码转换成类似于流密码的工作模式,然而对比之下,CFB和OFB都无法通过并行加速,相比CTR模式也没有提供额外的安全性。综上,笔者推荐在CBC,CFB,OFB以及CTR模式中,优先选用CTR模式。
综上,分组密码的工作模式选用方面,非商密场景,按照下列顺序选用工作模式:
商密场景,按照下面的顺序选用工作模式:
AES-GCM --> AES-CCM --> EtM组合模式的AES-CTR + HMAC-SHA256
商密场景,按照下⾯的顺序选⽤⼯作模式:
SM4-GCM --> EtM组合模式的SM4-CTR + HMAC-SM3