DEV Community

Cover image for I Built a Password Manager Using Python, Streamlit, and Fernet β€” Here's How πŸ›‘οΈ
Nishkarsh Pandey
Nishkarsh Pandey

Posted on

I Built a Password Manager Using Python, Streamlit, and Fernet β€” Here's How πŸ›‘οΈ

Tired of trusting your most sensitive passwords to random apps? I decided to build my own simple password manager app using Streamlit and Fernet encryption to keep my passwords safe.

The result?
A lightweight, fast, and secure app that stores passwords locally and encrypts them properly.
Let’s break it down πŸ‘‡

πŸ› οΈ Tools I Used
Python 3

Streamlit β€” To create a fast, interactive web app without building a frontend from scratch.

Fernet (from the cryptography library) β€” To encrypt and decrypt password data safely.

To build the password manager in Python, I have used the following libraries:

cryptography: For encryption and decryption of passwords.

1.os: To interact with the operating system.

2.json: For storing and managing data in a structured format.

3.getpass: To securely accept the master password from the user.

Step 1: Install Required Libraries

pip install cryptography

Step 2: Write the Script
Here’s the code for the Password Manager using Streamlit and Fernet encryption:

import json
import os
import streamlit as st
from getpass import getpass
from cryptography.fernet import Fernet
from streamlit_elements import elements, mui

# File to store passwords
PASSWORD_FILE = 'passwords.json'
KEY_FILE = 'key.key'

def generate_key():
    """
    Generate a new encryption key and save it to a file.
    """
    key = Fernet.generate_key()
    with open(KEY_FILE, 'wb') as key_file:
        key_file.write(key)

def load_key():
    """
    Load the encryption key from a file.
    """
    return open(KEY_FILE, 'rb').read()

def encrypt_password(password, key):
    """
    Encrypt a password using the provided key.
    """
    f = Fernet(key)
    return f.encrypt(password.encode())

def decrypt_password(encrypted_password, key):
    """
    Decrypt a password using the provided key.
    """
    f = Fernet(key)
    return f.decrypt(encrypted_password).decode()

def save_passwords(passwords):
    """
    Save the password data to a JSON file.
    """
    with open(PASSWORD_FILE, 'w') as file:
        json.dump(passwords, file)

def load_passwords():
    """
    Load the password data from a JSON file.
    """
    if os.path.exists(PASSWORD_FILE):
        with open(PASSWORD_FILE, 'r') as file:
            content = file.read().strip()
            if content:
                return json.loads(content)
            else:
                return {}
    else:
        return {}

def add_password(account, password, key):
    """
    Add a new account and password to the password manager.
    """
    passwords = load_passwords()
    encrypted_password = encrypt_password(password, key)
    passwords[account] = encrypted_password.decode()
    save_passwords(passwords)
    print(f"Password for {account} added successfully.")

def retrieve_password(account, key):
    """
    Retrieve the password for a specific account.
    """
    passwords = load_passwords()
    if account in passwords:
        encrypted_password = passwords[account].encode()
        return decrypt_password(encrypted_password, key)
    else:
        print(f"No password found for account: {account}")
        return None

def main():
    if not os.path.exists(KEY_FILE) or os.path.getsize(KEY_FILE) == 0:
        st.info("Encryption key not found or invalid. Generating a new key...")
        generate_key()

    key = load_key()

    try:
        Fernet(key)
    except ValueError:
        st.warning("Invalid encryption key detected. Regenerating...")
        generate_key()
        key = load_key()

    st.title("Password Manager πŸ”’")
    st.subheader("Securely store and retrieve your passwords πŸ”")

    choice = st.selectbox("Choose an option:", ["Add a new password", "Retrieve a password", "Quit"])

    if choice == "Add a new password":
        account = st.text_input("Enter the account name (e.g., website or app name): ")
        password = st.text_input("Enter the password: ", type="password")
        if st.button("Add Password"):
            add_password(account, password, key)
            st.success(f"Password for {account} added successfully.")

    elif choice == "Retrieve a password":
        account = st.text_input("Enter the account name:")
        if st.button("Retrieve Password"):
            password = retrieve_password(account, key)
            if password:
                st.success(f"Password for {account}: {password}")
            else:
                st.error(f"No password found for account: {account}")

    elif choice == "Quit":
        st.warning("Exiting the Password Manager. Close the app.")

    st.divider()
    st.write("Developed by Nishkarsh Pandey")
    st.write("GitHub: [Nishkarsh Pandey](https://github.com/Nish2005karsh)")

    with elements("multiple_childrens"):
        mui.Button(mui.icon.Facebook())
        mui.Button(mui.icon.Twitter())
        mui.Button(mui.icon.Instagram())
        mui.Button(mui.icon.LinkedIn())
        mui.Button(mui.icon.GitHub())

if __name__ == "__main__":
    main()
Enter fullscreen mode Exit fullscreen mode

How It Works
πŸ”‘ Encryption Key Management:
Generate Key: The generate_key() function creates a new encryption key and saves it to a file (key.key).

Load Key: The load_key() function reads the encryption key from the file.

πŸ” Password Encryption and Decryption:
Encrypt Password: The encrypt_password() function encrypts a password using the encryption key.

Decrypt Password: The decrypt_password() function decrypts an encrypted password.

πŸ’Ύ Password Storage:
Save Passwords: The save_passwords() function writes the account-password pairs to a JSON file (passwords.json).

Load Passwords: The load_passwords() function reads the account-password pairs from the JSON file.

πŸ”‘ Adding and Retrieving Passwords:
Add Password: The add_password() function adds a new account and encrypted password.

Retrieve Password: The retrieve_password() function retrieves and decrypts the password for a specific account.

πŸš€ Final Thoughts
Building your own tools not only boosts your coding skills β€” it also teaches you how security works under the hood. This small project made me realize how much we take simple encryption for granted.

Want to try building your own password manager too? πŸš€
Feel free to fork my GitHub repo and get started!

Drop your questions or thoughts in the comments β€” I’d love to help!
Well output is this:
Image description:

Top comments (9)

Collapse
 
bhuvi_d profile image
Bhuvi D

Interesting, thanks for sharing.

Collapse
 
nish2005karsh profile image
Nishkarsh Pandey

Thanks, Bhuvi! Glad you found it interesting. Let me know if you’d like a walkthrough or want to build something similar together! πŸ˜ŠπŸ”

Collapse
 
bhuvi_d profile image
Bhuvi D

Sure, would love to collaborate on building something similar to this :)

Thread Thread
 
nish2005karsh profile image
Nishkarsh Pandey

Awesome! Really looking forward to building something cool together.
If you're up for it, happy to connect on Insta or LinkedIn too β€” totally your call :)
Let me know what platform works best for you!

Thread Thread
 
bhuvi_d profile image
Bhuvi D

You can reach out to me at @_booovviii_ on Insta , we can take it from there 😊.

Thread Thread
 
nish2005karsh profile image
Nishkarsh Pandey

Thanks, Bhuvi! Just connected with you on Insta (@booovviii) β€” excited to see where this goes πŸ™Œ

Collapse
 
nish2005karsh profile image
Nishkarsh Pandey

How is my project . Yeah i know its a basic version that uses fernet encryption . I will also try it with the AES one.

Collapse
 
alex-rivera88 profile image
Alex Rivera

I love the approach you’ve taken with this! I’ve been working on a similar project, and I’m curious about how you handle key management in your implementation. Any tips or best practices you’d recommend?

Collapse
 
nish2005karsh profile image
Nishkarsh Pandey

Use AES that's what i can say currently!!!