Random USB password manager using digispark

The ‘digispark’ is a small cheap development board based on an ATTiny85 microprocessor. It includes all the hardware for connection directly to USB, is USB powered, and comes ready flashed with a bootloader that allows programming via avrdude over the USB connection leaving about 8kB of program memory for use. There are libraries available to have the device act as most common USB profiles including HID devices like keyboards, mice, gamepads etc.

We can use the digispark as a keyboard device to type directly into a computer as computers will trust any device plugged in that announces itself as a keyboard. The digispark has 6 input digital input pins, however pin 1 is connected to the on board LED (can be disconnected), and pins 3 and 4 are connected to the USB lines so cannot be used at the same time as USB, leaving us only 3 pins for digital inputs. With a few diodes we can multiplex 6 buttons to the three inputs to make a keypad.

If we want to generate a random character we can use the arduino libraries pseudo random(max,min) function, this will give us a random number between limits (for example for printable ascii characters we could use 33 and 126). The pseudo random number sequence is initialised by calling randomSeed(seed) with an unsigned long value, commonly a source of randomness is used like an analog read from an unconnected pin but in this case if we can choose a repeatable number then each time we run we will get the same ‘random’ sequence, so by providing known inputs to randomSeed() we can generate sequences of pseudo random ascii characters to be used as passwords and recall them by providing the same seed.

Using a 6 key keypad gives us 5^n different possible codes (where ‘n’ represents the number of digits in the code). So a 4 digit code would give us 625 possible codes, 5 digits gives us 3125, and 6 gives us 15125 possible. As the random seed is an unsigned long value (2^32) we multiply the inputted code value by an amount to spread the seed value across the full range of possible seeds.

If we just use the number generated from the code then it would be easy to create a wordlist to brute force the generated passwords (even using 6 digit codes the wordlist would only need to be 15125 words), so we can also add some offset to move the seed to a slightly different place in the sequence – this offset value would need to be added at compile time rather than included in the source to protect it, and could also be changed for different devices to give different passwords for the same codes. Even with the offset we could generate a wordlist for each random seed, there are 2^32 possible seeds, and the actual pseudo random sequence used by the arduino libraries is about 2^31 numbers long ( just over 2 billion numbers), we can complicate this further by adding another variable to be set at compile time which will offset or alter the generated ascii codes before sending them making brute forcing effectively useless as long as we generate long enough passwords with enough entropy.

The device can be plugged in to any USB port and when a password needs to be entered we just type in the code and the device sends the keypresses to the computer and types it for us, we don’t need to remember the complicated passwords only the simple 5 or 6 digit codes, and we can use a different code for different things – each code will always generate its own unique ascii string.