我正在开发一种用于两个微控制器之间无线通信的协议,使用433Mhz调制解调器,可以以原始格式发送串行数据(如果需要,可以发送纯文本)。我知道这听起来更像是一个电子问题,但我的问题在于编码部分,让我自己解释一下。
假设单位一发送此命令“0x001 / 0x010 / LIGHT1 / ON”(这是纯文本)到单元2,第一个是单元1名称,第二个是单元2名称,第三个是执行器,最后一个是动作。一切都好,工作,但我想给系统一点安全性,因为如果有人用“中间人”这样的技术听这个频率可以很容易地复制命令并在任何时候重新发送它想。
我正在考虑加密通过空中传输的消息,但是再次这不会保护系统免受同类攻击,假设我使用类似MD5的东西加密消息,我会传输类似的内容767b79ebb8061054d3ad1eaef428b469“,攻击者只需复制该字符串并重新发送即可获得相同的结果。
那我怎么解决这个问题呢?考虑到我不是在控制核反应堆,所以我不需要很高的安全性。
答案 0 :(得分:2)
我假设每个节点“知道”它应该从中获取命令的节点 - 在这种情况下,接收节点为它将从中获取命令的每个节点存储(简单)密钥,然后将三个字段添加到协议:
发送方和接收方都存储了tx-> rx关系的最后使用的序列号,发送方随每条命令增加了它。
发件人和收件人都会创建串联SequenceNumber+Command+SequenceNumber+salt+nodekey
修改: nodekey
是发送节点的密钥
发送方将此作为认证字段发送,接收方将根据认证字段对其进行检查,并仅接受该命令,如果序列号高于LRU序列号且认证字段检出确定。
这对重放攻击是安全的,因为它涉及序列号重用。
修改强>
关于序列号中同步丢失的评论存在担忧,但建议的解决方案可以解决这个问题:只有发送方会增加SN,接收方将接受所有SN高于上次使用的。丢失消息将使SN跳跃,但仍然会被接受为高于LRU。
答案 1 :(得分:1)
假设我使用像MD5之类的东西来加密消息,我会的 发送类似“767b79ebb8061054d3ad1eaef428b469”的内容,
您不使用MD5进行加密。您发送命令的哈希值。这意味着在接收端,您需要有一个反向查找表来映射您发送到相应命令的消息摘要。
攻击者只需复制该字符串并重新发送即可实现 同样的结果。
这是一个有效的问题,属于Replay Attack类别。有很多方法可以解决这个问题,但是需要相当多的努力来重新设计发射器和接收器
答案 2 :(得分:0)
由于您使用的是微型控制器,我认为您没有最先进的加密功能,而且易于实现的东西大多是最好的方式。
如果您的控制器上有可用的MD5,我会使用Eugen Rieck方法,除了我只想说,你只能使用每个键一次,比如说你发送的数据量是多少(取决于发送的数据量)。
这使得它已经更加安全,除非他们进行长期监听,否则他们将无法使用您的命令。
请记住,这是Security through obscurity的某些人,如果攻击者知道它只有10天的冷却,那么它将无效。
如果您的设备上有加密功能和有效时间,我只会使用当前时间的基本加密功能。
答案 3 :(得分:-1)
您应该考虑使用某种依赖密钥的加密方式。当然,关键可能必须以某种方式确定,两个控制器都可以保持同步 - 也许一些使用时间的方法就足够了。类似PHP的time()
函数,舍入到最接近的百位。每个控制器在获得信号时都可以检查当前的舍入时间戳和前一个时间戳,因此如果攻击者获得加密信号,则最多只能重复使用200秒。根据传输每个信号所需的时间和所需的安全级别(以及可能的频率,您可以使用丢失的信号离开),您可能需要十到五秒钟。使用一些伪代码(四舍五入):
发送:
signal=encrypt(outgoing, round(time, 10))
sendSignal(signal)
接收:
signal=decrypt(incoming, round(time, 10))
if (invalid(signal)) {signal=decrypt(incoming, round(time, 10)-10)}
interpretSignal(signal)
如第二行所示,您需要某种方法来确定解密信号是否有效。
这就是我想到的一个共同的密钥机制,应始终保持同步。但是,基本思想是使用频繁更改的密钥加密信号,发送者和接收者都知道或可以确定这些密钥。