c - 是否可以通过分配内存来恢复 secret 数据(例如用于解密的空闲内存中的 RSA 私钥)?

标签 c cryptography malloc

例如,让我们使用伪代码尝试获取存储在已分配(然后释放)内存中的 RSA 私钥:

int main(){
    bigNum priKey;


    while(true) {
        void *mem = malloc(2024); //allocate a good amount of chunk

        if(rsaKeyIn(mem, &priKey))
            break;
    }

    printf("RSA PRK found: %s", priKey.getText())

    return 0;
}

问题:这可能吗?或者是否有可能恢复任何其他 secret 数据?

或者为了安全起见,操作系统是否将空闲的内存归零?如果不是这种情况,我们是否应该在释放之前手动用零填充分配的内存?

最佳答案

这是可能的,因为释放内存并不一定意味着它被清除。

例如,给定以下代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
    int i, len = 20;
    char *p = malloc(len);
    strcpy(p, "this is a test!!");
    printf("&p=%p, p=%s\n", &p, p);
    for (i=0; i<len; i++) {
        printf("%02x ", p[i]);
    }
    printf("\n");
    free(p);
    // undefined behavior below: dereferencing freed memory
    printf("p=%s\n",  p);
    for (i=0; i<len; i++) {
        printf("%02x ", p[i]);
    }
    printf("\n");
    return 0;
}

我的系统输出如下:

&p=0x7ffd24e08290, p=this is a test!!
74 68 69 73 20 69 73 20 61 20 74 65 73 74 21 21 00 00 00 00 
p=
00 00 00 00 00 00 00 00 61 20 74 65 73 74 21 21 00 00 00 00 

因此,如果您的程序存在允许攻击者控制它的安全漏洞,他们可以转储已释放内存的内容并暴露敏感数据。

因此,一旦不再需要包含 secret 数据的内存,就应将其删除。对此的幼稚方法是在内存块上调用 memset,但是如果许多编译器发现在该点之后不再使用内存,则会对其进行优化。

在 C 标准中定义了一个名为 memset_s 的函数,它保证不会被优化掉,但并不是所有的实现都有它。你需要找到一些库调用来清除我不会优化的内存。像 OpenSSL 这样的库会在您调用它们的清理例程时为您执行此操作(参见 this post 作为示例)。

关于c - 是否可以通过分配内存来恢复 secret 数据(例如用于解密的空闲内存中的 RSA 私钥)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57077378/

相关文章:

c - 使用 berkeley db 实现缓存

Objective-C 创建一个 C 数组属性

c - 无法使用 OpenGL 3.3 上下文 macOS 创建窗口,并且通过 brew 安装了 GLFW

c - 在 C 语言中 if(x) 到底解析成什么?

c - 程序在实现链表时查找堆栈中最大的元素,但数据未被访问

java - Java中的简单凯撒密码

c# - 解密TripleDES "Bad Data"

Java 7 : output from encryption with public RSA key using cipher "RSA/ECB/OAEPWithSHA1AndMGF1Padding" does not match with openssl command

c - 释放内存、函数

c - 如何确保以下函数没有过度分配?