离线临时密码的生成

前言

最近看到朋友家装了新的只能门锁, 可以使用指纹或密码解锁. 密码解锁没什么, 但其在手机端可以生成一个临时密码倒是引起了我的兴趣. 这个场景是这样的:

  1. 密码锁不能联网
  2. 生成密码时, APP与密码锁没有通讯(不在一起, 且密码锁不能联网)
  3. APP 和密码锁仅在首次配对的时候进行过通讯
  4. 临时密码有效期为30分钟, 从密码的生成时间开始计算
  5. 手机端可以多次生成临时密码, 每个都不一样且有效

那么问题来了, 密码锁是如何验证密码是否有效的呢?

实现方案思考

方案一: 预生成

思路:

  1. APP与密码锁在首次配对的时候, 预先生成1万个临时密码
  2. 每次获取临时密码时, 从预生成列表中获取下一个即可

问题:

  1. 密码无法与时间绑定, 无法实现"临时"的需求
  2. 密码用尽后需要重新配对

方案二: TOTP

思路:

  1. 基于动态密码 TOTP 方案实现
  2. 在配对的时候同步共享密码与计数器
  3. 计数器每30分钟+1

问题:

  1. TOTP为固定时间窗口, 无法实现动态窗口
  2. 计数器每30分钟+1, 无法多次生成临时密码

方案三: 增强型 TOTP

到这里其实已经有方案了, TOTP是固定窗口, 那多个固定窗口连在一起, 不就是个滑动窗口么.

思路:

  1. 仍然基于 TOTP 的方案, 在配对时同步共享密钥和计数器
  2. 计数器每5秒+1
  3. 密码验证时, 验证当前时间向前推30分钟的所有 TOTP密码, 若与其中一个匹配即为可用

若计数器每5秒+1, 则30分钟可产生的密码数量为: (30min / 5s)=360

这个方案是我想到能够满足此场景的. 优势:

  1. 双方无需存储密码队列, 无存储开销
  2. 能够把握30分钟的滑动窗口, 误差为5秒
  3. 每5秒可生成一个新的动态密码, 支持重复生成

潜在问题:

  1. 时间同步: 密码锁长时间无对外通讯, 时间同步可能产生误差. 可在每次通讯时调整, 或适当放宽验证的时间范围以平衡时钟误差
  2. 计算资源: 每次密码验证需要进行360次 TOTP 计算. 可考虑在密码锁中维护一个密码队列, 每5秒生成密码添加到队列中, 并将旧密码出队列. 这样验证密码的时候就不需要频繁计算了

以上, 就是基于这个场景进行的设想, 其具体是如何实现的俺就不晓得了.

订阅评论
提醒
guest
0 评论
最新
最旧
内联反馈
查看所有评论
0
希望看到您的想法,请发表评论。x