Van*_*nya 16 c encryption openssl aes
我在我的程序中使用Open SSL,使用aes密码加密和解密数据.目前有一点内存泄漏,所以我正在寻找一种方法来解决这个问题.在我的加密解密例程中,我有这样的上下文
EVP_CIPHER_CTX_free(ctx);
Run Code Online (Sandbox Code Playgroud)
并创建:
EVP_CIPHER_CTX_new
Run Code Online (Sandbox Code Playgroud)
这是在示例中的OpenSSL wiki页面上
但!在MAN页面上,有使用EVP_CIPHER_CTX_cleanup和EVP_CIPHER_CTX_init功能的建议.所以基本上应该正确使用的是EVP_CIPHER_CTX_new/ EVP_CIPHER_CTX_free某种方式被弃用了吗?并且EVP_CIPHER_CTX_new/ EVP_CIPHER_CTX_free和EVP_CIPHER_CTX_init/ 之间有什么大的区别EVP_CIPHER_CTX_cleanup吗?
if(!(ctx = EVP_CIPHER_CTX_new())) return -1;
if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv))
{
EVP_CIPHER_CTX_free(ctx);
return -1;
}
if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
{
EVP_CIPHER_CTX_free(ctx);
return -1;
}
ciphertext_len = len;
if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) { EVP_CIPHER_CTX_free(ctx); return -1; }
ciphertext_len += len;
EVP_CIPHER_CTX_free(ctx);
Run Code Online (Sandbox Code Playgroud)
mwo*_*era 23
首先,如果您想要一个精确的答案,您应该始终指定您正在使用的OpenSSL版本.FYI 1.0.2是当前的长期支持版本,而1.1.0是最新版本(2016年9月).
如果您阅读1.1.0手册页,您会注意到:
EVP_CIPHER_CTX在OpenSSL 1.1.0中变得不透明.结果,EVP_CIPHER_CTX_reset()出现,EVP_CIPHER_CTX_cleanup()消失.EVP_CIPHER_CTX_init()保留为EVP_CIPHER_CTX_reset()的别名.
简短的回答是:您应该使用EVP_CIPHER_CTX_new初始化并EVP_CIPHER_CTX_free释放内存,无论版本如何,这都是原因.
分配:
1.0.2手册页说:
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
Run Code Online (Sandbox Code Playgroud)
和1.1.0手册页说:
EVP_CIPHER_CTX *ctx;
ctx = EVP_CIPHER_CTX_new();
Run Code Online (Sandbox Code Playgroud)
如果你看一下1.0.2中EVP_CIPHER_CTX_init 的代码
void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx)
{
memset(ctx, 0, sizeof(EVP_CIPHER_CTX));
/* ctx->cipher=NULL; */
}
Run Code Online (Sandbox Code Playgroud)
而EVP_CIPHER_CTX_new是:
EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void)
{
EVP_CIPHER_CTX *ctx = OPENSSL_malloc(sizeof *ctx);
if (ctx)
EVP_CIPHER_CTX_init(ctx);
return ctx;
}
Run Code Online (Sandbox Code Playgroud)
所以你最好初始化上下文,比如在1.1.0示例中:
EVP_CIPHER_CTX *ctx;
ctx = EVP_CIPHER_CTX_new();
Run Code Online (Sandbox Code Playgroud)
对于1.1.0,同样适用.
为了释放记忆:
1.0.2手册页:
EVP_CIPHER_CTX_cleanup(&ctx);
Run Code Online (Sandbox Code Playgroud)
1.1.0手册页:
EVP_CIPHER_CTX_free(ctx);
Run Code Online (Sandbox Code Playgroud)
但是,如果你检查代码,你可以看到1.0.2:
void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
{
if (ctx) {
EVP_CIPHER_CTX_cleanup(ctx);
OPENSSL_free(ctx);
}
}
Run Code Online (Sandbox Code Playgroud)
所以你应该EVP_CIPHER_CTX_free用来解除分配.如果您只想重置其他操作的上下文,则EVP_CIPHER_CTX_cleanup(1.0.2)和EVP_CIPHER_CTX_reset(1.1.0)是您的朋友.
如果你是好奇malloc memset和calloc,这里有一个很好的解释
你不应该再使用EVP_EncryptInit了.该函数确实自动创建了特定的上下文,但它不支持后来添加的加密引擎.EVP_EncryptInit_ex但是明确指出:
ctx必须在调用此函数之前初始化.
所以EVP_CIPHER_CTX_new我想你需要在这里使用.
EVP_CIPHER_CTX_free是另一回事,它似乎已被弃用,我在OpenSSL的手册页上看不出任何提及它.使用后删除密钥材料和密码的其他状态是一种很好的做法(并且是NIST认证功能所必需的).否则,攻击者可能会扫描内存或在稍后阶段使用溢出.
名称EVP_CIPHER_CTX_free仅表示应释放CTX内存.但释放内存并不意味着它首先被清除敏感信息; 它只是返回到系统,它没有义务覆盖它.EVP_CIPHER_CTX_cleanup另一方面,在释放内存之前会明确地清除这些信息(或者它至少做了一次体面的尝试,我认为).因此,您需要在提供密钥材料后调用此函数.
Van*_*nya -5
好吧,我想现在已经清楚了。如果你这样做EVP样式加密/解密,请确保像这样创建上下文:
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
Run Code Online (Sandbox Code Playgroud)
并像这样释放它:
EVP_CIPHER_CTX_cleanup(&ctx);
Run Code Online (Sandbox Code Playgroud)
不要使用EVP_CIPHER_CTX_new/EVP_CIPHER_CTX_free来创建/释放上下文,它们已被弃用!
| 归档时间: |
|
| 查看次数: |
7451 次 |
| 最近记录: |