简谈单车智能锁的攻与防

   哇 ,很久没有更新了啊。由各种各样的原因。一开始是因为要赶一个项目,后来是赶完项目太累休息了一段时间,然后是自己在摸鱼 感觉太舒服了,最后是因为电脑被抢劫(对的你没看错。我被抢劫了!!!下次有机会我会写一篇文的)终于,我在耽搁了这么久之后又想起了 啊 我竟然还有个博客。。。
  
   现在的共享单车形式呢,我感觉都已经要凉了,但是这个不管我的事情是吧..我就是个擦键盘的。关于为什么想写这篇文章,主要是因为萌萌给我看了[一篇关于小黄车的文章][1],看完这篇文章 我竟然都看懂了 ,(= =)甚至觉得这车锁还没我们做的完善啊(膨胀了。。其实也就多了几个步骤),因为自己也干了这个有一段时间了 所以就简单说说自己的理解吧。
[1]:http://news.mydrivers.com/1/554/554943.htm
  

初代的小黄

  这玩意不久是送的么?是个是我对初代小黄的第一想法。第一代的小黄车锁,是纯机械锁,也就是说锁本身没有(至少我没发现,或许有gps定位芯片?)与服务器链接,而是通过用户手机来定位用户在哪。在用户请求开锁时,服务器将该机械锁的密码告诉用户,然后用户完成手动开锁。
  既然是这样,那么大家也应该一下子就能想到,每一把锁的密码是固定的,你只需记下你曾经开过的 车号与之对应的密码,这辆车对于你就是免费的了。那么想“破解”他也就很容易了(这里并不是正真意义上的破解),自己做一个辅助app,每次开锁前先查询一下车id,如果已经有记录那么直接就返回密码;如果是新的车id,那么就在正常开完车之后,将其密码输入保存,达到一个小数据库的目的,根据用的人的数量 可以快速的记录大量车的密码。(共享单车 共享密码 。这个仅仅是我的一个想法,并未实现,因为这是 违法的!!! 虽然不清楚具体法律,但是一定会被告= =)

二代目

  小黄也许是在第一代上吃了比较多的亏,所以第二代很快就出来了,但是小黄的第二代(以及后面的的几代) 说实话我不是很清楚,因为提到了 也就稍微讲讲我的理解,有可能全是我的脑洞。二代变成了电子锁,但依然是手动输入密码,我没有验证过同一辆车的密码是否会发生改变。如果没有发生改变- -那么和之前一样;但是应该是会发生改变的(我倾向于这一点)这里又要分2种可能。
  第一种,车锁与 服务器采用了某一种 约定的算法。什么意思呢? 假如 一辆车的密码的 1234,那么这次用车结束(开锁 关锁 )后他的密码就会变, 怎么变呢? 变成 2341 (将第一位移到第四位置)。这样你 继续按 1234 这锁就不会开了。点了开锁,服务器会将新的密码告诉你 2341 ,并且在这次使用结束后 密码变成 3412 依次类推。 当然这个算法不可能这么简简单单的就移一位。。
  还有另一种可能就是,也就是类似于摩x,客户端(手机)像服务器发送开锁请求,然后服务器再像车锁发回指令来开锁(这样就是膜x 自动开锁),也就是说车锁与服务器 产生了直接联系,服务器通知车锁 变更密码( 但是这个可能是我的脑洞 我更加倾向于第一点 ),这样安全性就会比较高,难以破解,因为破解就相当于攻破了 他们的服务器。。。

蓝牙锁

  蓝牙锁为什么会开始使用呢??这个问题是我很好奇的。在我看来最完美的形式就是像膜x 那样的流程,点击开锁后,服务器验证通过,就告诉车锁 “我验证没问题 你打开吧”,这完全由服务器控制。也就是说 锁-服务器 之前是互动的 用户的手机仅仅是一个 “敲门的” 并不与车锁交互。题外话扯远了,蓝牙蓝牙,车锁的蓝牙和谁连接,显而易见是你的手机,千里迢迢之外的服务器怎么管得着你?
   之前萌萌给我看的那篇文章就说了一部分,我在简单的用大白话说一下流程:
   在蓝牙建立后,你开锁时首先要拿到一个token,这个token简单理解就是一个认证码,只有用正确的认证码才能完成操作。假如开锁的指令是 1234 ,那么 你开锁的时候 要告诉车锁的 就是 1234(指令,告诉他你该开锁)+ token(认证)。接着就是开展脑洞的时候了。
   怎么破解?使用蓝牙查询工具, 获取大量的 蓝牙通讯帧, 找规律,当发现每次开锁时 能发现类似的记录: 固定内容 + 可变内容时 ,那么这个固定的内容可能就是 开锁指令,而可变内容就是token令牌。 而要开锁就是 自己发送 指令+token就可开锁了。这个token 可以像初代小黄的密码一样 自己存起来。(我自己是没怎么干,那篇文章中看下来,小黄还是学不乖啊 每一辆车的token竟然不会变??那和初代有什么不一样?)
  首先 token 也就是令牌 必须得改变啊。在车锁中就应该 设置 token的生成规则 ,比如 token = 现在的时间+随机数+今天是周几+本车的id,那一定程度上就可以保证token的唯一性。接着,开锁时客户端与锁交互中 所有的通讯帧都需要 加密 解密,然后在验证这条指令。这样就算外部拦截了通讯帧也难以找到规律。