如何在大量设备上(物理地)注入密钥?

信息安全 密钥管理
2021-08-18 21:48:51

我正在设计的系统有大量(假设数百万)个单独的设备,每个设备都需要注入一个专用于该设备的唯一对称密钥。每个设备还具有一个序列号,可以通过该序列号对其进行物理跟踪和核算。

问题:有哪些行业标准方法可以将密钥注入如此大量的设备?

我对在这种工业规模上可用的物理机制很感兴趣。该解决方案可以是硬件和软件的组合。

相关要求:

  1. 没有两个设备可以获得相同的密钥。系统需要确保每个密钥只使用一次。
  2. 出于设备生命周期内可追溯性的原因,系统需要知道哪个序列号接收了哪个密钥。
4个回答

由于您似乎无法(可能可以理解)提供更多信息,因此我将重新表述您的情况,以便您确定我们是否处于同一水平。并做出一个看起来合理的假设。

出于所有意图和目的,对称密钥不是密钥,而只是数据,因为我们从某个系统中“预制”了它们。因此,换句话说,您在问我如何通过“不安全通道”(=工厂及其员工)向一组“用户”(=设备)发送一些“私人数据”(=密钥),具有唯一标识特征(= 序列号)的用户,该特征很容易被恶意用户知道和/或模仿。由于攻击而丢失一些设备(或有重新编程的成本)也不是问题。

您需要的是每个用户只能请求一次其数据。

  1. 用户使用经过身份验证的安全通道连接到您的服务器(我建议使用某种 SSL 连接)。
  2. 用户将其 ID(序列号)发送到服务器。
  3. 服务器检查该ID对应的数据(对称密钥)是否尚未分发(未标记)。
  4. 未标记:服务器向用户发送其数据(对称密钥)并将此密钥标记为在其 DB 系统中分发。
  5. 已标记:服务器未将数据传递给用户。

只有从该服务器接收到对称密钥,设备才能工作。这可能是生产过程的最后一部分,让设备初始化(获取密钥)并检查它是否已收到密钥(当然,设备不知道密钥是)。

如果有人破坏您的工厂并开始向服务器发送恶意请求,它不会破坏安全性(尽管由于某些设备是使用已使用的序列号制造的,因此会涉及一些成本,设备的成本必须非常小,或者您可以重新编程序列号,当然这也应该重置对称密钥)。

该系统的重点是减少安全环境的大小,只有服务器及其数据库需要安全,如果需要,可以将它们放置在异地。假设服务器和数据库是安全的,并且设备在初始化和客户拥有之间不能被读取或滥用,一旦设备出厂,它打开的事实会让客户知道它有它的密钥并且只有服务器(和 DB)知道这个密钥。

我相信在初始化和客户拥有之间无法读取或滥用该设备不在此 SE 的范围内,因为它与物理安全有关。我想做的一个说明是,如果设备可以在客户面前进行初始化,比如在客户监督下由供应商进行初始化,这可能会大大降低这种情况影响安全性的可能性。

编辑:对吉尔斯发表的言论的回应

服务器无法知道请求中发送的序列号是否真实

我阅读了 OP 的评论说“您可以假设这个问题已经生成了密钥并具有关联的标识符”作为“有一个包含 {serial-number, key} 对的数据库”。因此,服务器可以检查(做)序列号是否真实。

这意味着某些设备会因为某种原因而中断通信而被阻塞

我不确定如何解释这一点,但我将其解读为“如果在初始化期间通信中断,那么设备就会变砖”。我推测这将是工厂内部的网络,或者至少是同一家公司,因此不太可能出现通信问题(尽管可能,但确实如此)。顺便说一句,只有在向设备发送密钥期间通信失败时才会出现问题。当我说“这可能是制作过程的最后一部分”时,我并不是说这应该发生在公司网络之外,只是让它尽可能接近尾声是最安全的,对于任何沟通不畅感到抱歉。

它支持微不足道的 DoS 攻击,其中攻击者声称所有序列号

它确实允许对序列号进行 DoS 攻击。这是因为我假设安全性是这个设备的一个非常重要的问题,并且重置设备将是一个可接受的安全性权衡。但是,由于您需要首先破坏公司的内部网络,因此我认为这风险不大。然而,攻击者仍然需要猜测正确的序列号,并且给定一个相当长的序列,命中率应该相当低,因为我们知道生产能力,因此可以限制服务器的查询限制作为额外的安全措施。

它还允许“仅一次”规则无法阻止的相当广泛的模拟场景,例如:公司订购 100 台设备,提供 90 台设备并保留最后 10 台作为备份;攻击者冒充这 10 个设备中的一个,并获得该公司记录为属于其合法设备之一的密钥。在设备离开制造商的安全供应链之前,您需要配置一个密钥(不一定是最终客户将使用的密钥,它可以是一个临时配置密钥)。

我应该明确表示“初始化”应该在公司安全网络中进行。作为生产过程的一部分或作为销售的一部分(我假设是公司的一部分,但在我的“注释”中没有明确说明)但我在“注释”中确实说过供应商确实必须初始化设备(在客户的监督下)。因此,不应发生客户未初始化设备的任何情况。

我不认为这个问题是可以回答的,因为它非常笼统,并且没有说明设备制造过程、分销过程或设备功能。

我确实同意,鉴于这个问题的一般性质,无法给出最佳(或非常好的)解决方案。我提供的解决方案在可能需要重新编程序列号(或根据实施情况而变砖的设备)的可能性方面存在固有成本。但这是为了在不影响安全性的情况下提供一般性答案。我相信更好的解决方案将涉及 PKI 进行客户端身份验证,但 OP 禁止这样做。

存在实现深度安全性的 SoC(片上系统),具有以下特性:

  1. 板载加密引擎
  2. 一次性可编程 (OTP) 存储器
  3. 安全引导加载程序(通常通过 UART 访问)
  4. 唯一的嵌入式芯片序列号

安全性通常通过以下方式实现:

  1. 制造商,在这种情况下是您的公司,在适当的深度安全环境中创建主密钥对。(您可以选择拥有多个主密钥对,每个销售区域、配置或其他任何一对,以遏制违规行为。)
  2. 仍然在深度安全环境中,使用主私钥对固件进行签名。
  3. 签名的固件和主公钥从深度安全环境导出到生产线。
  4. 在生产线上,主公钥被写入 SoC 上的 OTP,并且...
  5. ...固件使用安全协议传输到 SoC,该协议在引导加载程序中实现,用于检查签名。
  6. 嵌入式软件现在可以使用 SoC 的加密引擎和 SoC 的唯一序列号来生成对称密钥(或者更好的是:非对称密钥对)。
  7. 然后从芯片发送芯片的序列号和公钥并存储在服务器的数据库中。
  8. 服务器通过向芯片发送一些消息(随机字符串)的密码来对芯片进行身份验证,该密码使用芯片特定的公钥进行编码。芯片返回解码后的信息,服务器将其与原始信息进行比较。

我认为最好的工业可用技术是使用符合 ANS X9.24 标准的每个事务的派生唯一密钥(https://en.wikipedia.org/wiki/Derived_unique_key_per_transaction)。

单个 BDK(基本派生密钥)能够促进 500,000 台设备。因此,通过拥有多个 BDK,您可以支持数以百万计的设备,这些设备能够为要加密数据的每个实例使用唯一密钥。

您可以将 BDK 存储在工业用 HSM(硬件安全模块)中。相同的 HSM 也可以编程以将 IPEK(初始密钥)注入所有设备。

这是一种在金融业中用于将密钥注入其支付设备的技术。

您提到的两个要求(使用唯一和具有序列号来识别设备)将通过使用上述标准来满足。

您的设备可能需要安全内存(存储安全密钥)和防篡改功能,以确保设备永远不会泄露密钥。

如今,我们正在开发需要您强调的上述要求的类似产品(支付设备),我们使用上述技术来实现它。

让固件在第一次启动时生成一个随机私钥,并将其存储在一次写入内存中。然后,设备需要与配置服务器通信,通常是通过网络,但您可以使用 UART 引脚将其关闭,具体取决于您的工作流程。将公钥连同处理器序列号一起发送,并让服务器签署序列号和公钥。固件可以验证签名,然后将序列号和签名存储在一次写入内存中以完成配置过程。(用于配置的公钥可以是固件映像的一部分,无需刻录。)

椭圆曲线加密对此很有效,因为密钥很小并且生成很简单。如果您在上述过程中使用 Ed25519 和 32 位序列号,则只需 100 字节的一次性写入内存即可获得完整的预配包。

如果您想要一个完整的 X.509 证书基础架构,您也可以实现它:只需让供应服务器确定性地构建证书。静态设置有效日期,使用设备序列号作为证书序列号,并使用一组预先确定的扩展(可能只是基本约束)。固件可以计算除签名之外的关于证书的所有内容,并将其从一次性写入内存中插入,瞧,您拥有证书基础架构,并且可以将 TLS 用于更高级别的操作。唯一的缺点是您不能将 Ed25519 与大多数 TLS 库一起使用,因此您必须使用 ECDSA 而不是 P-256。

从这一点开始,您可以通过 TLS 连接传输任何机密信息来引导它们的配置,并且设备可以安全地存储机密信息。这可以通过为每个文件生成一个新的临时密钥对、使用 ECDH 导出一个对称文件加密密钥以及将临时密钥对的公钥与加密文件一起存储来实现。(这提供了前向保密。您永远不想直接使用存储的私钥进行加密。)

该系统的美妙之处在于设备正在请求密钥,而不是您每次都注入它,从而简化了固件刷新。如果您想要最大的安全性,请让它通过物理连接(UART,或只是位 GPIO)向编程计算机发出请求,但它比注入密钥更安全,因为程序员无法在设备完成后模拟设备规定。

另一个好处是设备存储了所有需要的状态。没有可能丢失或受损的大量密钥和序列号数据库,只有每个处理器序列的设备序列列表,甚至可以在配置后删除。