Day 3414 用Arduino制作RFID钥匙链

rfid_keychain

很多人对管理密码感到由衷的麻烦,在生物特征验证尚未完全普及的今天(好像迄今为止做的最好、最为人所知的就是专属于iPhone 5S起的Touch ID),假设服务商没有(被迫)采取明文存储密码的2B做法,那么密码太短可能很容易被猜解出来,而密码太长又很容易记不住,而且在输入时也很麻烦。

因此有许多基于软件的密码管理器出现了(如1Password),只要记住一个主密码,剩下的密码都由其负责管理,并且很多优秀的产品已经出了很多平台的版本,可以跨平台进行使用,然而这种方式仍然有一点局限性:

  1. 在程序无法运行的环境下无法使用,例如:使用TrueCrypt加密的系统分区,在开机时要求输入密码;
  2. 主密码是拥有一切的前提,换句话说,如果忘记了主密码又没有备份,那么所有的密码可能都要丢失掉;
  3. 很多人有对商业软件与生俱来的不信任,在米国的棱镜项目被揭露后尤其如此。

我一直觉得很奇怪,为什么没有一种硬件,将密码离线存储在诸如IC卡之类的外部存储设备上,在需要的时候只要读卡,就能能模拟真实的键盘将密码输入。经过一番搜索,发现这种东西可能早就有了,只是没有供个人使用的商业化产品出现,其中的一个例子就是Mooltipass。

Mooltipass是一款设计精良的硬件密码管理器,除了实现以上所述的功能外,还能在适合的环境下与插件配合进行自动登录、帮助用户生成强密码(并存储下来供下次使用)。当时看到这款产品时,它还处在早期研发阶段,后来上了Indiegogo众筹。我没有双币卡,而且看到众筹也晚了些,$80的价格对我来说也有点贵(虽然说真的,值这个价钱),并且关于International Shipping说得好像也不是很清楚,所以就这么错过去了。

后来我听说了Arduino这个电子积木,其使用一种近似C的语言进行编程,并且通过一些方式可以模拟USB键盘。虽然我不会写C,但懂一点C#,两者有共通之处,所以二话没说就买了一堆零件开始尝试。

在拖延症和急功近利心理的共同作用下,一共走了以下几个弯路:

  1. 买错型号:设计上我想让成品既能读卡,又能写卡,但买了一圈之后我才知道能同时模拟USB键盘并与SPI总线上的RFID读卡模块RC-522通讯的型号是Arduino Leonardo,等我终于意识到时,已经额外买了Uno和Nano了。
  2. 多买了许多零件:跟以上理由相同,一开始以为需要用V-USB去模拟USB键盘,所以电阻、稳压二极管等等买了一大堆,最后才买到真正需要的东西。

虽然造成了许多不必要的支出,但最终这个东西还是做出来了,只有两个基本功能:

  1. 读卡,并将解密后的数据模拟键盘输入。
  2. 写卡,将加密后的明文(最长16位)存储到RFID标签中。

真正用到的元器件成本如下:

  1. Arduino Leonardo R3(¥30)
  2. 3×4矩阵键盘(¥5)
  3. RFID读卡模块RC522(含2张S50卡)(¥18)
  4. 无源蜂鸣器1枚(¥4)
  5. 公对母杜邦线一堆(¥5)
  6. 10K单联电位器(¥0.5)
  7. 8.5×5.5cm面包板(¥4)
  8. 1602 蓝色背光LCD(¥8)

合计¥74.50元——这么一算好像也不便宜,但是如果从一开始就核算成本,以自己的惰性怕是永远也做不出来。

不过以后输入16位长的密码简单些了。

源码和接线方式就算了,写的太烂。

2015-08-16更新:由于我手太笨,一直学不会焊接,所以这东西的最终形态是:

封装形式为PBC,即Paper Box Container

注:所有评论将在审核通过后显示,请不要在评论内容的任何位置出现链接,否则您的评论将被自动移入回收站,且永远不会被复审。

All comments will be available after being manually reviewed, please do not include any links anywhere in your comment, otherwise your comment will be automatically deleted and are not eligible for review.

10 条评论

    1. @hcl
      你和我这种大闲人不同啊,我把这个放着吃灰,其它成就也不会有,你还有其它东西可折腾 ╮( ̄▽ ̄)╭

  1. 从硬件的角度来看,感觉这种方式完全不如把密码烧到MCU的内置FLASH里面,既省去了一堆外设又不会有数据丢失的问题,更新密码等操作通过串口通讯,连键盘都可以省了,还能在线升级MCU程序。。。烧写程序时把外界读取操作的所有接口都设为关闭就ok了。

    1. 您太高看我了,我头一次玩Arduino,不会那么多高级姿势。
      另外还有几方面的考虑:
      1、那个3×4矩阵键盘是用来输入解密KEY的,不多余,用来将RFID标签中存储的密文解密成明文,我可不想在卡片中存储明文数据(Mifare Classic S50本身的KEY保护并不安全,可以暴力破解)。
      2、一个RFID标签可以存储一个密码(目前的设计如果活用一下还可以在S50卡里写15个密码),但如果写在MCU FLASH里,最少也得加个小型键盘选择,或者说,您更青睐选择密码时也需要上位机通讯比较方便?
      3、不觉得拿出钥匙扣来刷一下,密码唰地出现在屏幕上(或者加个KEY_ENTER直接连回车都敲了)比点点点选半天然后“只是输入了密码而已”要帅么(被打

  2. 嘛,我的想法是串口作为一个输入输出接口,所有操作都可以通过命令的方式进行触发,以后如果有需要新的功能可以很方便地添加,如果设计得好的话,甚至可以通过串口添加自定义命令。键盘倒也是可以控制终端机器的状态,双重控制效果更好。
    至于说到的升级,是想着有需要添加下位机功能的时候,可以通过这个方式来升级程序而不用烧录工具,这样就不会破坏密码存储区域的数据。你甚至可以在指定区域存储一个中间密钥。【越做越复杂。。。
    想想,缺点可能就是万一MCU坏了,那么就完全丢失数据了。如果是用两块MCU设计(用片外FLASH很容易被暴力读取密文,不过如果真要暴力读取的话,怎么加密都无济于事)的话就不会有这问题了,其中一块用51就行。

    1. 所有操作都通过串口下发命令的局限性有二:
      一、在使用者的机器上,必须首先安装Arduino Leonardo的驱动,这在开发机上不是什么问题,但拿到别的机器上就不是很方便,要不再在Arduino上实现一个只读的CDROM分区存储各种版本的驱动?
      二、在无法安装串口驱动及/或运行自定义程序的情况下(例如:用这个小玩意去输入BIOS密码(这个场景把两个情况都包括了),不要跟我说BIOS密码可以用跳线清除这回事233)就根本无法使用,这样似乎也不好。

  3. 嗯,驱动是个很大的问题,搞这个就要出人命了,模拟成usb键盘更好(再低端的系统都包含键鼠驱动)。

    1. 这个对于Leonardo不是问题,因为接入系统后就会被识别成板子本身加一套USB输入设备。
      总之我对最大兼容性有考虑,肯定想得不全面,但可以满足几个常用的场景。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注