DIY USB password generator

Having done half a dozen V-USB tutorials I decided it’s time to whip up something cool. As USB keyboards were an area untouched, I decided to make a small USB HID keyboard device that types a password stored in EEPROM every time it’s attached. A new password can be generated just by tabbing CAPS LOCK a few times (4 times to start password regeneration and one tab for each password character generated, 10 is the default password length). Below you can see the device in action:

The place I work at requires me to change my password every few months so this would be one way to skip remembering a new password altogether (as long as I remember to write it down before regenerating a new one so password can be changed :).

What is inside?

The device is powered with a simplified version of the hardware I used in my ATtiny85 USB tutorial – I stripped away the LCD, reset pullup and both capacitors. If you’re better in cramming components inside enclosures I suggest adding at least a 0.1 uF capacitor between VCC and GND, but it seems to work fine even without it:


The enclosure was graciously donated by an old 512 MB flash drive. I couldn’t make myself to break the USB connector from the circuit board inside, so I stripped appart a short USB cable instead (shown on left):

After some thinking and iterative soldering, I managed to cram everything on a tripad veroboard with 2×8 pads with the following initial setup:

I soldered the connector first, then the zener diodes, then resistors and jumpers, and finally VCC, GND and the ATtiny itself. I used the following tricks to make all ends meet:

  • D+ zener diode goes to the pad under ATtiny that is connected to GND pin
  • After the D- zener diode, only 1 pad is left for 2k2 pullup and 68 ohm resistor, so I used a jumper wire to the next pad
  • 2k2 pullup goes to a pad connected to ATtiny VCC
  • VCC goes to the pad under the ATtiny using a black jumper wire
  • I soldered the D+ 68 ohm resistor to a wrong tripad, so I used another jumper wire just barely visible behind the top left black jumper wire for GND

I was pretty satisfied the result and the fact that it actually worked! The board did not initially fit into the very snug space in the plastic enclosure, so I had to use a Dremel to trim its insides a bit, but after that, everything snapped right back (click for larger versions):




Update: For those who are building this project – I recommend you first build it on a breadboard, and only when you have it working, solder it to a veroboard. Here are two additional, extra-large pictures of the configuration I used to help you in the component layout:


Software

The device presents itself to the computer as a USB HID keyboard. To enable communication to the device, it is a boot-compliant keyboard that can receive LED status changes from the computer. HID descriptor is from Frank Zhao’s USB business card example and I also looked at Frank’s code to understand how LED state is sent to the device (in short, PC sends a control message with 1 byte of data, the LED state bit mask).

The code is mostly based on my USB HID mouse example except for the usbsconfig.h and HID descriptor changes required to implement a boot keyboard. I’ve documented the code but here are some highlights if you want to understand it better:

  • PASS_LENGTH defined in the beginning controls the length of generated passwords
  • SEND_ENTER can be defined to 1 if you want the device also to send ENTER after typing the keyboard
  • measuring_message and finish_message contain the messages that are displayed when generating / saving a new password
  • buildReport() is called by the program main loop to send keypresses to PC one by one – it translates characters in messageBuffer to USB key codes on the fly
  • usbFunctionWrite() is implemented to receive the 1-byte LED state from PC – it calls caps_toggle() function every time the LED state changes
  • generate_character() is used to return random keypresses – it is currently written to return alphanumerics, hyphen and underscore (64 symbols make it simple to select one so each has equal chance of being selected without additional logic)
  • caps_toggle() does the caps-lock counting and password generation/saving

I’ve packed the source files with the schematic, critical pictures and a Makefile. In addition to “make flash” you of course need to update the fuse bits to use the PLL clock source – see details from my previous tutorial for that. I also very strongly recommend testing the device using a breadboard before soldering it, because otherwise reflashing will be a major pain.

And of course, if you build it, try it at your own risk – and remember that once you reprogram the password, nothing will be able to restore it. I recommend storing passwords generated with the device to a safe place just to be sure.

Update: Getting it from SparkFun

I found out yesterday that SparkFun is carrying an almost identical piece of hardware, the AVR Stick. So if you order one and reprogram it with this firmware (pin configuration in usbconfig.h needs to be updated in that case), you can avoid some soldering (although not all, you’ll likely need to solder in the programming header).

I asked SparkFun if they’d be interested to make a “2.0” model of their AVR Stick with actual USB connector and enclosure to go with the package, and my password generation firmware preloaded. If you think that’s a good idea, now would be a great time to send them feedback. I’d also be interested in covering additional hacks and tutorials with such a device. :)

Update 2: Indiegogo project

Alvin Chang is currently (December 1st 2012) running a Indiegogo project to build a device very similar (and inspired by) my DIY version. In case you’re interested in getting a ready-made version, be sure to check Mr. Chang’s project out: Aladdin: The Key to Your Computer.

Published by

Joonas Pihlajamaa

Coding since 1990 in Basic, C/C++, Perl, Java, PHP, Ruby and Python, to name a few. Also interested in math, movies, anime, and the occasional slashdot now and then. Oh, and I also have a real life, but lets not talk about it!

248 thoughts on “DIY USB password generator”

  1. What may be missing some drivers. Therefore, the computer sees the device as unknown. What drivers should be installed?

    1. The USB HID drivers should be available in every operating system, so no additional drivers should be needed here (in contrast with my USB tutorial device which does need drivers)

  2. Dear Joonas Pihlajamaa, can be laid out last revision of your project contains any error. Otherwise, what else can you explain the problems that occur not only at me one last time. Please refresh the files.

    1. Dear Ale XXX, I’m not sure what you are saying? If there are several people (including me) that got it working. If you have an improved schematic that does work better than the version presented, please share.

  3. sir how to change the password means what is logic behind this.
    if i change the password as you told then which logic is used to change password.

    1. The device measures the amount of time between caps lock presses – human reflexes are quite random so you can get several bits of true randomness with each press. See generate_character() comments in main.cc for details.

  4. Hello,

    I made it! Thank you, it works well with Windows XP and windows 7, it did not work with one of windows 8 but i cant tried with another windows 8 machine. when it comes to Linux (ubuntu 14.10) first two digit of password gone missing. It types 8 digits. why this behavior? i checked code what may encounter this issue but couldn’t find problem.

    1. It might be that Linux has a longer delay between the “keyboard” being recognized and starting to accept keypresses, so the first two characters are ignored. A longer delay would correct it if that is the case.

    1. Seems like usbconfig.h is not found. Which dev environment uses the .inc files? Arduino? I would make sure usbconfig.h is in the usbdrv directory, and if required by the dev environment, usbdrv is added to include path (and the .c and .S files to project)

  5. Please let me know if you’re looking for a article writer for your weblog.
    You have some really good posts and I believe I would be a good asset.
    If you ever want to take some of the load off, I’d absolutely love
    to write some material for your blog in exchange for a link back to
    mine. Please shoot me an e-mail if interested. Many thanks!

    1. Thanks! Also visited your blog, good work! By the way, never write short comments like this that have no context to the post you are commenting, I get 10 of these a week and all are just spam pointing to goldonlinenow.ch or something. Even with the sensible blog in your URL I was still only somewhat sure this might not be spam. :)

  6. I made this awesome thing for university project. But I have some problem. I test by plug it with many labtops but just a few laptop that the USB-driver can install successfully.
    How can I solve this problem ? I am stuck in this black hole for 2 weeks.

    Ps. I flash ATtiny85 by using HEX file you give in your project by setting fuse in PLL mode.

    Thank you very much !!

  7. Thank youuuuuuuu for your awesome article.
    I’ll try it but can you say which attiny85 you’ve used? because I’m new in electronic and it’s a bit hard for me to understand these things.

    1. I think they only make one model of the ATtiny85. :) For Attiny2313 Atmel has both normal and 10PU version (2313V), and the latter is limited to about 10 MHz – for those, the normal version is the one you should get.

  8. I have been trying to compile the C file that you provided in the source package. But I have been getting these errors.

    When I try to compile with the version of ‘usbdrv’ you provided, it gives me this error: http://cl.ly/image/3J1k2P1p0K3Z/error%201%20-%20old.png

    And when I try to compile it with the newest version of ‘usbdrv’ downloaded from the V-USB website, it gives me this error: http://cl.ly/image/3J1k2P1p0K3Z/error%201%20-%20old.png

    Please help.

  9. помогите мне, у меня распознается и сразу пропадает*((( как программировать МК?

  10. Hoooray!
    Finally!I get it working after three days.
    Here is the result:
    GMKjkQcLjQ
    GMKjkQcLjQ
    Starting generation…
    cLm9IqJSCT
    cLm9IqJSCT
    ^_^
    ———–THERE IS A BUT!——————
    But! when I touch the circuit(It’s on bread board).It disconnects and reconnects a few times (windiwos diling! sound) and then doesn’t work after.but when I touch it again and mess around with it, it works perfect!.
    I don’t know If you see what I’m trying to say or not.
    Anyway thank you for the great tutorial :)

Leave a Reply

Your email address will not be published. Required fields are marked *


7 × = forty two

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>