我在我的C ++项目中使用openssl来加密和解密文本文件。正如这里已经指出的那样,我正在遵循以下教程:https://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption。我注意到在本教程中,单独的缓冲区用于普通和加密文本。由于数据可能占用大量内存并且算法是按块执行的,我想知道是否可以执行就地加密/解密,以便输出数据与输入数据放在同一个缓冲区中,当它不再需要了吗?
答案 0 :(得分:1)
这是一般性答案,不仅针对EVP _ *。
对于某些实现是,但加密和填充可能存在问题。
对于加密,需要增加输入数据存储以接受填充,但这会改变输入数据,从而改变加密数据。在可以明确指定输入长度的一些实现中,这可以起作用。
对于使用填充进行解密,数据大小会更小,并且必须以某种方式处理,同样一些实现将允许完成此操作。
但是,除非支持实现明确指出使用相同的数据空间,否则不建议这样做。它可能适用于某些输入,但不适用于所有输入,如果将来更改实现内部结构,则可能会中断。
注意:我已经在一个实现上成功测试了这个(不是EVP _ *)。
答案 1 :(得分:1)
EVP_EncryptUpdate() 的 OpenSSL 1.1.1 文档在这里:
https://www.openssl.org/docs/man1.1.1/man3/EVP_CIPHER_CTX_new.html
EVP_EncryptUpdate() 段落末尾的这句话谈到重叠输入和输出缓冲区:
<块引用>它还检查输入和输出是否部分重叠,以及它们是否 返回 0 表示失败。
检查我们看到的实际源代码:
int is_partially_overlapping(const void *ptr1, const void *ptr2, int len)
{
PTRDIFF_T diff = (PTRDIFF_T)ptr1-(PTRDIFF_T)ptr2;
/*
* Check for partially overlapping buffers. [Binary logical
* operations are used instead of boolean to minimize number
* of conditional branches.]
*/
int overlapped = (len > 0) & (diff != 0) & ((diff < (PTRDIFF_T)len) |
(diff > (0 - (PTRDIFF_T)len)));
return overlapped;
}
...
if (is_partially_overlapping(out + ctx->buf_len, in, cmpl)) {
EVPerr(EVP_F_EVP_ENCRYPTDECRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING);
return 0;
}
因此允许完全重叠的输入和输出缓冲区(对于非自定义密码)。只是部分重叠是不允许的。对于自定义密码,会参考密码本身的重叠规则。