TLS/SSL 协议详解 (31)TLS1.1 TLS1.2 在CBC模式下两种不同的加解密方式及优化思考
前言:
TLS 1.0 和 TLS 1.1、TLS 1.2在块加密(CBC)时,组织数据的方式是不同的,RFC上规定了这种不同,但是没有说如何实现。
于是查看了OpenSSL和PolarSSL(现为Mbedtls)2套主流的开源代码,发现2者在实现TLS 1.1块加密时,它们的实现方法“截然不同”,OpenSSL严格按照RFC上所说的方式组织数据,而PolarSSL却用了另一种方法组织数据,然而这两种看似截然相反的操作,无论加密解密,其结果都是正确的,起初很是疑惑。
CBC链式加密:
在块加密的时候,需要一个叫做向量的东西“IV”,“IV”是用来和待加密数据进行异或(XOR)操作的(显然,一个数据data异或(XOR)一次 “IV”,得到data2,data2再次异或一次“IV”,数据就还原了)。
标准的CBC模式见下图。
加密时,将明文数据和IV异或,然后再去加密,输出密文(这一次的密文,当做下一次加密的IV):
图片来自网络。
解密时,将密文数据解密,然后再和IV异或,得到明文:
图片来自网络。
TLS1.0 和 TLS1.1 CBC模式加密的区别
RFC规定,为了应对beast攻击,需要在收个待加密的的密文数据前,填充一个block size大小的随机值。即送入CBC加密的数据为 “random + plaintext”,IV为KDF得到的初始化向量,得到ciphertext后,直接封装record 层发送出去。
OpenSSL就是这么组织数据的。
解密时,使用CBC模式解密得到的明文数据需要去除blocksize大小的随机值。
OpenSSL (RFC)块加密前组织数据方式:(TLS 1.1和TLS 1.2 )
加密:
明文数据前填充随机值,和IV异或,然后和明文一并送入加密,输出密文数据,IV为上一次块加密的结果(见上上图)。
解密:
解密收到的数据,解密后,和IV异或,剔除随机数长度(即一个块长度)的数据,IV是上一次收到的密文。(见上图)
PolarSSL块加密前组织数据方式:(TLS 1.1和TLS 1.2 )
加密:
明文数据前填充随机值,但是,仅仅是数据送入加密,并且IV为这个随机值。(即随机值不参与直接加密)
密文数据(即发送出去的数据),是未加密的随机值 +加密后的明文。
解密:
取当前收到密文数据的前随机数字节(一个块长度)当做当前解密的用的IV,然后去解密后面的数据。注意,前一个块的长度的数据不参与解密。
即,随机生成一个random,送入加密的数据是plaintext,加密需要的IV是这个random,加密完成之后得到ciphertext,发送的密文则是random + ciphertext。
解密时把收到的第一个块大小的密文数据当成解密IV,剩下的数据送入CBC解密。
乍一看,明明只可能openssl加密的数据,openssl才能解密,polarssl加密的数据,polarssl才能解密,其实不然。
举例:
假设原始数据为1110 1010 1011,加密规则为xor,协商的**是0101,初始化iv是0001。
(1)OpenSSL对其加密(>=TLS 1.1)
生成随机值 1001
送入CBC,CBC参数
加密IV 0001
明文 1001 1110 1010 1011
CBC加密流程
1001 xor 0001(IV) xor 0101(key) = 1101
1110 xor 1101(IV) xor 0101(key) = 0110
1010 xor 0110(IV) xor 0101(key) = 1001
1011 xor 1001(IV) xor 0101(key) = 0111
得到 密文
1101 0110 1001 0111
(2)PolarSSL(MbedTLS)对其解密(>=TLS 1.1)
收到的密文数据
1101 0110 1001 0111
提取前Blocksize大小的值为 解密IV
送入CBC,CBC参数
解密IV 1101
密文 0110 1001 0111
CBC解密流程
0110 xor 0101(key) xor 1101(IV) = 1110
1001 xor 0101(key) xor 0110(IV) = 1010
0111 xor 0101(key) xor 1001(IV) = 1011
得到明文 1110 1010 1011
两者能够互相兼容。
思考:
上述只描述了PolarSSL的解密,其加密也类似。
总的来说,在TLS协议号大于等于1.1时,其加密解密都可以少加解密一个块大小的数据,而不影响任何安全性。
这就是我们能够优化的点,对于请求响应均小的流量模型下,这种优化方式还是很有效的。