应用场景:无网络情况下。 管理员生成一个指定使用次数的密码(时间无限制),达到使用次数后失效. 用户拿着这个密码就可以开启房门。
也就是说管理员控制的密码生成程序和门上的控制程序产生的密码要对得上,才能打开。
想不到怎么实现,有没有大神指点一下?
这个是别人已经实现了的功能。 APP端和门这边没任何通讯,即可实现密码检测、开门。
1
546669204 2018-01-03 13:43:57 +08:00
如果不要求多门共享次数的话还是比较容易的
明文密码 (我是密码,快开门呀,我只能用 X 次,我在 2018 年 1 月 3 日 13:40 生成) 然后通过加密编码压缩等等操作获得一段 key 房门上的程序进行各种解码 然后效验密码 和判断打开次数 就可以了。 |
2
geelaw 2018-01-03 13:59:17 +08:00 via iPhone 3
考虑一个不可伪造( existential unforgeability )签名系统,管理员和门分别可以产生和验证签名,管理员如此产生开门密钥:
选择一次性随机串 r,选择初始次数 k,产生 (r, k) 的签名 s,把 (r, k, s) 作为钥匙。 门如此管理密钥: 接到 (r, k, s) 的时候,先验证 s 是 (r, k) 的签名,如果不是有效,则拒绝。 接着查看内部表格里面是否有 r,如果没有,设置 r 的剩余开门次数是 k。 重新查看内部表格里 r 的开门次数,如果是 0 则拒绝,否则减少一次开门次数并开门。 当然楼主对这个模型的定义不是很完善,所以无法形式化证明这个构造是安全的——比如我得知道“安全”是什么意思。 |
4
takato 2018-01-03 15:30:32 +08:00
@geelaw 这样把门记录 remaining_r 的数字 hack 掉就知道了,感觉这个 remaining_r 也要加入加密体系中才可以。
|
6
akira 2018-01-03 16:28:45 +08:00
控制程序 预先创建一定数量的密码和次数限制,管理员这边挑个没用过的给用户就是了
|
7
geelaw 2018-01-03 16:35:17 +08:00
@takato 没理解您的意思——我假设门的系统是不能被改换的,否则不妨不直接让门自己开开就好。如果您仍然觉得这个方案不是看似可行的,是否可以形式化描述一下如何攻击?
|
8
neosfung 2018-01-03 16:42:13 +08:00
https://jwt.io/
可以考虑使用 jwt,在 payload 中添加一个字段表示初始次数。 第一次读取的时候获取初始次数,并写入系统。以后每次读取时,检索到已经存在这个 jwt,就直接将次数减一。 #2 的是简单的流程 |
9
takato 2018-01-03 17:30:29 +08:00
|
10
hugee OP 忘记说一点很重要的了:门上只能输入 0 到 9 的数字和*#
|
11
murusu 2018-01-03 17:56:18 +08:00
@takato 能 hack 掉 remaining_r 的数字证明系统已经被完全入侵,对在这种情况下能保住系统安全我表示怀疑,如果你真的有这种情况下的防护方案,我真想请教一下
|
12
takato 2018-01-03 18:25:05 +08:00
@murusu 我的意思是两边均不能保存 remaining_r 的明文,验证过程也不能取明文的 remaining_r..这里需要再思考下,但绝对不会是上文所述的直白方法。
|
13
TimePPT 2018-01-03 18:57:08 +08:00
如果不是非要按键输入的话,直接用门卡系统很好解决吧
|
14
msg7086 2018-01-03 19:00:31 +08:00
如果能 hack 进系统,说明你已经有足够的能力改动内部状态了。
那为什么不直接冻结内部状态,把有限次数认证转换成无限次数呢? 电脑上的软件,早就有人这么玩过了,破解方法就是用硬盘还原卡或者影子系统。 |
15
dream7758522 2018-01-03 19:00:52 +08:00 via Android
密码锁里面维护一个次数表,然后生成密码的时候将最大开门次数用某种方式加进入。
|
17
hugee OP 门上只是个单片机而已,不要把它功能和算力想得太高。生成的密码也仅仅只能是数字,并且位数不能太长,十位以上就影响体验了。
|
18
geelaw 2018-01-03 23:24:35 +08:00
@takato remaining_r 是什么?是指 (r, k, s) 对应的剩余次数,还是指 (r, k, s) 里面的 r ?
提醒:无论如何处理 (r, k, s) 里面的 (r, k) 这部分,也不能保证 (r, k) 是隐匿的——因为一个不可伪造的签名机制可以把 (r, k) 在 s 里面明明白白写出来。如果你想藏匿 (r, k),你必须用其他要求的密码原语。 |
19
hugee OP @dream7758522 这种方式完全不现实的。
|
20
wevsty 2018-01-03 23:28:45 +08:00
HOTP 就行了,用一次就失效
|
21
dream7758522 2018-01-03 23:46:53 +08:00 via Android
@hugee 为什么不现实
|
22
hugee OP @dream7758522 每个生成的密码都能指定不同的指定次数,每次生成的密码都不一样。想想就知道了……
|
24
hugee OP @geelaw 我说的是他的那种方式不现实。行业内已经有人实现了,我想弄清楚是怎么实现的。我电脑上有截图,明天我发出来给你看下。
|
26
geelaw 2018-01-06 16:19:30 +08:00
您可以试试手机开飞行模式之后建立新的密码,然后尝试解锁,看能不能做到。
|
30
Asshasahole 2018-01-07 12:22:28 +08:00 via iPhone
用时间和算法确定一个可用密码池,密码被使用时验证是否在可用密码池中,验证成功则生效并记录,已被记录的密码单独维护权限,可以通过手机与锁连接修改密码类型等。这种离线密码是以牺牲安全性为代价的,同一时刻可用密码有一定的数量,并且密码本身要包含类型等数据,位数会长一点。我有九成把握。
|
31
xiaosaiyin 2018-01-08 00:10:30 +08:00
随机数 r, 使用次数 k, 验证位 s
生成密码为 E( r k s, key) 验证时 r k s = D(m,key) 然后 检测验证位是否正确,这样可以隐藏(r,k) |