--- title: 'Multi-Factor Authentication Secure Access System for Safes' disqus: hackmd --- :::danger *Bareal Issa* ::: Tutorial on How to Build a Multi-Factor Authentication Secure Access System for Safes === [TOC] ## Title :::info Multi-Factor Authentication Secure Access System for Safes ::: ## Project Overview This project involves developing a multi-factor authentication secure access system for Safes using a Raspberry Pi Pico (W). The system utilizes an RFID reader, a keypad, an LCD display, LEDs, and a buzzer to control access to a Safe. The project incorporates security features such as a lockout mechanism after multiple failed attempts and sends notifications to a Discord channel using webhooks. Additionally, a Python Flask server is set up to handle unlock requests and display the Safe's status on a web page. This ensures that the Safe remains secure and the owner is promptly informed of any unauthorized access attempts. ## Time Requirements This project can be finished within (4-6 hours). ## Objective The motivation behind choosing this project is to create a secure, reliable, and convenient method of controlling access to valuable items stored in a Safe. The use of various components such as RFID, a keypad, and web-based notifications provides a modern solution that can be monitored remotely. This project also presents an opportunity to learn and apply various technologies, including hardware interfacing, web development, and network communication. The primary purpose of this secure Safe access control system is to enhance security by ensuring that only authorized individuals can access the Safe. The system requires both an RFID tag/card and a correct PIN, adding a layer of security. Additionally, the system notifies the owner of any unauthorized access attempts via Discord, allowing for immediate response. The Flask server also provides a web-based interface to monitor the Safe's status in real-time. This project also provides valuable insights into the integration of multiple technologies to achieve a robust security solution. It demonstrates how different components can be used together to enhance security and convenience. The project also highlights the importance of multi-factor authentication in securing valuable assets. Furthermore, it provides practical experience in setting up and using webhooks for real-time notifications and in building web interfaces to interact with physical devices. ## Materials | kit | Price | Purchased From | Image | | ----------------------------------------------------- | ------- | ----------------------------------- | --- | | Freenove Ultimate Starter Kit for Raspberry Pi Pico W | 699 SEK | [Amazon](https://shorturl.at/kBnzP) |![frennove](https://hackmd.io/_uploads/HyfyqchH0.jpg) Components used: | Material | Purpose | Image | | --------------------- | -------------------------------------------------------------------------------------- | ------------------------------------------------------------- | | Project Board | To mount and connect all components | ![project board](https://hackmd.io/_uploads/Sy_TZs2B0.png) | | Raspberry Pi Pico (W) | To control and process inputs and outputs in the project | ![rasperri pi pico](https://hackmd.io/_uploads/HJACZo3SC.png) | | LCD Module | To display information and outputs | ![LCD](https://hackmd.io/_uploads/SkNXzohB0.png) | | RFID Module | To read RFID tags/cards for identification or security purposes. | ![rfid](https://hackmd.io/_uploads/HkCZfjnHA.png) | | Keypad | To input data or commands into the system | ![keypad](https://hackmd.io/_uploads/ryvVMjnHR.png) | | Passive Buzzer | To emit sound for alerts or notifications | ![buzzer](https://hackmd.io/_uploads/BJZufihHC.png) | | 3 LEDs (R,G,B) | To indicate status or provide visual feedback | ![LEDs](https://hackmd.io/_uploads/rJ8tfj2BA.png) | | 3 Resistors (220) | To protect LEDs from damage | ![resistor](https://hackmd.io/_uploads/Hyaqfj2S0.png) | | Jumper Wires, Male to Male (21) - Male to Female (4) | To connect various components on the project board | ![wires](https://hackmd.io/_uploads/Syk3zinrR.png) | | USB Cable | To provide power and enable communication between the Raspberry Pi Pico and a computer | ![cabel](https://hackmd.io/_uploads/rkEm8s3rC.png) | ## Computer setup :::info **Prerequisite** 1) Download Python Interpreter from this website [Python](https://www.python.org/downloads/) 2) Run the installer and follow the on-screen instructions to install Python on your computer. ::: :::info ***Chosen IDE:*** * For this project, we will mainly use Thonny IDE, which is a beginner-friendly Python IDE perfect for programming with MicroPython on the Raspberry Pi Pico. * VScode will also be used for running the Flask Server. ::: :::info ***How to upload the code:*** 1) Visit [thonny](https://thonny.org/) website and click on the download link for your operating system (Windows, macOS, or Linux). 2) Run the installer and follow the on-screen instructions to install Thonny on your computer. 3) Plug your Raspberry Pi Pico into your computer using a micro USB cable while holding down the BOOTSEL button on the Pico. Release the button after connecting, your computer should recognize the Pico as a USB storage device. 4) Launch Thonny IDE on your computer. 5) Go to Run > Configure Interpreter in the Thonny menu. 6) In the Interpreter tab, select MicroPython (Raspberry Pi Pico) from the Interpreter dropdown menu. 7) Click on the Install or update firmware button. 8) Follow the instructions to download and install the latest MicroPython firmware on your Pico. 9) After installation, your Pico will restart and be ready for programming in MicroPython. 10) Download the code from this URL [Project Files](https://drive.google.com/drive/folders/1PwRzIDfHgnuYhSvDcK_qUmqYSUef-ya4?usp=sharing) 11) Open all the python files (*.py) in Thonny, for each file go to File > Save copy... select Raspberry Pi Pico ::: :::info ***Steps you need for running the Web Server*** 1) Visit [VScode](https://code.visualstudio.com/) website and click on the download link 2) Upon installation, Open VScode and go to Extensions then download the Python extension 3) Open the Terminal or CMD and type "pip install -U Flask" for insatlling Flask framework 4) Open the "Simple Web App" folder you have downloaded from the link above in VScode 5) run the "app.py", you will get URL open it in the browser 6) (Optional) You can deploy the server on [Heroku](https://id.heroku.com/login) cloud service, follow this guide [Deploy Python Flask App on Heroku](https://www.geeksforgeeks.org/deploy-python-flask-app-on-heroku/), I have already deployed the server and it can be directly accessed from this URL [Safe Access Control](https://safe-access-system-225b4ff8d3d5.herokuapp.com/), without going through steps 1-5 . ::: ## Electronics Connection Guide :::info ***1) Wiring Instructions*** 1) RFID Reader (MFRC522) Connections | Pin Number | Pin Name | Connect To GPIO | | ---------- | ------------ | --------------- | | 1 | Vcc 3.3V | 3V3 out (Pico) | | 2 | RST | 5 | | 3 | GND (ground) | GND | | 4 | IRQ | Not Connected | | 5 | MISO | 4 | | 6 | MOSI | 3 | | 7 | SCK | 2 | | 8 | SDA/CS | 0 | 2) Keypad Connections | ROW/COL | Connect To GPIO | | ------- | --------------- | | ROW 1 | 13 | | ROW 2 | 12 | | ROW 3 | 11 | | ROW 4 | 10 | | COL 1 | 9 | | COL 2 | 8 | | COL 3 | 7 | | COL 4 | 6 | 3) I2C LCD Display Connections | Pin Name | Connect To GPIO | | -------- | --------------- | | GND | GND | | VCC | VBUS (40) | | SDA | 20 | | SCL | 21 | 4) LED Connections (with 220-ohm resistors) | LED | Anode (+) | Cathode (-) | | ----- | ------------------------------------- | ----------- | | Red | to GPIO 16 through a 220-ohm resistor | to GND | | Green | to GPIO 17 through a 220-ohm resistor | to GND | | Blue | to GPIO 18 through a 220-ohm resistor | to GND | 5) Buzzer Connections | +/- | Connect To GPIO | | ------------ | --------------- | | Positive (+) | 15 | | Negative (-) | GND | --- Diagram ![circut diagram](https://hackmd.io/_uploads/By5y99VIC.png) ::: :::info ***2) Voltage and Current Considerations*** **- Resistors for LEDs** * Use 220-ohm resistors to limit the current through the LEDs. This ensures they do not draw more current than the GPIO pins can safely supply (typically 3.3V and up to 20mA per pin on the Pico) **- Power Supply** * Ensure the Raspberry Pi Pico is powered via a reliable 5V USB power source. The 3.3V pin can supply power to low-current devices like the RFID reader and LCD **- Buzzer:** * Ensure the buzzer is rated for 3.3V operation. If it requires more current than a GPIO pin can supply, use a transistor to switch the buzzer on and off. ::: :::info ***3) Development vs. Production*** **- Development Setup** * Using a breadboard and jumper wires is suitable for development and testing. It allows easy modifications and troubleshooting **- Production Setup** * For a production setup, consider using a PCB or soldering components onto a perfboard. This enhances durability and reliability. Encase the project in a suitable enclosure to protect it from physical damage and environmental factors. ::: ## Platform Choice: Local and Cloud Integration :::info ***- Local Platform: Raspberry Pi Pico (W)*** 1) Functionality * Supports MicroPython, simplifying the coding process. * Offers 26 GPIO pins for various peripheral connections. * Built-in Wi-Fi for network connectivity without additional modules. 2) Advantages * Cost-effective and low power consumption. * Integrated Wi-Fi simplifies connectivity. * Extensive community support and documentation. ::: :::info ***- Cloud Platform: Heroku*** 1) Functionality * Simplifies deployment of Flask server for web applications and APIs. * Easily scalable with various add-ons for enhanced functionality. 2) Advantages * User-friendly git-based deployment. * Costs only 1$ for subscription suitable for small projects and testing. * Seamless scalability by adjusting dyno numbers. ::: :::info ***- Comparison of Platforms*** 1) Raspberry Pi Pico W vs. Other Microcontrollers * Easier coding with MicroPython compared to C/C++. * More GPIO pins and flexibility than some Arduino boards. * Built-in Wi-Fi simplifies design compared to traditional Raspberry Pi Pico and some Arduino boards that require additional Wi-Fi modules. 2) Heroku vs. Other Cloud Platforms: * Simpler deployment process than AWS or Google Cloud. * Heroku offers easier scalability without extensive configuration. ::: :::info ***- Future Scaling*** 1) Adding Additional Sensors and Modules * Motion Sensors: Detect unauthorized access or movement around the safe. * Fingerprint Scanner: Add another layer of security with biometric authentication. 2) Integration with Other IoT Devices * Smart Home Systems: Integrate the safe with smart home ecosystems like Amazon Alexa or Google Home for voice-controlled access. * Security Cameras: Connect to security cameras to capture images or video when the safe is accessed. 3) Optimizing Power Consumption * Battery Backup: Implement a battery backup system to ensure the safe remains operational during power outages. 4) Production Setup * Custom PCB Design: Design and manufacture a custom PCB to replace the breadboard setup, improving reliability and making the system more compact. * Enclosures: Design custom enclosures to house the electronics securely, protecting them from physical damage and tampering. 5) Scaling Applications * Dedicated Database Services: Utilize Heroku’s managed database services for improved data management and security. 6) Disaster Recovery * Automated Failover: Implement automated failover mechanisms to switch to a backup server in case the primary server fails. ::: ## The code :::info **1) Network Setup and Connection** * The Raspberry Pi Pico W needs to connect to a Wi-Fi network to communicate with the Flask server hosted on Heroku. The network module is used for this purpose. ```python import network # Connect to Wi-Fi ssid = "Your_SSID" password = "Your_PASSWORD" station = network.WLAN(network.STA_IF) station.active(True) station.connect(ssid, password) while not station.isconnected(): pass print("Connection successful") ``` This code connects the Pico W to a Wi-Fi network using the provided SSID and password, and waits until the connection is established. ::: :::info **2) RFID Reader Integration** * The RFID reader (MFRC522) is used to read tags and obtain their unique IDs. The reader is initialized and used to detect and read the tags. ```python from mfrc522 import MFRC522 # Initialize RFID reader reader = MFRC522(sck=2, mosi=3, miso=4, rst=5, cs=0) try: while True: reader.init() (stat, tag_type) = reader.request(reader.REQIDL) if stat == reader.OK: (stat, uid) = reader.SelectTagSN() if stat == reader.OK: card_id = int.from_bytes(bytes(uid), "little", False) print("CARD ID: " + str(card_id)) # Further processing except KeyboardInterrupt: print("Exiting...") ``` This snippet initializes the RFID reader and continuously checks for RFID tags. When a tag is detected, it reads the tag's unique ID. ::: :::info ***- tag_reader.py*** * This script tests the RFID reader independently to ensure it can correctly read and display tag IDs. ```python from mfrc522 import MFRC522 import utime reader = MFRC522(sck=2, mosi=3, miso=4, rst=5, cs=0) try: while True: reader.init() (stat, tag_type) = reader.request(reader.REQIDL) if stat == reader.OK: (stat, uid) = reader.SelectTagSN() if stat == reader.OK: card_id = int.from_bytes(bytes(uid), "little", False) print("CARD ID:", card_id) utime.sleep(1) except KeyboardInterrupt: print("Exiting...") ``` Use this code to get the tag's unique ID and then change these values according ```python # Define valid card IDs and associated PINs valid_cards = { 2775547683: "1234", 2903672963: "5678" } ``` ::: :::info **3) Keypad Integration** * The keypad is used to enter a PIN code. The Keypad class handles the scanning and detection of key presses. ```python from keypad import Keypad # Initialize Keypad keypad = Keypad(row_pins=[13, 12, 11, 10], col_pins=[9, 8, 7, 6]) # Function to check PIN def check_pin(expected_pin, keypad): input_pin = "" while len(input_pin) < len(expected_pin): key = keypad.scan() if key: input_pin += key print("Pressed:", key) utime.sleep(0.3) # Debounce return input_pin == expected_pin ``` This function reads the input from the keypad and checks if the entered PIN matches the expected PIN. ::: :::info **4) LCD Display** * The LCD display is used to provide feedback to the user, such as prompting for PIN entry or indicating access status. ```python from machine import I2C, Pin from pico_i2c_lcd import I2cLcd # Initialize I2C LCD I2C_ADDR = 0x3f # Change to your actual address if different i2c = I2C(0, sda=Pin(20), scl=Pin(21), freq=400000) lcd = I2cLcd(i2c, I2C_ADDR, 2, 16) # 2 rows, 16 columns # Display a message lcd.putstr("Ready...\nScan your tag") ``` To get the I2C_ADDR run this script ***lcd_address_finder.py*** ```python import machine import utime i2c = machine.I2C(0, scl=machine.Pin(21), sda=machine.Pin(20), freq=400000) while True: devices = i2c.scan() if devices: print("I2C Address(es) found:", [hex(device) for device in devices]) else: print("No I2C devices found") utime.sleep(2) ``` ::: :::info **5) Communication with Flask Server** * The Pico W sends HTTP POST requests to the Flask server to unlock the safe or indicate a failed attempt. ```python import urequests # Function to connect to the (Flask Server) running on heroku def connect_to_heroku(pin, card): try: url = 'https://safe-access-system-225b4ff8d3d5.herokuapp.com/unlock' payload = {'pin': pin, 'card_id': card} response = urequests.post(url, json=payload) response.close() except Exception as e: print("Failed to send request:", e) ``` This code sends a request to the Flask server with the card ID and PIN to unlock the safe. ::: :::info **6) Discord Webhook Integration** * The system sends notifications to a Discord channel using webhooks to inform the owner of access attempts and security alerts. ```python import urequests # Discord webhook URL WEBHOOK_URL = "https://discord.com/api/webhooks/your-webhook-id/your-webhook-token" # Function to send a Discord notification def send_discord_message(content): data = { 'content': content } headers = { 'Content-Type': 'application/json' } try: response = urequests.post(WEBHOOK_URL, json=data, headers=headers) print(response.text) response.close() except Exception as e: print("Failed to send Discord message:", e) ``` Follow this guide for creating a [Discord Webhook](https://www.svix.com/resources/guides/how-to-make-webhook-discord/), then change the WEBHOOK_URL ::: ## Connectivity :::info **Overview** * The secure access system transmits data from the Raspberry Pi Pico W to a cloud-based Flask server hosted on Heroku. This communication ensures that access attempts are logged and security notifications are sent to a Discord channel. The system primarily uses Wi-Fi for wireless communication and HTTP POST requests for data transmission. ::: :::info **Wireless Protocol** * Wi-Fi: The Raspberry Pi Pico W utilizes its built-in Wi-Fi module to connect to the internet. This is the primary wireless protocol used for transmitting data to the Flask server. **Transport Protocol** * HTTP: The system uses HTTP POST requests to send data to the Flask server. This method is simple, reliable, and suitable for the relatively low-frequency, small-sized data packets being transmitted. ::: :::info **Data Transmission Frequency** * On Demand: Data is transmitted to the Flask server only when an RFID tag is read and a PIN is entered. This ensures that network usage is minimal and only relevant access attempts are logged. * Notification Frequency: Security notifications to Discord are sent only in the event of multiple failed access attempts, further reducing unnecessary network traffic. ::: ## Presenting the data :::info **Dashboard Overview** The dashboard is built using a Flask web server hosted on Heroku. The primary interface is an HTML page that visually indicates the status of the Safe. The status is updated in real-time based on data received from the Raspberry Pi Pico W. ::: :::info **How the Dashboard is Built** *- Flask Server:* The Flask server handles incoming HTTP POST requests from the Raspberry Pi Pico W and updates the Safe's status. It also serves the HTML page that acts as the dashboard. *- HTML and JavaScript:* The HTML page includes a styled visual representation of the Safe status using CSS. JavaScript is used to periodically fetch the latest status from the server and update the visual elements on the page. ::: :::info **Data Preservation and Database** * Currently, the system does not include a persistent database. Instead, the status of the Safe is maintained in memory on the Flask server. This approach is sufficient for real-time updates but does not support long-term data preservation. * To add data persistence, a database like SQLite, PostgreSQL, or MongoDB could be integrated, and data such as access attempts and timestamps could be stored for historical analysis and security auditing. ::: :::info **How Data is Presented** *- Visual Elements:* * Safe Status Indicator: A visual representation of the Safe that changes color based on the status (locked, unlocked, or access denied). * Access Button: A button that appears when the Safe is unlocked, allowing the user to view the Safe content. ::: :::info **Visual Examples** *- Dashboard - Locked State:* * The Safe indicator is gray, showing that it's locked. ![IMG-20240622-WA0005](https://hackmd.io/_uploads/B1FruI4L0.jpg) --- *- Dashboard - Unlocked State:* * The Safe indicator turns green, showing that it's unlocked, and the "Access Your Safe" button appears. ![IMG-20240622-WA0006](https://hackmd.io/_uploads/Hy2L_INUA.jpg) ![safe contnet](https://hackmd.io/_uploads/r1yqOLEUC.png) --- *- Dashboard - Access Denied State:* * The Safe indicator turns red, indicating a failed access attempt. ![IMG-20240622-WA0007](https://hackmd.io/_uploads/BJovu8NUA.jpg) ::: ## Finalizing the Design :::info **Final Thoughts on the Project** I think the project was good enough in achieving its goal of creating a secure access control system for Safe's. Here are some reflections on the project: *- Successes* * Integration: Successfully integrated multiple hardware components with the Raspberry Pi Pico W and established reliable communication with the Flask server. * Real-Time Feedback: The system provides real-time feedback to users through the LCD display, LEDs, and buzzer. * Security: Implemented multi-factor authentication using RFID tags and PINs, along with a lockout mechanism and security notifications via Discord. * User Interface: Developed a user-friendly web dashboard that visually represents the Safe's status. *- What Could Have Been Done Differently* * Earlier Integration of Database: Starting with a database from the beginning would have made data management more straightforward. * Advanced Security Measures: Considering additional security measures, like encrypted communication and advanced user management, early in the design phase could have strengthened the system. * Optimized Dashboard: Using more advanced front-end frameworks like React or Vue.js could have improved the user interface and experience. * Custom PCBs: Designing and using custom PCBs would enhance the reliability and professionalism of the setup. PCBs can reduce wiring clutter, improve electrical performance, and make the system more durable and easier to replicate for larger-scale deployments. ::: :::info **Pictures of the Final Setup** ![IMG-20240622-WA0003](https://hackmd.io/_uploads/BkICo84IR.jpg) --- ![IMG-20240622-WA0004](https://hackmd.io/_uploads/H1YenU4IC.jpg) --- ![IMG-20240622-WA0001](https://hackmd.io/_uploads/SykVnIEI0.jpg) --- ![IMG-20240622-WA0002](https://hackmd.io/_uploads/r1XrnIE8C.jpg) :::