我试图找出一种在微 Controller 项目上实现体面加密的方法。我有一个基于ARMv4的MCU,它将控制我的车库门并通过WiFi模块接收命令。
MCU将运行TCP / IP服务器,该服务器将侦听来自可从Internet上任何地方连接的Android客户端的命令,这就是为什么我需要实现加密的原因。
我知道如何使用带有共享密钥的AES来正确加密流量,但是我发现很难应对重放攻击。到目前为止,我看到的所有解决方案都有严重的缺陷。
有两个基本问题使我无法很好地使用
已建立的方法,例如 session token ,时间戳或随机数:
质量随机数。
因此可以随意擦除任何存储状态,并重置与
零(或等待49天直到循环)。
考虑到这些限制,我只能看到一种似乎是
对我来说还可以(也就是说,我还不知道如何解决)。不幸的是
需要非 Volatile 存储,这意味着要写入外部闪存,
由于各种技术细节,这带来了一些严重的复杂性。
我希望获得有关以下解决方案的一些反馈。更好的是,有没有我不需要非 Volatile 存储的解决方案?
请注意,该项目的主要目的是教育。我意识到我可以通过在防火墙内设置安全的中继来简化此问题,并让其处理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将用于回答当前请求。
3)Android发送
IV_Response
4)MCU使用HMAC接收并验证完整性,因此攻击者无法
修改纯文本
[<Ti, IV_Response, Ci>, <== HMAC(K)]
。5)MCU检查
Ti
是否存储在闪存中。这样可以确保记录的消息无法重播。
6)MCU计算
Ti > T(i-1)
并解密IV(i) = AES_ECB(IV_Key, Ti)
。7)MCU使用
Ci
响应8)MCU将
AES_CBC(Key, IV_Response, RESPONSE)
存储在外部闪存中。这样行吗?有没有更简单的方法?
编辑:注释中已经显示,此方法容易受到延迟播放攻击的攻击。如果攻击者记录并阻止了消息到达MCU,则消息可以在以后的任何时间播放,并且仍然被认为是有效的,因此此算法不好。
如@owlstead所建议,可能需要质询/响应系统。除非我能找到解决方法,否则我认为我需要执行以下操作:
那个听起来是对的吗?
最佳答案
不需要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,同时仍然做出肯定的响应,从而导致我们的机器人在抛 anchor 时抛 anchor 时损坏了它。这确实有不完善的解决方案。将响应(应该放在一个块中)附加到命令中,以便对其进行加密,并使MCU用
AES_ECB(Key, Response)
响应,设备将对其进行验证。这样,攻击者将无法(切实可行)伪造有效的响应。请注意,当您认为/dev/random
不可信时,这可能会为攻击者提供纯文本-密文对,如果攻击者拥有大量对,则可用于密钥的线性密码分析。因此,您需要定期更改密钥。除此之外,您的方法看起来不错。只需记住,使用存储的
Ti
防止重放攻击(而不是MCU的时钟)是至关重要的。否则,您将遇到同步问题。关于security - 如何防范重播攻击,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26585108/