0%

AEAD接口和GCM算法

AEAD接口用于同时加密和消息完整性认证。GCM是实现这个接口的一个具体实现模式。

1. 简介

TLS协议中使用的模式最开始有ECB、CBC等,为了对消息完整性进行确认,保证消息没有被篡改,还需要一个HMAC算法,其实就是对消息进行hash,得出来的值缀在被确认消息的后边。这就有个问题,是先对明文进行HMAC,再加密;还是先加密,再对密文进行HMAC。最开始是先对明文取HMAC,再加密(RFC5246,TLS1.2);后来认为这种不安全,就先加密,再对密文取HMAC(RFC7366, encrypt-then-mac);再后来认为这样也不安全,就出现了加密和验证在同一个操作中进行,也就是AEAD(RFC5116, Authenticated Encryption with Associated Data),带附加数据的认证加密算法。

GCM是一种加密模式,跟ECB、CBC类似,但相比后者的优势是多了附加数据认证,并且可以并行计算,速度很快。AEAD相当于定义了各个协议使用GCM模式的一个统一接口,AEAD可以用GCM去具体实现,也可以用CCM去实现。

2. GCM模式

还有个叫GMAC的算法,是GCM不输入附加数据,只对明文数据取最后的认证标签,算是GCM的一个变体。

计算的前提是已经选好了底层的块加密算法(AES,SM4等)和对应密钥key。

2.1. 带认证的加密模式

输入数据

  • 明文P, len(P)<=2^39-256 位
  • 附加数据A,包含不需要加密的但需要保证不能被改变的数据,比如IP、PORT等, len(A)<=2^64-1位
  • 初始向量IV, 1<=len(IV)<=2^64-1 位,为了兼顾安全、效率,建议96位,12字节

输出数据

  • 密文C,长度跟输入明文一样
  • 鉴别标签,记为T,长度可以是128,120,112,104,96位这5个的一个

图例
HMAC

2.2. 带认证的解密模式

输入数据

  • 初始向量IV, 1<=len(IV)<=2^64-1,为了兼顾安全、效率,建议96位,12字节
  • 附件数据A
  • 密文C
  • 鉴别标签T

输出数据
输出一下之一:

  • 明文P

或者

  • 特殊的错误代码

图例
HMAC

3. AEAD接口

AEAD包含两个操作:带认证的加密和带认证的解密。RFC5116-An Interface and Algorithms for Authenticated Encryption规定了该接口的输入输出。AEAD其实就是封装了一下GCM模式算法。

3.1. 带认证的加密模式

输入数据

  • 密钥K,长度为[1,255]字节,但对每个具体的AEAD算法,该长度是固定的
  • 初始化向量IV,也叫nonce,建议是12字节
  • 明文P,长度可以是0
  • 附加认证数据A,长度可以是0

输出数据

  • 成功:密文C,长度可以是0,最少是明文P的长度,实际中还要加上GCM的鉴别标签
  • 失败:错误值,此时不能输出部分加密过的数据

图例
HMAC

3.2. 带认证的解密模式

输入数据

  • 密钥K,
  • 初始化向量N
  • 附加认证数据A,长度可以是0
  • 密文C

输出数据

  • 成功:明文P
  • 失败:错误值,此时不能输出部分解密过的数据

图例
HMAC

4. TLS1.2中使用的AEAD

RFC5288-AES Galois Counter Mode (GCM) Cipher Suites for TLS定义了如何在TLS1.2中跟RSA,DSA和DH密钥交换算法配合使用AEAD接口。该RFC定义了如下加密套件:

  • CipherSuite TLS_RSA_WITH_AES_128_GCM_SHA256 = {0x00,0x9C}
  • CipherSuite TLS_RSA_WITH_AES_256_GCM_SHA384 = {0x00,0x9D}
  • CipherSuite TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = {0x00,0x9E}
  • CipherSuite TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = {0x00,0x9F}
  • CipherSuite TLS_DH_RSA_WITH_AES_128_GCM_SHA256 = {0x00,0xA0}
  • CipherSuite TLS_DH_RSA_WITH_AES_256_GCM_SHA384 = {0x00,0xA1}
  • CipherSuite TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 = {0x00,0xA2}
  • CipherSuite TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 = {0x00,0xA3}
  • CipherSuite TLS_DH_DSS_WITH_AES_128_GCM_SHA256 = {0x00,0xA4}
  • CipherSuite TLS_DH_DSS_WITH_AES_256_GCM_SHA384 = {0x00,0xA5}
  • CipherSuite TLS_DH_anon_WITH_AES_128_GCM_SHA256 = {0x00,0xA6}
  • CipherSuite TLS_DH_anon_WITH_AES_256_GCM_SHA384 = {0x00,0xA7}

其中:

  • 输出的鉴别标签长度都是16字节,128位
  • nonce长度为12字节,96位,分为两部分 salt[4] || nonce_explicit[8]。其中salt是隐含部分,从握手中生成:client_write_IV 或 server_write_IV;nonce_explicit是发送端选取的,并放在TLS记录层的GenericAEADCipher.nonce_explicit字段随包发送,在同一个GCM加密上下文中使用的nonce必须是唯一的,否则会严重降低安全性,nonce_explicit可以是递增的64位序列号,不会回绕。
  • 密钥K是client_write_key或server_write_key
  • 附加认证数据为 seq_num || TLSCompressed.type || TLSCompressed.version || TLSCompressed.length

5. TLCP中使用的AEAD

跟TLS1.2是一样一样的

6. TLS1.3中使用的AEAD

  • 输出的鉴别标签长度都是16字节,128位
  • nonce长度为12字节,构成方法为0(paddings to iv length) seq(64bits) XOR client_write_iv/server_write_iv, seq是64位从0开始递增的序列号
  • 附加认证数据为 TLSCiphertext.opaque_type || TLSCiphertext.legacy_record_version || TLSCiphertext.length

参考

  1. RFC5246–TLS1.2
  2. RFC5116–An Interface and Algorithms for Authenticated Encryption
  3. RFC5288–AES Galois Counter Mode (GCM) Cipher Suites for TLS
  4. 国内SSL标准–GBT 38636-2020信息安全技术传输层密码协议TLCP
  5. RFC8446–TLS1.3