我试图想出一种在微控制器项目上实现体面加密的方法。我有一个基于ARMv4的MCU,它将控制我的车库门并通过WiFi模块接收命令。
MCU将运行TCP / IP服务器,该服务器将侦听来自可从Internet上任何位置连接的Android客户端的命令,这就是我需要实现加密的原因。
我理解如何使用带有共享密钥的AES来正确加密流量,但我发现很难处理重播攻击。到目前为止,我看到的所有解决方案都存在严重缺陷。
有两个基本问题妨碍我使用得好 已建立的方法,如会话令牌,时间戳或随机数:
MCU没有可靠的熵源,所以我无法生成 质量随机数。
攻击者可以通过切断车库电源来重置MCU, 从而随意擦除任何存储的状态,并将时间计数器重置为 零(或等待49天,直到它循环)。
考虑到这些限制,我只能看到一种方法 对我好(即我不知道如何打破它)。不幸的是,这个 需要非易失性存储,这意味着写入外部闪存, 由于各种技术细节,这引起了一些严重的复杂性。
我希望得到以下解决方案的一些反馈。更好的是,我缺少一个不需要非易失性存储的解决方案吗?
请注意,该项目的主要目的是教育。我意识到我可以通过在防火墙内部设置安全中继来简化这个问题,让它处理互联网流量,而不是直接暴露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
生成IV_Response
MCU将用于回答当前请求。
3)Android发送[<Ti, IV_Response, Ci>, <== HMAC(K)]
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所建议的那样,可能需要挑战/响应系统。除非我能找到解决办法,否则我认为我需要做以下事情:
这听起来是对的吗?
答案 0 :(得分:1)
不需要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的时钟是至关重要的。否则会遇到同步问题。