在某些假设下将未加密的密钥存储在 RAM 上的可行性

在某些假设下将未加密的密钥存储在 RAM 上的可行性

我们有运行 Linux 5.4.31 内核的 IoT 网关。这些网关需要管理数千个移动设备,每个设备都有唯一的加密密钥。这个想法是当设备进入范围时从服务器获取设备的密钥(通过安全通道),只要设备在范围内就使用它进行解密,并在设备离开时从内存中删除密钥。解密必须在网关上完成,因为我们必须根据接收到的数据执行特定操作。

我们希望将密钥不加密地存储在 RAM 上,因为我们不希望每次访问密钥时都需要解密密钥。我们有以下假设:

  1. 无法对网关进行物理访问。
  2. 该服务在非 root 用户下运行。
  3. 攻击者可能以非 root 用户身份(如果重要的话,这与服务用户不同)访问网关。
  4. 攻击者可能会实施缓冲区溢出攻击。

在这些假设下,攻击者可以选择哪些选项来访问 RAM 上的加密密钥:

  1. 我们将密钥存储在静态分配的内存中(通过 C 中的 static 关键字,而不是在堆栈中)
  2. 我们将密钥存储在动态分配的内存上(这可能是一次性分配,因为我们的资源有限)。

另外,我们应该对非 root 用户施加哪些限制,例如,他们不能访问交换内存、核心转储、安装软件包、使用 gdb 等,以防止访问进程 RAM?

注意:如果攻击者具有 root 访问权限,那么他们无论如何都可以使用用于访问服务器的私钥来访问所有密钥,因此我们不考虑此问题的这种情况。

答案1

您可能会得到更好的答案信息安全SE

您应该通过锁定相关内存范围来确保密钥不会写入交换(请参阅mlock);如果您为键分配内存池,这会更容易做到。

另外,我们应该对非 root 用户施加哪些限制,例如,他们不能访问交换内存、核心转储、安装软件包、使用 gdb 等,以防止访问进程 RAM?

非 root 用户无论如何都无法访问交换区,通过将密钥锁定在内存中,您可以完全避免该问题。非 root 用户也无法访问除自己进程生成的核心转储之外的核心转储,并且他们不能ptrace其他用户的进程(这意味着它们无法运行gdb等来查看其他进程的内存)。

如果您的 CPU 提供所需的功能,您可以考虑使用pkeys以获得额外的保护。另一种可能性是将密钥处理完全委托给内核;看keyrings了解详情。

相关内容