Introduction
This is my showcase article and I hope you find it enjoyable and informative.
First of all, I know that my extreme title (Never Type A Password Again) gets under a lot of people's skin because they believe it is 100% hyperbole. But, that's the fun of it.
And, it's really not just hyperbole. Not just. If you really build this device, you really don't ever have to type a password again. You also won't have to memorize passwords or make them up ever again either. More on that later.
First, A Picture of The Final Device
First of all, let me show you the Arduino-driven device that I am using so I never have to type a password again.
I know! It is a beauty, isn't it? All those wonderful wires! (There are 8 just for the data lines. Phew...). Form follows function you know and this thing does work great. It really does solve my problem.
What Does It Do?
- It will receive your password via Bluetooth and type it into your computer (to unlock your screen or log you in).
- It allows you to type a PIN that you set up and then it will type your password into your computer (to unlock your screen or log you in).
- Since this device is simply seen as a keyboard to the computer, there are no drivers to install on the computer. It's amazing. It also means that you can use it on Linux, Mac or Windows with no changes to anything. Just plug it into your USB port.
Watch It In Action At YouTube
I've created two YouTube videos to show the device unlocking my computer.
Solves CTRL-ALT-DEL To Show Login
I've even solved the challenge of your computer sitting on the "saver screen" where the login text box is not displayed yet. The device can send CTRL-ALT-DEL to your system to display the login. If you are using Bluetooth, you can unlock your computer as you're walking down the hallway to your computer.
I Hate Passwords: I Bet You Do Too
This all started because I hate passwords. I really do. I hate memorizing them. I hate making them up. I hate typing them on small devices (phones, etc.) with only my thumbs. If I could tell you the arguments I've had with my wife about what the password is for some bank account ("...and don't you type it wrong again or we'll get locked out!!!") you'd really understand.
Then one day, I noticed that you could hash any data. I wrote it all up in an article here on CP (Destroy All Passwords: Never Memorize A Password Again[^]) which got over 250,000 views in one week (now at over 374K views). Wow! That's because everyone hates passwords. But not everyone believed in my approach. That's okay. I just like how attempting to solve the problem has helped me think some interesting thoughts.
Must Be Available On All Platforms
That's when I decided to create the thing for myself. There's no better way to test out an idea than to create a usable prototype and start using it. However, if I were to convince others to use the thing, then it must be available on all platforms (Android, Windows, iOS, Web). That took a while but I did it and wrote it up in an article and released all code to Open Source via Github (and CP). See Users Hate Passwords (We're All Users): Never Memorize a Password Again[^] so you can get the Android, iOS, Web and/or WinForm code.
I Use It Every Day, But There's One Thing That Needed A Solution
I use the thing every day and multiple times a day. Once you use it, you'll wonder why you ever typed passwords. But, there was one thing that was a bit annoying.
If I didn't have my phone or other device running C'YaPass then I couldn't unlock my computer (because the password is 64 characters long and I don't have it memorized).
The Annoying Thing That Needed A Solution
If I have my phone, I just run the Android C'YaPass, generate the password and send it over Bluetooth and my computer is unlocked. But that was a bit of a pain. When I sit down to my computer, I don't want to have to pull out my phone and all that rigmarole* (WOTD).
*a lengthy and complicated procedure
The Dream of An Arduino Solution
Since I already had this Arduino device which was typing my password for me (via Bluetooth), I knew I should be able to simply add a number pad of some sort that would allow me to type a 4 or 5 digit PIN in and then the device would type my long password for me and my computer would be unlocked.
But, how would I do that?
I knew I could just add a number pad, but I wanted something a bit more flashy and I wanted to try using a touch screen anyways. I started looking around out there and found that you can get a TFT 320x240 touch screen for only about $16 USD.
Summary Of How It Works
If you watched the YouTube videos (above) then you know how it basically works, but I've also created a graphic overview that should give you a quick idea of what my device does.
Save button: You need a way to save your password to the device so it can type it for you. I've chosen to use the Arduino's EEPROM (Electrically Erasable Programmable Read-Only Memory). Once you've saved your password, then when you enter the correct PIN#, the Arduino will type that password into your Login textbox on your computer.
Send button: When you've typed your valid PIN #, you press this button and the Arduino will check that it is valid and type your password which was previously stored in EEPROM into the Login textbox for you.
PIN# button: The PIN# button allows you to change your PIN# at any time. Of course, the first time you use the C'YaPass Keypad, you'll need to set the value. Press the button, type your 4-digit PIN and you're ready to go.
CAD button: The CAD button sends the CTRL-ALT-DEL sequence to your computer to either get it to display the login textbox, or if you're already logged in, it will lock your computer for you.
The Components List
There are four main things you need to build out this project and run it:
- Arduino Pro Micro - Original Pro Micros from SparkFun are $20 each, but you can get one clone from Gikfun for only $7.98 (https://amzn.to/2Ki4kqr). Or you can buy a few at a time and get them even cheaper (buy 5 @ $6 per https://amzn.to/2Im66VK).
- 320x240 TFT TouchScreen (https://amzn.to/2tpPKXp) - A very nice touch screen and well supported by manufacturer.
- HC-05 Bluetooth module (https://amzn.to/2lAbuf3)
- USB Cable - USB 2.0 A-Male to Micro B (https://amzn.to/2tA48eX) - So you can connect the C'YaPass Keypad to your computer. The device gets all power from your USB port also.
If you want to build the prototype like mine, you will also need:
- Connector wires - I bought this really nice set of solid core connector wires that is great for hobby use: (https://amzn.to/2Ki9y5i)
- Breadboards - I've bought multiple sets of these (https://amzn.to/2Kf4tdX)
Now, let's talk about some of the things I found interesting while developing this project.
Why Do We Use the Arduino Pro Micro?
We are using a Pro Micro board instead of a Arduino Nano because the Pro Micro (aka Leonardo) uses a different ATmega microcontroller: 32u4 instead of the ATmega328P (used by Nano, Uno and many others).
What Is Special About the 32u4
The 32u4 includes support for keyboard and mouse libraries supplied by the Arduino IDE and the hardware supports the HID (Human Interface Device) standard so that when you connect it to your computer, the computer will instantly recognize it as a keyboard and/or mouse. That's why it is so easy to make this Arduino type on your computer for you.
The Arduino Types For You
Here's the code that runs when you press the [CAD] button on the screen.
if (b == 14){
Keyboard.press(KEY_LEFT_CTRL);
Keyboard.press(KEY_LEFT_ALT);
Keyboard.write(KEY_DELETE);
Keyboard.release(KEY_LEFT_ALT);
Keyboard.release(KEY_LEFT_CTRL);
Keyboard.write(KEY_RETURN);
}
The b
variable simply holds the integer value of the on screen button that was pressed.
The Keyboard.press()
, Keyboard.release()
and Keyboard.write()
methods are all provided by the Keyboard.h library which works with the 32u4 microcontrollers.
The press()
method is seen by the computer exactly as if the key were pressed on a real keyboard. Using press()
and release()
like this allows us to simulate all three keys (ctrl-alt-del) being pressed and released and then the write()
method sends in an <ENTER>
(aka return).
Imagine all the things you can do with that now! It's so easy using the 32u4 microcontroller.
Touch Screen Code
Now, the touch screen code is quite straight forward. It was provided by Elegoo (manufacturer of the TFT touch screen) at their great site. They provide a decent basic Arduino program that handles drawing the buttons and handling when a button is pressed.
I took that code and altered it for my purposes. I also broke up the code into functions where I had repeatable code. If you compare the download for this article to Elegoo's code^, you'll see I made a lot of changes.
Screen Saver: I'm Not Sure About TFT Screen Image Burn
If you know how Arduino Sketches are set up, you'll remember that they basically run a loop()
method forever.
If loop()
ends, then the Arduino program ends. It is similar to the old Windows SDK Message loop^ that was where everything in your program happened.
Well, inside that loop()
is the code that draws the buttons and the textbox that appear on the screen. However, I wanted to make the screen display nothing, if it wasn't being used. I figured this would save the screen from getting the image of those buttons burned into the screen (if this is necessary, I'm not sure) and I figured that way you didn't have to see that thing lit up all the time.
I added some code that checks to see if it has been more than 10 seconds since the screen has been touched, if it has been then it fills the screen with a black box. However, if the screen has been black and you touch it, then the screen should draw the buttons for you.
if ((millis() - lastTimeTouched) > 10000){
if (!needsRefresh){
tft.fillScreen(BLACK);
needsRefresh=true;
}
}
else{
if (needsRefresh){
DrawMainScreen();
needsRefresh=false;
p.x = 0;
p.y = 0;
}
}
The millis()
method is an Arduino library method that returns the number of milliseconds (unsigned int
) since the Arduino program started. I simply update the lastTimeTouched
(unsigned int
) each time the user touches the screen. Whenever it has been over 10 seconds since the user touched the screen, I call the tft
library method called fillScreen()
and fill it with the defined value for black.
A Bug I Fixed
At one point, the code would fill the screen with black every time through the loop because I didn't set a flag that it had already been filled. That made the touch screen extremely slow to respond to a new touch to draw the main screen with buttons again so I added the flag and now it is very responsive.
PIN Number: Storing In EEProm
The next interesting thing I did was to allow the user to create her PIN number and store it in the EEProm. The supplied library makes it quite easy to write and read to EEProm. However, you do have to manage the memory yourself and that means deciding what address you are going to write to and deciding how many bytes you are going to write.
4 Digit Pin For Now
For now, I'm just doing a 4-digit pin. I am storing that 4-digit pin at EEProm Address 0 (zero).
Oh, by the way, EEProm memory can be written to approximately 10,000 times so it is perfect for this type of thing. Even if we changed the PIN# once every day, we would be okay for 27 years. Also, there is a limited amount of EEProm but it is 1024 bytes which is plenty for us. The 4-digit pin will only take up 4 bytes. Later you will see that we also store the password we want the CYaPassKeyPad
to type into our login text box but that is also only 64 bytes (for a 64 character long password).
I am only doing a 4-digit pin and I'm not (yet) forcing you to verify your old pin to change it to a new one. I will implement that code soon and post it up when I do.
For now, when you click the [PIN#] button, the program will take the next 4 digits you type on the keypad and display them in the top text box and save them into a byte array. When you type the 4th digit, the program will clear the text box automatically and write the digits to the EEProm starting at Address 0.
Here's the code that handles the numeric buttons.
if ((b >= 3) && (b < 14) && (b != 12)) {
if (textfield_i < TEXT_LEN) {
textfield[textfield_i] = buttonlabels[b][0];
textfield_i++;
textfield[textfield_i] = 0; if (isPinChanging){
if (textfield_i-1 < 4){
pinValue[textfield_i-1] = buttonlabels[b][0];
}
if (textfield_i >= 4){
isPinDone = true;
writePinToEEProm();
ClearTextField();
}
}
}
}
When you press the [PIN#] button, the isPinChanging
flag is set to true
. That means each time through the loop()
when the user presses a numeric button, the value is saved in the pinValue
byte array so we can write it to EEProm. When the user presses the 4th digit, then the following code runs to save the data to EEProm:
void writePinToEEProm(){
if (isPinDone){
for (int i = 0;i < 4;i++){
EEPROM.write(i, pinValue[i]);
}
isPinDone = false;
}
isPinChanging = false;
}
I just iterate through the EEPRom addresses from 0 through 3 and write one byte (numeric keypad value) for each address.
Verify that Proper PIN# Is Typed by User
Once the PIN is set, then later when the user attempts to use the PIN# to unlock the computer, the program reads the bytes out of the EEPRom and compares that final value to ensure that the PIN# is correct.
The following method takes the PIN# the user typed before pressing the [Send] button and reads the EEProm to determine if it matches and returns a bool to the caller to let it know if it should type the password for the user and unlock the computer.
bool verifyPinValue(String pinAttempt){
String pin = "";
for (int i = 0; i<4;i++){
byte value = EEPROM.read(i);
pin+= (char)value;
}
if (pin == pinAttempt){
return true;
}
else{
return false;
}
}
You can see I'm using EEPROM.read()
to iterate through the first 4 bytes again. That value is compared to the user's input and the boolean is returned.
One More Thing: EEProm Solves It Again
Finally, there is one more thing that has to be done to use the CYaPass KeyPad. The user's password must be stored in EEPRom also so that when the user types the correct PIN#, the device can type the password into the login box on the Windows screen.
Now, I need to allow the user to store her password in the EEProm. First of all, note that this value stored in the EEProm will be stored as cleartext but I'm not worried about that for now because this is a physical device.
We Have To Consider Password Length
Because your password may be any length and we have to write the number of bytes to EEProm and then later read them out, we have to also write the length of the password to the EEProm. We have to do that because we have to know when to stop reading bytes from the EEProm when we are retrieving the password. EEProm memory can be initialized to any values and there's no way to know if the memory is something you want or not.
I set up two #DEFINED
values:
#define PASSWORD_LENGTH 100 // writing password size as a byte at RAM address 100
#define PASSWORD_BEGIN 101 // writing password as bytes begin at address 101
This gives me a clean way to reference the addresses where I write the length of the password (address 100) and where the password's first byte will be written in EEProm.
That way, later, if you have a password that is 17 characters, I read the value stored at address 100 and then know I need to start reading at address 101 and then read only the next 16 bytes beyond that first byte.
It's a little tricky because you have to do all that work yourself, but I've put it in a nice function that is easy to call:
String readPwdFromEEProm(){
byte pwdLength = EEPROM.read(PASSWORD_LENGTH);
String pwd = "";
for (byte i = 0; i<pwdLength;i++){
pwd += (char)EEPROM.read(PASSWORD_BEGIN + i);
}
return pwd;
}
How Do You Store the Password?
Right now, I have it working so that you take the following actions to store your password in the EEProm.
- Press the [Save] button on the CYaPass Keypad. At this point, the program is waiting for input from the Bluetooth device.
- Run Android CYaPass app (paired with the CYaPass Keypad) and press the Send button in the app.
- The CYaPass Keypad will receive the bytes, store them in the EEProm memory.
- It will put a small output statement that says "Got Serial" on the keypad.
- Press the [Save] button again to indicate that you are no longer sending data to the device to be saved in EEProm.
One More Thing
There is actually another way to store any password you want (instead of one generated by CYaPass app -- although you'll still need the CYaPass Android app).
All you have to do is type your password on your Android phone and then select it and copy it to the clipboard.
Once you do that, switch to the CYaPass app and press the [Send] button (circle with up arrow). When you do that, CYaPass will send whatever is copied to the clipboard over Bluetooth. That will write it to the CYaPass KeyPad.
The End of Typing Passwords?
You may not agree that this is the end of typing passwords but hopefully you agree this is a step in the right direction. I'm really using the thing on my desktop every day and loving it.
But, hopefully, you see that this article isn't just about destroying passwords (though I do want to destroy all of them). It is about thinking of new things to do with these powerful Arduino devices that are small, inexpensive and use a small amount of power.
Maybe something you saw here will stimulate your imagination and give you the boost to go and build the next big thing.
Keep on learning, keep on building.
Schematic For Wiring It Up
I had forgotten to add a schematic for wiring it up. It looks a little complicated but it's actually quite easy. Just make the connections in the following diagram and power it off your USB port and you're ready to go.
History
- 2018-06-24: First publication