如何防止重播攻击
我正试图想出一种在微控制器项目上实现体面加密的方法。 我有一个基于ARMv4的MCU,可以控制我的车库门并通过WiFi模块接收命令。
MCU将运行一个TCP / IP服务器,它将监听来自Android客户端的命令,这些客户端可以从互联网上的任何地方连接,这就是为什么我需要实现加密。
我知道如何使用带共享密钥的AES来正确加密流量,但我发现很难处理重播攻击。 我目前看到的所有解决方案都有严重的缺陷。
有两个基本问题妨碍我使用像会话令牌,时间戳或随机会话这样的良好方法:
MCU没有可靠的熵源,所以我无法生成高质量的随机数。
攻击者可以通过切断车库电源来重置MCU,从而随意擦除任何存储的状态,并将时间计数器重置为零(或者等待49天直到它循环)。
考虑到这些限制,我可以看到只有一种方法对我来说似乎没问题(即我没有看到如何打破它)。 不幸的是,这需要非易失性存储,这意味着要写入外部闪存,由于各种技术细节,这会导致一些严重的复杂性。
我很想获得关于以下解决方案的一些反馈。 更好的是,我缺少一个不需要非易失性存储的解决方案吗?
请注意,这个项目的主要目的是教育。 我意识到我可以通过在防火墙内部设置安全的中继来简化这个问题,并让它处理Internet流量,而不是直接暴露MCU。 但那有什么乐趣呢? ;)
=建议的解决方案=
将使用一对共享的AES密钥。 将Nonce转变为CBC阶段的IV的关键之一,以及另一个用于对消息本身进行加密的关键:
Key
IV_Key
以下是我正在做的事情的图片:https://www.youtube.com/watch?v = JNsUrOVQKpE#t=10m11s
1)Android以毫秒( Ti
)(64位长)为单位的当前时间,并将其用作CBC阶段的随机输入以加密该命令:
a) IV(i) = AES_ECB(IV_Key, Ti)
b) Ci = AES_CBC(Key, IV(i), COMMAND)
2)Android利用/dev/random
生成MCU将用来回答当前请求的IV_Response
。
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
存储在外部闪存中。
这是否工作? 有一个更简单的方法吗?
编辑:它已经在评论中显示,这种方法容易受到延迟播放攻击。 如果攻击者记录并阻止消息到达MCU,那么消息可以在任何时候播放,并且仍然被认为是有效的,所以这个算法是不好的。
正如@owlstead所建议的那样,可能需要挑战/响应系统。 除非我能找到解决办法,否则我认为我需要做以下工作:
那个听起来是对的吗?
拥有IV_KEY
是不必要的。 IVs(和类似的结构,如盐)不需要加密,如果你看看你在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的时钟。 否则,你会遇到同步问题。