是否可以以安全的方式加密无头嵌入式设备上的敏感数据?

是否可以以安全的方式加密无头嵌入式设备上的敏感数据?

我的公司使用 Raspberry Pi,其中所有数据(操作系统、我们的软件等)都存储在 SD 卡上。我们配置这些设备(在其上加载我们的软件),并将它们发送到现场(我们无法控制的环境)。这些 Pi 上有敏感数据,担心现场有人会拿走 Pi,并访问这些敏感数据。

不将敏感数据存储在 SD 卡上,而是通过安全网络进行流式传输的明显解决方案对我们来说不起作用 - Pi 并不总是能够访问互联网或任何其他类型的网络。

另一个显而易见的解决方案是对存储数据的分区进行加密,但这被证明是一个挑战。 Pi 需要能够在运行时访问这些敏感数据,这意味着无论我们使用哪种类型的加密,Pi 都需要能够在启动时解密加密分区。这意味着它需要某种存储在非加密分区上的解密密钥,这本质上是有缺陷的。攻击者可以轻松访问密钥,并使用它来解密加密的分区。

有一些硬件解决方案(例如 Zymkey)有望解决这个问题。我们尝试过,并且我只花了 5 分钟多就闯入了一个使用 Zymkey 作为密钥的加密根分区。问题是,即使您可以加密根分区,也无法加密启动分区,该分区存储内核以及在启动时将参数传递给内核的文件。这使得攻击者可以修改这些引导加载程序文件,例如要求内核在引导时启动 shell,从而使攻击者能够完全访问加密的根分区。

即使我们要编译自己的自定义内核,但不接受任何参数,从而防止引导参数向攻击者提供 shell,该自定义内核也会存储在攻击者有权访问的 /boot 分区上。没有什么可以阻止他们用通用内核替换我们的自定义内核。

我知道你可以将一些硬件解决方案组合在一起,将 SD 卡粘合起来,和/或将 Pi 放入装有诱杀装置的盒子中,如果有人试图打开盒子,它将删除加密密钥,并卸载加密分区(或重新启动)。这些都是相对容易绕过的,而且充其量只是hacky。

所以我的问题是:从概念上讲,是否有可能加密整个根分区,或者只是加密一些可以存储敏感文件的数据分区,这样,如果攻击者拿到 SD 卡,他们将无法让他们自己拿到文件? Linux 在运行时仍然需要能够解密和使用这些文件。

答案1

如果没有最低限度的物理安全,您就无法保护敏感数据。 Raspberry Pi 没有物理安全性。您要么需要将其放入防篡改盒子内,要么需要使用内置防篡改功能的不同硬件。

是的,它会花费更多。安全性是一项通常需要付出代价的功能。

通知来自您引用的论坛帖子仅作为 Raspberry Pi 配套设备使用的 Zymkey 无法保护任何内容。您还需要对 Pi 本身进行一些物理保护。

具有安全启动功能的单板计算机应该可以工作。我没有什么特别的型号可以推荐。显然也可以在 Raspberry Pi 上安装 TPM;这不会为您提供安全启动(在执行代码之前不验证代码),但它会为您提供验证启动(如果代码不是预期的,它将无法从 TPM 检索密钥)。请注意,无论哪种方式,这都只能防止小规模的物理攻击,例如交换 SD 卡,而不能防止更具侵入性的攻击,例如在 RAM 总线上插入逻辑探针。

答案2

为此,您可以使用 LUKS,使用加密文件作为应用程序存储文件的保管库。

要使用加密卷,您必须:

  1. 打开加密的 LUKS 卷。
  2. 将加密卷装载到装载点以供您的应用程序使用。

当你完成后,

  1. 卸载卷安装点。
  2. 关闭加密的 LUKS 卷。

下面链接的帖子涵盖了所需的步骤。

在 Linux 上创建加密文件库

答案3

我过去也遇到过类似的问题。我预计没有完美的解决方案。这在很大程度上取决于入侵者想要投入多少时间闯入系统以及您投入多少时间来制造困难。肯定没有 100% 安全的解决方案。 Zymkey 解决方案确实很简洁,但根据项目的不同,它可能成本高昂,而且在某些情况下效果不佳。

这就是我所做的,这对于客户的请求来说已经足够了:

  1. 创建一个包含所有加密数据的隐藏卷(尝试将其设置为只读,如果可能的话,读取一次以提高速度:加密卷非常慢。不要将其用于频繁访问/修改的数据)。就我而言,我存储的代码只读一次。
  2. 创建一个命令来进行一些验证,然后安装该卷。使用像 C 这样的低级语言(是的,我知道,有点难,但是如果你做得正确的话,它会迫使入侵者使用反汇编器或内核调试器)。
  3. 编译时隐藏所有符号
  4. 使用非常复杂的算法混淆所有字符串。 (字符串包括密码、文件名、外部命令等,基本上什么都做)
  5. 加密混淆的字符串(我使用的是 libtomcrypt)
  6. 确保所有字符串都不可见(使用 strings 命令)
  7. 在有效函数之间插入随机和复杂的数学计算函数以使反汇编复杂化
  8. 此命令将运行外部命令来挂载需要多个身份验证变量的加密文件系统:
  • 使用PI的唯一序列号(/proc/cpuinfo)
  • 将 SD 卡的序列号用于其他卡(或与 PI 一起使用)
  • 使用命令动态生成的一些附加文件
  • 使用dos分区中文件的校验和(start.elf、kernel.img)
  • 验证 root 密码未被更改
  • 验证时区、操作系统版本以及可能更适合您的环境的操作系统的其他方面
  • 如果您有某种类型的网络访问(即使只是本地)或连接到它的特定设备,请检查它们是否存在
  1. 文件应在内存中创建、用于挂载和删除
  2. 密码应作为环境变量传递,这样在 ps/top/htop 中就看不到它们
  3. 基本上确保如果不满足所有这些条件,该命令将不会运行。

当所有这些检查都正确时,该命令将挂载该卷。 (将命令的执行添加为 systemd 服务)。安装您不会使用的众所周知的服务,并将可执行文件替换为新命令。您甚至可以隐藏为其他服务运行的某个脚本的命令。

虽然花了一些时间,但回忆过去的 C 语言还是很有趣的。当然有办法侵入C命令的代码,但我保证入侵者会花几个不眠之夜去尝试。就我而言,客户只是想避免其他人将 SD 卡复制到它,这对我们来说效果很好。

相关内容