【问题标题】:Best practices to protect over-air protocols保护空中协议的最佳实践
【发布时间】:2012-05-12 19:37:38
【问题描述】:

我正在为两个微控制器之间的无线通信开发一个协议,使用一个 433Mhz 调制解调器,它可以以原始格式(如果需要,可以是纯文本)发送串行数据。我知道这听起来更像是一个电子问题,但我的问题在于编码部分,让我自己解释一下。

假设一号单元发送这个命令“0x001/0x010/LIGHT1/ON”(这是纯文本)到单元2,第一个是单元1名称,第二个是单元2名称,第三个是执行器,最后一个是动作。一切正常,但我想为系统提供一点安全性,因为如果有人使用“中间人”之类的技术收听该频率,则可以轻松复制命令并随时重新发送想要。

我正在考虑加密通过空中传输的消息,但是这又不能保护系统免受相同类型的攻击,假设我使用 MD5 之类的东西加密消息,我将传输类似 之类的东西767b79ebb8061054d3ad1eaef428b469”,攻击者只需复制该字符串并重新发送即可达到相同的结果。

那么我该如何解决呢?考虑到我不是在控制核反应堆,所以我不需要非常高的安全级别。

【问题讨论】:

    标签: algorithm security md5


    【解决方案1】:

    我假设,每个节点都“知道”它应该从中获取命令的节点 - 在这种情况下,接收节点为它将从中获取命令的每个节点存储一个(简单)密钥,然后将三个字段添加到协议:

    • 盐(发件人创建的随机数)
    • 序列号
    • 身份验证字段

    发送者和接收者都为 tx->rx 关系存储最后使用的序列号,发送者每次命令都会增加它。

    发送者和接收者都创建连接SequenceNumber+Command+SequenceNumber+salt+nodekey的哈希(SHA1?)

    编辑:nodekey发送节点的密钥

    发送方将此作为身份验证字段发送,接收方将其与身份验证字段进行检查并仅在序列号高于 LRU 序列号且身份验证字段检查正常时接受命令。

    这对于重放攻击是安全的,因为它涉及序列号重用。

    编辑:

    cmets 担心序列号会失去同步性,但建议的解决方案对此具有弹性:只有 发送方 会增加 SN,接收方将接受所有 SN高于上次使用的。消息丢失会导致 SN 跳变,但仍会被接受为高于 LRU。

    【讨论】:

    • 我认为重要的是要考虑可能导致两端序列号不同步的数据丢失/损坏。
    • @Alex 我正在考虑这个
    【解决方案2】:

    假设我使用 MD5 之类的东西加密消息,我会 传输类似“767b79ebb8061054d3ad1eaef428b469”的内容,

    您不使用 MD5 加密。您发送命令的哈希值。这意味着在接收端,您需要有一个逆向查找表来将您发送的消息摘要映射到相应的命令。

    攻击者只需复制该字符串并重新发送即可实现 同样的结果。

    这是一个有效的问题,属于Replay Attack 类别。有很多方法可以解决这个问题,但您需要付出相当多的努力来重新设计您的发射器和接收器

    【讨论】:

      【解决方案3】:

      由于您使用的是微控制器,因此我假设您没有最先进的加密功能,而易于实现的东西通常是 imo 的最佳方式。

      如果您的控制器上有可用的 MD5,我会使用 Eugen Rieck 方法,但我只想说,您只能使用每个键一次,例如 10 天或其他时间(取决于您发送的数据量)。

      这使它更加安全,除非他们进行一些长期监听,否则他们将无法使用您的命令。

      请记住,这是某种 Security through obscurity,如果攻击者知道它只有 10 天的冷却时间,它就不会起作用。

      如果您的设备上确实有加密功能和当前时间,我只会使用基本的基本加密功能和当前时间。

      【讨论】:

        【解决方案4】:

        您应该考虑使用某种依赖于密钥的加密。当然,关键可能必须以两个控制器可以保持同步的某种方式确定——也许使用一天中的时间的某种方式就足够了。类似于 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)
        

        如第二行所示,您需要某种方法来确定解密信号是否有效。

        这是我想出的一种通用密钥机制,它应该始终保持相当同步。不过,基本思想是使用发送者和接收者都知道或可以确定的频繁更改的密钥对信号进行加密。

        【讨论】:

          猜你喜欢
          • 2017-11-16
          • 1970-01-01
          • 2017-07-12
          • 2016-10-20
          • 2020-01-16
          • 1970-01-01
          • 2011-06-27
          • 2016-03-10
          • 2020-09-21
          相关资源
          最近更新 更多