在我看到的所有代码片段中,我都看到使用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
是否在某处正式记录?
答案 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的调用则不显示任何错误。很奇怪。