车库开门器的质询/响应认证

信息安全 挑战-反应
2021-08-17 15:23:58

我正在构建一个基于 Arduino 的无线电车库开门器,为了保护它免受重放攻击,我想出了这个算法:

  1. 发送者发起通信
  2. 接收方发送一个随机的 32 位数字与密钥进行异或运算
  3. 发送者使用相同的密钥反转 XOR 操作,解决挑战(例如:挑战 ^ 2 - 5),XORes 并将结果与​​命令一起发送给接收者(gate up 或 gate down)
  4. 接收者将响应与它自己对挑战的计算进行比较,如果它们匹配,则执行命令。

我很好奇,上述步骤是否确保攻击者无法猜测响应?

2个回答

不。

让我们把它写下来:

  • C是挑战信息
  • R是响应消息
  • K是密钥
  • C = q ⊕ K其中q是一个随机数。
  • R = ((C ⊕ K) 2 - 5) ⊕ K,或者如果我们跳过解密步骤:R = (q 2 - 5) ⊕ K

攻击者可以看到CR如果攻击者然后异或这两个值:

C ⊕ R = (q 2 - 5) ⊕ K ⊕ q ⊕ K

由于我们与K进行了两次异或运算,因此我们可以删除这些操作。这为攻击者提供了以下信息:

C ⊕ R = (q 2 - 5) ⊕ q

在 32 位空间中,对于C ⊕ R的任何给定值, q只有几个值。事实上,这是一个非常简单的操作,只需要蛮力:只需尝试所有q值,直到找到所有匹配的值。

这为您提供了一些可能的q值,即随机数。由于C = q ⊕ K,只需为每个候选q计算C ⊕ q即可获得少量可能的K值。第二次重复这个过程,看看在两次运行中出现了哪个候选K值:这给了你K

我什至写了一个 PoC!

// our key!
int k = 0xBAD1DEA;

void Main()
{
    // output the key just so we can see it in the output
    Console.WriteLine("Key is: 0x{0:X8}", k);

    int challenge = GenerateChallenge();
    int response = GenerateResponse(challenge);

    Console.WriteLine();
    Console.WriteLine("Cracking the challenge and response...");

    // this is the attacker: they know only the challenge and respoonse!
    Crack(challenge, response);
}

int GenerateChallenge()
{
    Random rng = new Random();

    // I'm keeping the random number small-ish to avoid the c^2 operation from overflowing
    // this is just a limitation of the fact that .NET has sane integer types that don't wrap on multiplication overflows
    int q = rng.Next(0, 10000000);
    Console.WriteLine("I picked q={0}", q);

    int challenge = k ^ q;
    return challenge;
}

int GenerateResponse(int c)
{
    c ^= k;
    return ((c * c) - 5) ^ k;
}

void Crack(int c, int r)
{
    int c_r = c ^ r;

    // try all possible 'q' values.
    for (int q = 1; q < int.MaxValue; q++)
    {
        if ((((q * q) - 5) ^ q) == c_r)
        {
            // got a match, output it
            Console.WriteLine("q candidate: {0}", q);
            Console.WriteLine("k candidate: 0x{0:X8}", q ^ c);
        }
    }
}

样本输出:

Key is: 0x0BAD1DEA
I picked q=2847555

Cracking the challenge and response...
q candidate: 2847555
k candidate: 0x0BAD1DEA

“破解”过程在我的系统上花费了不到一秒钟的时间。


编辑:因为这显然不清楚:你没有对真实系统进行任何暴力破解。这种方法根本不涉及您向接收者发送任何数据。您只需使用软件定义无线电 (SDR) 坐在那里,捕捉车主打开车库门时产生的信号。然后,您从这些信号中提取挑战和响应值 - 它们是CR给定CR,您可以使用上述过程为该特定挑战/响应对计算一些可能的q值。在某些情况下你只会得到一个,在某些情况下你可能会得到 2 或 3。计算每个候选q的q ⊕ C获取候选K值的列表。如果你得到多个,等待他们再次打开他们的车库并捕获另一个CR对,重新运行该过程,并查看哪些候选K值第一次匹配 - 这将为您提供真正的K值。一旦你有了它,你就拥有了模拟真正的开瓶器设备所需的一切。由于您知道K的值,因此您每次都可以正确回复

首先,您需要一个密码函数,其输入和输出之间的关系不容易辨别。XOR 只是不会削减它。加密数据的一种缓慢但有效的方法是将 32 位值分成两半,H 和 L,并重复以下几次:

  • 用足够的字节填充 H 来为 DES、AES 或其他一些体面的方案(和密钥)制作加密块并对其进行加密。
  • 将 H 设置为 L 的旧值,并将 L 设置为 H 的旧值与加密块的 16 位异或。

如果使用上述方法并在其核心采用一种不错的加密方法,则结果将是一个安全的 32 位到 32 位映射。通过交换 H 和 L,执行上述过程,然后将它们交换回来,可以获得逆映射。

32 位有效负载有点小,但如果挑战从不重复,则可以提供合理的安全级别。这可以通过让发送者对已发送的质询数量进行终生计数,并将其用作要加密和验证的质询数据来实现。