【问题标题】:How to protect against Replay Attacks如何防范重放攻击
【发布时间】:2014-10-27 10:07:07
【问题描述】:

我正在尝试找出一种在微控制器项目上实现体面加密的方法。我有一个基于 ARMv4 的 MCU,它将控制我的车库门并通过 WiFi 模块接收命令。

MCU 将运行一个 TCP/IP 服务器,它将侦听来自可以从 Internet 上任何地方连接的 Android 客户端的命令,这就是我需要实现加密的原因。

我了解如何使用带有共享密钥的 AES 来正确加密流量,但我发现很难处理重放攻击。到目前为止,我看到的所有解决方案都有严重的缺陷。

有两个基本问题阻碍了我很好地使用 已建立的方法,如会话令牌、时间戳或随机数:

  1. MCU没有可靠的熵源,所以无法生成 质量随机数。

  2. 攻击者可以通过切断车库电源来重置 MCU, 从而随意擦除任何存储的状态,并将时间计数器重置为 零(或等待 49 天直到它循环)。

考虑到这些限制,我只能看到一种方法似乎 对我来说没问题(即我还不知道如何打破它)。不幸的是,这 需要非易失性存储,这意味着写入外部闪存, 由于各种技术细节,这引入了一些严重的复杂性。

我很想就以下解决方案获得一些反馈。更好的是,我是否缺少不需要非易失性存储的解决方案?

请注意,此项目的主要目的是教育。我意识到我可以通过在我的防火墙内设置一个安全中继来简化这个问题,让它处理互联网流量,而不是直接暴露 MCU。但这有什么乐趣呢? ;)

= 建议的解决方案 =

将使用一对共享的 AES 密钥。一把钥匙将 Nonce 变成 CBC 阶段的 IV,另一把钥匙用于加密消息本身:

  • 分享消息Key
  • 分享IV_Key

这是我在做什么的图片: https://www.youtube.com/watch?v=JNsUrOVQKpE#t=10m11s

1) Android 以毫秒为单位占用当前时间 (Ti)(64 位长)和 使用它作为 CBC 阶段的 nonce 输入来加密命令:

a) IV(i) = AES_ECB(IV_Key, Ti)
b) Ci = AES_CBC(Key, IV(i), COMMAND)

2) Android 利用/dev/random 生成IV_Response MCU 将用于回答当前请求。

3) Android 发送[<Ti, IV_Response, Ci>, <== HMAC(K)]

4) MCU 使用 HMAC 接收并验证完整性,因此攻击者无法 修改纯文本Ti

5) MCU 检查Ti > T(i-1) 是否存储在闪存中。这确保了 录制的消息无法重播。

6) MCU计算IV(i) = AES_ECB(IV_Key, Ti)并解密Ci

7) MCU 使用AES_CBC(Key, IV_Response, RESPONSE) 响应

8) MCU 将Ti 存储在外部闪存中。

这行得通吗?有没有更简单的方法?

编辑: 在 cmets 中已经表明这种方法容易受到延迟播放攻击。如果攻击者记录并阻止消息到达MCU,那么消息可以在以后的任何时间回放,仍然被认为是有效的,所以这个算法不好。

正如@owlstead 所建议的,可能需要一个质询/响应系统。除非我能找到解决办法,否则我认为我需要执行以下操作:

  • 移植或实施一个体面的 PRGA。 (有什么建议吗?
  • 为 PRGA 预先计算大量随机种子值。每次 MCU 重启都会使用一个新种子。假设 128 位种子,16K 的存储购买了 1000 个唯一种子,因此在 MCU 成功使用至少一个 PRGA 输出值并重新启动 1000 次之前,这些值不会循环。这似乎还不错。
  • 使用 PRGA 的输出来生成挑战。

这听起来对吗?

【问题讨论】:

  • 有些东西告诉我,对于质询响应协议,您应该首先从门发送质询,然后 - 在特定时间范围内 - 接受质询。现在攻击者可以在他们到达门之前捕获加密命令并随时打开门(通过转发捕获的消息)。
  • 啊,在某个时间范围内,“接受(经过身份验证的)挑战响应”。
  • @owlstead 你是对的——我的算法似乎容易受到你描述的攻击。我正在考虑对每个请求使用挑战/响应方法,但这需要 MCU 能够选择唯一的 Nonce。这反过来又需要一个 PRGA,并且由于没有可用的随机性,它还需要一个预先计算的种子表,所以我们可以在每次重启时使用一个新的。我希望避免必须实施或移植 PRGA,但也许我毕竟必须这样做。我的想法是否正确?
  • 您可以只使用随机数作为挑战 - 挑战不一定是随机的,尽管它需要写入 EEPROM 来更新计数器(总是提前更新计数器我>)。也许使用挑战响应的Kerberos method

标签: security encryption cryptography aes


【解决方案1】:

没有IV_KEY 是不必要的。 IV(以及类似的结构,例如盐)不需要加密,如果您查看在 youtube 视频中链接到的图像,您会看到他们对有效负载的描述包括明文形式的 IV。使用它们是为了使相同的明文不会每次都在相同的密钥下编码为相同的密文,从而将信息呈现给攻击者。防止 IV 被更改的保护是消息上的 HMAC,而不是加密。因此,您可以删除该要求。 编辑:这一段是不正确的,见下面的讨论。如前所述,上述方法可以正常工作。

您的系统确实存在缺陷,即IV_Response。我假设,你将它包含在你的系统中,它有一些用途。然而,因为它没有以任何方式编码,它允许攻击者在没有 MCU 接收的情况下对设备的请求做出肯定的响应。假设您的设备正在指示运行小型机器人的 MCU 投掷球。你的命令可能看起来像。

1) Move to loc (x,y).
2) Lower anchor to secure bot table.
3) Throw ball

我们的攻击者可以允许消息 1 和 3 按预期传递,并阻止消息 2 到达 MCU,同时仍然做出肯定响应,从而导致我们的机器人在抛球而不被锚定的情况下被损坏。这确实有一个不完美的解决方案。将响应(应该放在一个块中)附加到命令中,以便它也被加密,并让 MCU 以AES_ECB(Key, Response) 响应,设备将对其进行验证。因此,攻击者将无法(可能)伪造有效响应。请注意,当您认为/dev/random 不可信时,这可能会为攻击者提供明文-密文对,如果攻击者有大量可使用的对,则可以将其用于密钥的线性密码分析。因此,您需要定期更改密钥。

除此之外,您的方法看起来不错。请记住,使用存储的Ti 来防止重放攻击是至关重要的,而不是 MCU 的时钟。否则会遇到同步问题。

【讨论】:

  • 在 CBC 中,即使 IV 是公开的,IV 也需要与攻击者无法区分。这是关于 CBC 的棘手问题之一。用不同的密钥加密 nonce 无疑是实现这一目标的好方法。
  • @owlstead 很有趣。分组密码不是我的强项,所以我只看到了一些关于它们的基本讨论,我当然没有看到你提到的弱点。我什至可以直接引用 Schneier(当然,他的 Applied Cryptography,这有点过时)“时间戳通常是一个很好的 IV”。 IV 必须与随机无法区分的原因是什么?
  • @owlstead 没关系,找到了nice SO answer。感谢您的提醒。
  • @SamuelJudson 我不确定攻击者如何对命令 #2 做出肯定响应。 IV_Response 与 Key 结合使用来加密来自我们假设的机器人的响应。是的,攻击者有 IV_Response,但是没有 Key,攻击者如何做出可以欺骗客户端的有效响应?
  • @SamuelJudson 哦,我明白了 - 我想我在第 7 步中不清楚。我的意思是说 MCU 使用 AES_CBC(Key, IV_Response, RESPONSE) 进行响应。
猜你喜欢
  • 2020-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-16
  • 2021-12-17
  • 1970-01-01
  • 2021-06-06
相关资源
最近更新 更多