4

AEAD接口和GCM算法

 3 years ago
source link: http://suntus.github.io/2020/12/25/AEAD%E6%8E%A5%E5%8F%A3%E5%92%8CGCM%E7%AE%97%E6%B3%95/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

AEAD接口和GCM算法

发表于

2020-12-25 07:10

|

更新于 2021-04-29 17:15

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

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
  • 鉴别标签T

输出数据
输出一下之一:

  • 特殊的错误代码

图例
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. 带认证的解密模式

输入数据

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

输出数据

  • 成功:明文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

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK