This project was created as a means to add location-based security by a dedicated 2FA device. I also did it for a school project, so check out [the report I wrote](Two-Factor Authentication with a Dedicated Hardware Device.pdf) for lots of extraneous words, pictures, libraries used, and extra info.
- Arduino Uno
- DS3231 RTC module: http://a.co/eDsdnLE
- MAX7219-driven 7-segment display matrix. Currently configured for this 8-digit matrix: http://a.co/1kaq6FC
- Arduino IDE: https://www.arduino.cc/en/Main/Software
- Python 3
- Create a virtualenv:
virtualenv env
- if virtualenv isn't installed:
pip install virtualenv
- if virtualenv isn't installed:
- Activate the virtualenv:
env\Scripts\activate
(or, preface each command withenv\Scripts\python
) - Install dependencies:
python -m pip install -r requirements.txt
- Choose a random 10-character ASCII password, for example:
k30asvb6yd
- Using the OTP tool at https://www.dylanpraul.com/tools/otp/
- Put whatever you want into the account name, for example:
My App
- Enter your secret key into the box
- Click go
- Replace
hmacKey[]
intotp_interface\totp_interface.ino
with the contents of the Arduino HEX array box. For example,k30asvb6yd
results in{0x6b, 0x33, 0x30, 0x61, 0x73, 0x76, 0x62, 0x36, 0x79, 0x64}
- Copy your password to
SECRET_PASSWORD
inserver\2fa.py
- Optionally, use the Google Authenticator app to scan the generated QRCode. This can be used to verify functionality later.
- Put whatever you want into the account name, for example:
- Wire up the DS3231
- GND to Arduino GND
- VCC to Arduino 3.3V
- SDA to Arduino A4
- SCL to Arduino A5
- Wire up the 7-segment displays (these can be changed in the top of
totp_interface.ino
)- GND to Arduino GND
- VCC to Arduino 5V
- DIN to Arduino D12
- CLK to Arduino D11
- CS/LOAD to Arduino D10
- Connect the Arduino to a computer using a USB cable.
- In the Arduino IDE, go to Tools--> Port--> Select the COM port that the Arduino UNO is listed in.
- Replace
port
insync_time\sync_time.py
with the port (e.g.COM4
) from the Arduino IDE - Also copy this port to
port
inserver\2fa.py
- Use the Arduino IDE to upload
sync_time\sync_time.ino
to the device. - Run
env\Scripts\python sync_time\sync_time.py
to set the RTC module to the current system time. - Use Arduino IDE to upload
totp_interface\totp_interface.ino
to the device.
The 7-segment display matrix should now be displaying the 6-digit TOTP.
An example Flask 2FA server is provided that can either match TOTP keys with the device or from a saved secret.
If the Arduino is connected to the computer, change USE_DEVICE_COMMUNICATION
in server\2fa.py
to True
.
Otherwise, leave it set to False
. Enabling this feature allows the server to gather the 2FA token from the
hardware device instead of by using the Python implementation.
- Run
cd server
- Run
python 2fa.py
to start the server at http://127.0.0.1:5000 - The password is
password
. Enter the displayed TOTP token to accesssecret.html