对称加解密之AEAD

269 阅读2分钟

关于

上篇主要描述了对称加解密概念及在C和Python语言中的实践,本篇主要说下TLS1.3中使用的对称加密AEAD模式算法。

模式由来

在密码学里面,经常有人去使用各种假密钥去尝试解密ciphertext,然后根据反馈的结果去不断推断从而破解,这也是OpenSSL的error handle方法在对称加密算法里面返回的信息非常少,或者说根本没有。

为了防止这种行为,密码学专家们提出了AE(Authenticated Encryption)模式。前文说到块式加密算法有各种机密模式,其中GCM模式不同于CTR之处在于她不仅加密plaintext,而且验证ciphertext,意思是说如果发现ciphertext有异同,就会失败。

密码学家们也发明了AEAD(Authenticated Encryption with Associated Data)模式。有一些AE模式允许加密后的数据和未加密的信息作为校验信息,这样就允许使用者添加一些上下文应用信息,这些信息就是Associated Data,OpenSSL中也叫做ADD(Additional Authenticated Data)。

模式应用

TLS1.3只支持AEAD模式的对称加密算法,比如AES_128_GCM, AES_256_GCM, CHACHA20_POLY1305等。

实践

使用OpenSSL需要掌握她的各种“套路”,下次有机会记录下OpenSSL编程,估计大家平时使用的也少。
使用AEAD模式的算法时,比如使用CHACHA20_POLY1305,需要key、ADD、IV,plaintext,最后输出ciphertext和tag,一般将ciphertext和tag结合后发送给对方。以下提供不完整C代码片段说明(Python代码可以参考上篇):

	EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
/* 设置IV的长度 */
	EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, IV_LEN, 0);
/* 初始化算法 */
	EVP_EncryptInit_ex(ctx, EVP_chacha20_poly1305(), NULL, key, iv);
/* 添加ADD数据,注意ADD数据必须先添加,而且ouput必须设置为NULL */
	EVP_EncryptUpdate(ctx, NULL, &outlen, aad, aad_len);
/* 添加plaintext */
	EVP_EncryptUpdate(ctx, out, &outlen, plaintext, plaintext_len);
/* 最后处理 */
	EVP_EncryptFinal_ex(ctx, out, &outlen);
/* 获取auth tag */
	EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, TAG_LEN, tagout);

以上需要注意的几点:

  1. 设置IV长度,因为OpenSSL有默认的IV长度,比如For GCM AES and OCB AES the default is 12 (i.e. 96 bits). For OCB mode the maximum is 15,而且必须在添加IV之前设置。
  2. ADD数据必须在plaintext之前添加,使用EVP_EncryptUpdate添加时候,output参数必须设置为NULL。
  3. EVP_EncryptFinal_ex对于某些模式的算法做收尾工作,比如CBC模式,这个阶段会给最后一个block data添加padding,然后进行加密。所以这个函数最后还有可能产生加密数据。