调用EVP_DecryptUpdate后可以设置AES-GCM标记吗?

时间:2017-03-14 22:16:53

标签: openssl aes-gcm

在我看到的所有代码片段中,我都看到使用OpenSSL EVP接口进行AES-GCM(example),代码看起来大致如下:

EVP_DecryptInit(...);
EVP_CIPHER_CTX_ctrl(..., EVP_CTRL_GCM_SET_TAG, ...);
while (...) {
  EVP_DecryptUpdate(...);
}

success = EVP_DecryptFinal(...);

在调用EVP_CTRL_GCM_SET_TAG之后,使用EVP_DecryptUpdate 设置代码是否合法?例如,如果正在传输传入的密文,并且标记位于流的末尾,这将是方便的。

相关问题:EVP_CTRL_GCM_SET_TAG是否在某处正式记录?

2 个答案:

答案 0 :(得分:2)

  

在调用EVP_DecryptUpdate后,使用EVP_CTRL_GCM_SET_TAG设置标记是否合法?例如,如果正在传输传入的密文,并且标记位于流的末尾,这将是方便的。

目前很难说,但我猜不是。来自OpenSSL的wiki页面EVP Authenticated Encryption and Decryption

  

当您调用最终的EVP_DecryptUpdate时会执行标记验证,并由返回值反映:没有对EVP_DecryptFinal的调用。

GCM是一种在线模式,这意味着您可以对其进行流式传输。但是,EVP接口是通用的,它们支持其他经过身份验证的加密模式,如CCM。 CCM模式需要提前标记大小,因为它用于格式化标题。 CCM是离线模式,因为标签的大小需要事先知道纯文本。我正在实现CCM限制所有其他类似模式的飞跃。

此外,OpenSSL是SSL / TLS库,而不是通用加密库。 TLS协商密码套件和标签长度作为握手协议的一部分。 TLS没有您描述的用例,因此OpenSSL无需支持它。

相关的,“OpenSSL是一个SSL / TLS库”是库中有时会遗漏一些好东西的原因。这是一个治理问题。

  

相关问题:EVP_CTRL_GCM_SET_TAG是否在某处正式记录?

这个问题的答案是否定的:

$ cd openssl-src
$ grep -IR EVP_CTRL_GCM_SET_TAG *
include/openssl/evp.h:# define     EVP_CTRL_GCM_SET_TAG      EVP_CTRL_AEAD_SET_TAG
$
记录了

IF EVP_CTRL_GCM_SET_TAG,然后您会看到文件扩展名为*.pod的点击。 pod文件是手册页的源。

但是上面有一些wiki文档。 Matt Caswell写道,他是OpenSSL开发者之一。虽然手册页是官方文档,但维基在这种情况下同样出色。

答案 1 :(得分:1)

我不知道答案,但我想分享对此的调查。

openssl Wiki页面https://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption上的示例显示了以下顺序:

EVP_DecryptUpdate(...);
EVP_CIPHER_CTX_ctrl(..., EVP_CTRL_GCM_SET_TAG, ...);
EVP_DecryptFinal(...);

因此您可能认为这是合法的,但是在我的测试中只有一半有效:当我设置了altered tag时,对EVP_DecryptFinal_ex的调用指示错误(返回非1),但随后对ERR_print_errors_cb的调用则不显示任何错误。很奇怪。