4字节认证问题

信息安全 验证 hmac
2021-09-06 02:19:38

我有一个经典的安全问题,Alice 需要向 Bob 证明它的身份,但由于M2M 上下文而具有非常不寻常的要求和约束。

粗体字编辑

Alice 和 Bob 之间使用的通信通道具有以下特点:

  • 只有 Alice 可以向 Bob 发送消息(Bob 不能与 Alice 交谈)
  • 来自 Alice 的消息长度为 4 个字节
  • Bob 在收到 10 条消息后 10 分钟内停止收听
  • 如果可能,Alice 必须仅使用一条消息来证明其身份

其他具体要求是:

  • Alice 的 CPU和内存资源较低,Bob 的 CPU和内存资源较高
  • 消息必须包含 Alice 身份,但无需隐藏
  • Bob 实体的数量不限
  • 有 < 4000 个像 Alice 这样的实体可以向任何 Bob 进行身份验证
  • 必须合理地防止重放攻击(在发射后的几分钟内可以进行重放,但不能超过)
  • Bob 可以被蛮力愚弄,只要对手需要时间(即几天的计算或消息重试)

这是我为 Alice 4 字节消息想出的:

bits 1-20 = truncate(HMAC(date.format(dd/MM/yy hh:mm)),20) 
bits 21-32 = Alice ID (12bits = 4096 IDs)

当 Bob 收到消息时,如果我们允许 Alice 和 Bob 的时钟之间存在 X 分钟的偏差,Bob 会计算

truncate(HMAC(date.format(dd/MM/yy hh:mm)),20)

接待前后 X/2 分钟。因此对于例如 X=10 分钟,Bob 计算 10 个值。如果这些值之一与 Alice 发射匹配,则 Alice 被认证。

对手有 X / 2^20 机会随机生成好消息。由于 Bob 每 10 分钟只听 10 条消息,如果我的数学正确(对于 X = 10 分钟),这平均需要大约 73 天,这很好。

在 X/2 分钟内可以进行重放攻击。

通过将 HMAC 截断为 20 位引入的更高的冲突机会不会损害私钥,也不会降低进程 AFAIK 的安全级别。

我是开发人员,而不是安全人员,我的解决方案是否合理,我的分析是否正确?你看到更好的吗?

1个回答

重要的是 Alice 和 Bob 在存储方面各自的能力。在您的情况下,您假设 Alice 或 Bob 都没有任何记忆;它们共享一个秘密值(用于 HMAC),但它们没有要更新的读写槽。另一方面,您还假设 Alice 和 Bob 的时钟相当准确(彼此相差几分钟)。

如果 Alice 和 Bob 有时钟但没有记忆,那么你的解决方案是合理的。你的数学有点不对劲:

  • 如果 Bob 允许X分钟的偏差,那么他将计算2X+1 个值,而不仅仅是X
  • 如果 Alice 的时钟提前X分钟,重放攻击最多可能持续2X分钟左右。

如果 Bob 有一些临时内存(RAM...),那么他可以通过记住过去2X分钟内收到的消息来进一步保护自己免受重放攻击:这样,Bob 可以检测到不太旧的消息(和旧消息)的重放会因为他们的年龄而被拒绝)。

如果 Alice 和 Bob 有永久的读写内存,那么他们可以使用计数器而不是时钟。这可以使硬件实现更容易(时钟需要恒定的能量供应,计数器不需要)。

但是,您的主要错误是您试图定义自己的协议。一般来说,这不是一个好主意。相反,您应该依赖现有的、经过同行评审的协议。因此,您希望使用HOTP(用于基于计数器的解决方案)或TOTP(在内部重用 HOTP 机制)。强烈建议您通读它们各自的 RFC(分别为RFC 42266238),它们写得很好。

(不过,你离得不远。你的提议非常接近 TOTP。但密码学很微妙,所以使用现有标准总是更好。)