TLS1.2 AEAD GCM
TLS1.2 AEAD GCM的计算
TLS1.2中记录层协议对数据的保护方法支持三种算法:
(源自RFC 5246中6.2.3)
- Null or Standard Stream Cipher
- CBC Block Cipher
- AEAD Ciphers
我在抓包的过程中,发现算法套件是AES_GCM, 因此是属于AEAD Ciphers,AEAD的另一种算法是CCM,这里不做介绍,感兴趣的可以去看RFC.
TLS 记录层协议在进行数据加密保护时,过程是:
fragment —》compress ----》encrypt
即分段、压缩、加密
分段的数据要小于2^14
压缩算法因为存在安全问题,目前一般不压缩
下面重点分析AESGCM的加密过程:
首先看抓包数据,我们分析加密的第一条,即handshake的最后一条,Finished数据包,如下图所示:
图中可以看出整个TLS包的数据为:
16030300280000000000000000b75315d8ce17033a17c67bc7f6818873a9bd1adb0a5e0516ced403d83f173d1e
其中,1603030028为报头,剩余为加密的数据段
RFC5246中6.2.3.3中TLSCiphertext.fragment的数据结果如下:
数据结构分为两部分,结合RFC5246的介绍,可对
0000000000000000b75315d8ce17033a17c67bc7f6818873a9bd1adb0a5e0516ced403d83f173d1e
进行解析,
其中前八个字节0000000000000000为seq_num,根据RFC的介绍,seq_num为64位,从0开始,单调递增。
而剩余的32字节数据:b75315d8ce17033a17c67bc7f6818873a9bd1adb0a5e0516ced403d83f173d1e
即为opaque content[TLSCompressed.length]
根据RFC5246, AESGCM有4个输入,write_key, nonce, plaintext,
additional_data:
write_key:数据发送端的加密工作**
nonce:
salt + seq_num
plaintext:明文
additional_data:
这里write_key和plaintext 不用过多介绍,比较简单。nonce和additional_data的来源不是特别清楚。
先说additional_data吧,如上图所示,RFC5246是给出了additional_data的结构组成,但是由于没有使用压缩算法,type和version是何值不是确定,后来仔细看了RFC5246,有这样的介绍:
一开始没有结合上下文准确理解这里的identical的对象,后来经专家指点,发现这个type和version就是TLS的报头中的信息。
因此对于上面的抓包数据,
additional_data = ‘0000000000000000’+‘160303’+‘0010’
上文机密的数据长度为32(0x20)字节,为什么这里是‘0010’?
这是因为上文的32字节数据,包含MAC数据,AES_128_GCM的MAC长度为16,所以实际的密文数据为16(0x10)字节。
最后剩下了nonce,nonce在RFC5116里有详细介绍,nonce一般有两部分组成,隐式部分+显示部分,最小长度为12字节。隐式部分一般使用发送方的4字节IV值(salt),显示部分一般使用seq_num。
因此这里的nonce = IV + seq_num。
AES_128_GCM的counter(IV)是16字节,而这里只有12字节?
经百度查询,有专家指出,AES_128_GCM在计算时会在12字节nonce后面加上4字节的00000001。
最后,调用AESGCM的解密函数,得到明文:
1400000cda12b5318bc16ac3dcf86d53
(bingo!!!)
一看格式就证明基本没问题,数据结构如下图所示。
1400000c为密文结构的报头。
0x14(20)为Finished. 0x00000c为数据长度。
da12b5318bc16ac3dcf86d53为12字节的明文数据,即为下图数据结构的verify_data.