Introduction
Recently my website was hacked, due to my stupidity. I thought I was using a secure password, but clearly I wasn't. This incident made me rethink my password management strategies and I came up with a really simple
Arduino based password manager.
It's not a complete commercial full proof solution for various reasons. It's more like a proof of concept.
The hardware
The core of the hardware is an Arduino Leonardo. The Leonardo is built around the ATMega U32 microcontroller, that has hardware USB capabilities. Optionally an Arduino Due or Yún could be used, because the controllers used on that boards also has USB capabilities.
Other Arduino models are not suitable. Although every Arduino is programmed with USB, only the above mentioned models support USB natively. On boards, like the Uno a special USB-Serial translator chip is used, so it can't emulate USB devices like a keyboard or a mouse.
The key point here is keyboard emulation. The device stores login passwords for various sites in the microcontroller's FLASH memory, and with a single key press it enters the key into the selected password box. The device acts like a keyboard, and it will type the passwords letters into the selected password box very fast.
Because the device acts like a keyboard the solution is really platform free. It could be used under Windows, Linux, OS-X, or even Phones, and Tablets regardless of the operating system.
For the user interface I used an LCD keypad shield. It can be ordered from various sites. I got mine from a Chinese reseller on e-bay. For example you can buy it here. http://www.dfrobot.com/index.php?route=product/product&product_id=51
Each reseller has it's own version, so the look of the shield may vary, but they all work the same way.
The Shield features a Hitachi HD44780U compatible 16x2 Character LCD and 5 buttons. The LCD can be used with the built in LiquidCrystal library, which is good, because no additional libraries are required.
The other good thing about this shield is the buttons. They only use only one analog input, because they are wired like a voltage divider.
Using the code
The software is relay simple. At start-up the device will ask you for an unlock key. The unlock key is a sequence of key presses on the shield. It can be configured in the sketch, you can use any combination with any length. However there are only four keys used, so if you really want to use this as a full proof key vault then I recommend using 8 key presses or more.
For a precaution to make brute force attacks more harder it features a lock down timer. The Lock down timer is started when you enter 3 invalid unlock codes. It makes you wait 30 seconds, before you can try inputing the code agin. You can exit from this, by resetting the board, but it will take at least 5 seconds, because of the Arduino bootloader.
Theoretically, if your unlock code uses 10 key presses then the total number of combinations is 410, which is 1 048 576. Now, let's assume that your lock down code is very strong, so to crack it we have to try out every combination. Also let's assume that the attacker is very fast and can try a combination under 1 second, but on every 3rd combination he gets a lock down, so every 3rd combination takes at least 5 seconds, which means he can try 3 combinations under 7 seconds in theory. This means that the attacker needs at least 2 446 677 seconds to test all combinations, which is 28 days without sleep or stop. In conclusion this means that if your device gets stolen, you will have plenty of time replacing your critical passwords.
If you successfully unlocked the device, then you can choose the account with the up and down buttons. Pressing the select key will send the stored password to the computer.
#include <LiquidCrystal.h>
char unlock[] = "UUDDLR";
static char *desc[] = { "Facebook", "Gmail", "CodeProject" };
static char *keys[] = { "Password1", "Password2", "Password3" };
#define COUNT 3
int index = 0;
#define UP 0
#define DOWN 1
#define SELECT 2
#define RIGHT 3
#define LEFT 4
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int ReadKey()
{
int x = 1023;
do
{
x = analogRead (0);
if (x < 60) return RIGHT;
else if (x < 200) return UP;
else if (x < 400) return DOWN;
else if (x < 600) return LEFT;
else if (x < 800) return SELECT;
}
while (x > 800);
}
void setup() {
Keyboard.begin();
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print("Arduino Keylock");
lcd.setCursor(0, 1);
lcd.print("by Webmaster442");
delay(2000);
Unlock();
}
void Unlock()
{
int len = strlen(unlock);
char c;
int good, bad, i, count, repeat;
count = 0;
while (1)
{
c = '-';
good = 0;
bad = 0;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter unlock key:");
lcd.setCursor(0, 1);
i = 0;
repeat = 1;
while (repeat)
{
int key = ReadKey();
delay(200);
switch (key)
{
case UP:
c = 'U';
break;
case DOWN:
c = 'D';
break;
case LEFT:
c = 'L';
break;
case RIGHT:
c = 'R';
break;
case SELECT:
repeat = 0;
break;
}
if (unlock[i] == c) ++good;
else if (repeat != 0) ++bad;
lcd.print(c);
++i;
if (i > len) break;
}
if ((good == len) && (bad == 0)) return;
else
{
++count;
if (count > 2)
{
for (int i = 30; i >= 0; i--)
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Stop guessing!");
lcd.setCursor(0, 1);
lcd.print("Wait ");
lcd.print(i);
lcd.print(" Seconds");
delay(1000);
}
count = 0;
}
}
}
}
void loop()
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Key: ");
lcd.setCursor(0, 1);
lcd.print(desc[index]);
int key = ReadKey();
delay(200);
switch (key)
{
case UP:
--index;
if (index < 0) index = COUNT - 1;
break;
case DOWN:
++index;
if (index > (COUNT - 1)) index = 0;
break;
case SELECT:
Keyboard.print(keys[index]);
lcd.print(" - OK");
delay(1000);
break;
}
}
Further improvement possibilities
The project can be expanded in various ways. The most important improvement is to make it anti tampering safe. A good start at this is to find an enclosure that fits the components and once it's placed fill the electronics and it with a two component epoxy. Optionally hot glue can be used, but I don't recommend it, because it becomes a liquid if you heat it up.
Another improvement possibility is to add a serial SRAM memory for password storage. I recommend a SRAM because you can implement additional anti tampering mechanisms. For example a switch, which is activated when someone tries to take apart your device. The switch then disconnects the SRAM from backup battery, so the passwords contained in the are RAM are destroyed.
For this function to work really well a computer program could be made, which would make managing the passwords and accounts simple.
A security bug
This solution has a problem. It's vulnerable against software key-loggers, because it acts like a keyboard. This problem can be solved with a different password transfer solution, but it would require a special software on the computer.
History
- 2015-04-15: Initial Release