将证书保存在外部存储器上是一种不好的做法吗?

物联网 安全 MQTT aws-iot
2021-06-19 23:52:03

我们正在使用 STM32 微控制器开发 AWS-IoT。

直到今天,我们还在将证书写入闪存并锁定闪存以防止外部读取。随着应用程序代码的增加,闪存上的空间越来越小,因此我们计划将证书从外部移动到 SD 卡/EEPROM 上,并在连接到 AWS-IoT 之前随时读取。

笔记:

  • 为事物编写的策略将只允许具有特定名称的设备连接到该特定证书。

  • 该事物仅允许发布到连接到数据处理器的 2 个通道(它的名称和数据馈送通道),该处理器将忽略任何流向它的流氓数据包。

  • 如果Thing 发布/订阅任何其他主题,AWS 将立即断开该Thing。

如果我检测到设备被盗/流氓,我们会从服务器停用密钥。

漏洞利用者可以用证书(RootCA、服务器密钥、客户端密钥)做什么?

将此类用例的证书保存在可以被利用者访问的外部存储上是一种不好的做法吗?

4个回答

一点上下文

由于您将 MQTT 与 AWS IoT 结合使用,因此您应该使用 X.509 证书进行身份验证和安全。亚马逊有一些关于如何保护证书的指导,所以我会在这里引用:

证书使非对称密钥能够与设备一起使用。这意味着您可以将私钥刻录到设备上的安全存储中,而无需让敏感的加密材料离开设备。

由于您目前正在使用 STM32 的读出保护(RDP),因此除了最坚定的攻击者之外,所有攻击者都将无法访问您当前方案中的证书:

全局读出保护允许嵌入式固件代码(预加载在闪存中)防止逆向工程、使用调试工具的转储或其他侵入性攻击手段。

  • 0 级 - 无保护(默认)
  • 级别 1 - 通过调试或 RAM 加载代码的代码转储来保护闪存免于读取
  • 级别 2 - 禁用所有调试功能

外部存储会安全吗?

它可能不那么安全如果您的客户的私钥被盗,攻击者可以发送看似来自您设备的数据,但实际上并非如此。尽管不清楚您发送的是什么数据,但任何不受信任的数据都可能存在安全风险。

我需要保密哪些位?

在 AWS IoT 上创建设备证书时,您应该看到如下图像:

物联网

来自AWS IoT 文档创建和激活设备证书页面的图像。

私钥是您真正需要保留的东西... private,如果可能,绝对应该存储在读保护的内存中。公钥和证书旨在共享,因此如果您的空间不足,您可以安全地将它们移至外部存储。您可以在页面SSL/TLS 是如何工作的?Wikipedia上的信息安全堆栈交换和公钥密码学如果我不包含这张图片来解释为什么私钥需要保密,我想我会对你不利

公钥密码学.

图片来自维基百科,已发布到公共领域。

您设备的公钥是 AWS IoT 用来签署消息以发送到您的设备的密钥(但它不能证明谁在发送消息)。所以,真的,如果有人窃取了公钥,这并不是一场巨大的灾难,因为它并不是秘密。

私钥是你的设备用来解密的消息,所以这是一个稍微大一点的问题,如果一个攻击者窃取这一点。

您还询问了如果攻击者窃取了 RootCA 证书会发生什么。如果有人窃取了AWS IoT 的私钥,那将是灾难性的,但您设备上的 RootCA 证书并非如此RootCA.crt亚马逊给你的是完全公开的,其目的是让你可以验证你不会被以任何方式攻击(最有可能是人在这方面的中间人故作AWS物联网的服务器)。

被黑客入侵的设备会造成什么损害?

您被盗的设备只能执行策略中列出的操作尽量遵循最小特权原则只授予您的设备绝对需要的权限,因此如果最坏的情况确实发生,它不会造成太大破坏。对于您的具体情况:

该事物仅允许发布到连接到数据处理器的 2 个通道(其名称和数据馈送通道),该数据处理器将忽略任何流向它的流氓数据包。

那挺好的。任何攻击都应该隔离在设备可以发布到的两个 MQTT 主题上,这样就不会造成大规模的伤害。

理想情况下,您希望您的整个系统具有这样一种设计,即解剖单个单元只会破坏该单元,而不是整个系统。

特别是如果您将密钥存储在不同的存储器中,以便它们跨越芯片之间的标准电气接口,那么它们应该只是已经可以安全发布的密钥,或者对于设备的特定物理实例是唯一的。

如果单个密钥是从单个设备中提取的,并且开始被滥用或出现在必须来自多个未授权克隆的大量流量中,那么您可以在服务器端禁止该密钥。

您的密钥当然应该具有以下属性:未经授权的一方可以从一些提取的示例中猜测或生成他们自己的原始兼容实例 - 即,您需要在有效密钥所在的位置记录已生成的密钥只有巨大可能性空间中的一小部分和不可预测的部分,否则您需要对您生成的密钥进行签名,并使您的系统只接受与其签名证明相结合的密钥。

您提到了“证书”,但从上下文来看,我认为您指的是两种不同的东西。

  • 您的设备有一个私钥,该私钥对于该设备是唯一的,并且在设备之外是未知的。此密钥可识别您的设备。任何可以访问该密钥的人都可以模拟该设备。这意味着他们可以,特别是:

    • 在您的设备被合法授权发布的频道上发布有效但不正确的数据。
    • 发布将禁止合法设备的无效数据。
    • 可能,根据用例,公开设备所有者的一些私人信息。

    这个私钥最好保密。

  • 您的设备可能有至少一个公共密钥,允许它承认它在谈论哪些服务器。如果任何人都可以读取此密钥,那没关系:它是公开的。但是攻击者不应该能够修改密钥。否则,他们可以与设备通信并冒充服务器。这可以让他们做以下事情:

    • 将固件更新推送到设备。
    • 将配置更新推送到设备。
    • 使设备将其数据上传到不同的位置。

好消息是,这种威胁分析实际上并不是很相关。您不需要牺牲任何安全性(至少不是机密性和真实性属性——如果你在外部存储东西,那么可用性就会受到影响,因为那是系统中可能会丢失的一部分。)

只要您有至少 128 位的存储空间,您可以至少写入一次(您拥有的甚至更多),您就可以实施安全的远程存储解决方案。使用有限空间的设备存储来存储密钥。该密钥对于每个设备必须是唯一的;STM32 有一个硬件 RNG,所以你可以在第一次启动时在设备上生成它。如果您的设备没有硬件 RNG,您可以在安全的设备外位置生成密钥并将其注入设备。

使用此密钥,对存储在设备上的内容使用经过身份验证的加密当你想从外部存储读取一些数据时,加载它,解密并验证它。当您想将一些数据写入外部存储时,请对其进行加密和签名。这保证了数据与内部存储中的数据一样机密和真实。

认证加密足以保证数据的机密性和真实性,但并不能完全保证其完整性

  • 如果有多个数据块,那么当设备读回一个数据块时,它不能确定这是正确的块。解决方案:在每个块的内容中包含一个唯一标识符(例如,以"AWS-IoT private key.", "configuration CA certificate.", "publishing server CA certificate.", "user personal data.", ...之一开始每个块)。
  • 如果您在某个时间更新数据,那么当您读回数据时,您无法确定是否获得了该数据的最新版本。如果有人可以修改外部存储,他们就不能放假数据,因为那样会导致真实性检查失败,但是他们可以恢复旧数据,因为过去的真实数据仍然是真实的。解决方案:在外部存储的每个数据块中,包含一个计数器,每次写入该块的新版本时都会增加该计数器。当你读回一个块时,验证它是预期的版本。

为了避免在外部存储损坏或以其他方式丢失的情况下使设备变砖,在内部存储空间有限的情况下,您应该优先考虑将设备重置为“良好”状态所需的一切,例如恢复出厂设置. 第二个优先事项是性能考虑。

您应该尝试对客户端密钥保密(但要了解丢失它的含义(1),如其他答案中所述)。服务器公钥和 AWS 公共证书对于设备端的安全很重要,不是因为您想保密,而是因为通过替换 AWS 证书(在受感染的设备上),攻击者可以说服设备执行与攻击者的主机交换,或将您与 AWS 的通信中间人。

通过这样做 (2),攻击者可以剥离 TLS 安全性,这可能会导致安全性的充分降低,以至于他们可以对客户端密钥进行逆向工程。

根据这个推理,可以安全地在外部存储设备中公开的唯一密钥是服务器公钥。更改此 (3) 只会让您的设备被迫连接到可能难以工程师访问的流氓 AWS 服务。即使仅泄露此密钥也可能允许某人窥探或伪造某些传输(例如,如果 TLS 层可以以某种方式降级)。

因此,总而言之,风险不仅仅是泄露信息,如果可以为(据称受信任的)固件提供不受信任的安全信息,则存在风险。