Day 9740 用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

Comments

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

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

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

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

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

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

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

发表回复

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

 剩余字数 ( Characters available )

Your comment will be available after auditing.
您的评论将在通过审核后显示。

Please DO NOT add any links in your comment, otherwise it would be identified as SPAM automatically and never be audited.
请不要在评论中插入任何链接,否则将被自动归类为垃圾评论,且永远不会被提交给博主进行复审。

*