Click here to Skip to main content
15,063,239 members
Articles / Internet of Things / Arduino
Posted 15 Apr 2015


26 bookmarked

A Password safe built with Arduino Leonardo

Rate me:
Please Sign up or sign in to vote.
4.95/5 (15 votes)
15 Apr 2015CPOL4 min read
How to build a simple hardware password safe and login system with off the shelf components.


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.

Image 1

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.

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.

Image 2

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.

Image 3

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.

Image 4

#include <LiquidCrystal.h>

//Unlock key. U - Up, D - Down, L - Left, R - Right
char unlock[] = "UUDDLR";
//password descriptions
//static storage means it's stored in flash instead of ram
static char *desc[] = { "Facebook", "Gmail", "CodeProject" };
static char *keys[] = { "Password1", "Password2", "Password3" };
//number of passwords and descriptions
#define COUNT 3

int index = 0;
#define UP 0
#define DOWN 1
#define SELECT 2
#define RIGHT 3
#define LEFT 4

//Initialize LiquidCrystal lib.
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

//waits for a key press and returns it's identifier
int ReadKey()
  int x = 1023;
    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);

//initialize controller
void setup() {
  lcd.begin(16, 2); //16 chars in 2 rows
  lcd.setCursor(0, 0);
  lcd.print("Arduino Keylock");
  lcd.setCursor(0, 1);
  lcd.print("by Webmaster442");

//Wait for lock code
//Blocks further execution
void Unlock()
  int len = strlen(unlock);
  char c;
  int good, bad, i, count, repeat;
  count = 0;
  while (1)
    c = '-';
    good = 0;
    bad = 0;
    lcd.setCursor(0, 0);
    lcd.print("Enter unlock key:");
    lcd.setCursor(0, 1);
    i = 0;
    repeat = 1;
    while (repeat)
      int key = ReadKey();
      switch (key)
        case UP:
          c = 'U';
        case DOWN:
          c = 'D';
        case LEFT:
          c = 'L';
        case RIGHT:
          c = 'R';
        case SELECT:
          repeat = 0;
      if (unlock[i] == c) ++good;
      else if (repeat != 0) ++bad;
      if (i > len) break;
    if ((good == len) && (bad == 0)) return;
      if (count > 2)
        //lockdown mode
        for (int i = 30; i >= 0; i--)
          lcd.setCursor(0, 0);
          lcd.print("Stop guessing!");
          lcd.setCursor(0, 1);
          lcd.print("Wait ");
          lcd.print(" Seconds");
        count = 0;

void loop()
  lcd.setCursor(0, 0);
  lcd.print("Key: ");
  lcd.setCursor(0, 1);
  int key = ReadKey();
  switch (key)
    case UP:
      if (index < 0) index = COUNT - 1;
    case DOWN:
      if (index > (COUNT - 1)) index = 0;
    case SELECT:
      lcd.print(" - OK");

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.


  • 2015-04-15:  Initial Release


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Hungary Hungary
Been interested in computers & electronics since I got my NES, eventually became a Computer engineer, now a Software Architect

Comments and Discussions

-- There are no messages in this forum --