All Posts
project
10 min read

Creating a Simple Python Password Manager

A demonstration of a python password manager with a detailed explanation.

This is not intended to replace existing solutions as there are much better options currently on the market. This is a project to get more familiar with encryption and python programming.

Introduction:

In cybersecurity, safeguarding sensitive information is of utmost importance. Encryption techniques provide a means to secure data from unauthorized access. This breakdown explores three Python programs and how they work together to form a basic password management system. We will examine code snippets, make clear how they function and how they contribute to the overall system.

The first program, `encrypt.py`, employs the AES-256 encryption algorithm using the `Crypto.Cipher` module from the pycryptodome package. It defines the `AES256` class, which accepts a user-provided key and generates a 256-bit encryption key. The class offers methods to encrypt and decrypt plaintext data. The encryption process involves generating a random initialization vector (IV) and padding the plaintext to ensure it is a multiple of 16 bytes. The encrypted data is then returned in base64 format.

The second program, `save.py`, introduces the `Saver` class responsible for saving and retrieving data from a file. It utilizes the `json` module for data serialization, the process of converting data into a standardized format that can be easily stored, transmitted, or processed.  The `json` module is also used for data deserialization, the process of taking that serialized data and converting it back into its original form. The `Saver` class saves data as JSON in a specified file and reads data from the file.

The third program, `main.py`, serves as the main entry point for the password management system. It uses the functionalities provided by the previous two programs. The program prompts the user to provide a file name and a master password. It integrates objects of the `Saver` and `AES256` classes, reads any existing password data from the file, and enables the user to perform various operations such as creating new passwords, updating existing passwords, deleting passwords, and viewing all passwords. Prior to storage in the file, the passwords are encrypted using the AES-256 algorithm.

By breaking down these programs, we gain insights into the implementation of encryption techniques, file handling, and user interaction for password management. This breakdown provides a foundation for understanding basic encryption and password security principles and illustrates how different modules can be combined to create secure systems for managing sensitive information.

Breakdown of `encrypt.py`:
1. Initializing the `AES256` class:

This code segment demonstrates the initialization of the `AES256` class. It imports the required modules (`base64`, `hashlib`, `os`, and `Crypto.Cipher`) and defines the `__init__` method. The method takes a `key` as input, which is then hashed using SHA-256 to generate a 256-bit key. Additionally, it generates a random Initialization Vector (IV) using `os.urandom(16)`.

2. Encrypting plaintext:

This code segment showcases the `encrypt` method of the `AES256` class. It accepts a `plaintext` string as input and encrypts it using the AES-CBC mode. The method creates an AES cipher object with the key and IV, pads the plaintext to ensure its length is a multiple of 16 bytes, encrypts the padded plaintext, and returns the result in Base64-encoded format.

3. Decrypting ciphertext:

This code segment demonstrates the `decrypt` method of the `AES256` class. It accepts a Base64-encoded `ciphertext` as input and decrypts it. The method decodes the ciphertext, extracts the IV, creates an AES cipher object with the key and IV, decrypts the ciphertext, removes the padding from the decrypted plaintext, and returns the result.

Breakdown of `save.py`:
1. Initializing the `Saver` class:

This code segment illustrates the initialization of the `Saver` class. It imports the necessary modules (`json` and `os`) and imports the `AES256` class from `encrypt.py`. The `__init__` method accepts a `file` name as input and stores it as an attribute.

2. Saving data as JSON:

This code segment presents the `save` method of the `Saver` class. It accepts a `data` object and saves it as JSON in the specified file. The method opens the file in write mode, employs `json.dump` to write the data in JSON format, and indents the data with 4 spaces for improved readability.

3. Reading data from the file:

This code segment is a continuation of the previous one, reading data from the specified file. The method opens the file in read mode, reads the file's contents into the `data` variable, and checks if the file is empty using `os.stat(self.file).st_size`. If the file is empty, it returns an empty list. Otherwise, it employs `json.loads` to deserialize the JSON data and returns the result.

Breakdown of `main.py`:
1. Command-line argument validation:

In the `main` function, the program verifies if the user provided a file name as a command-line argument. It leverages the `sys.argv` list, which contains the command-line arguments passed to the script. If the length of `sys.argv` is not equal to 2, it implies that the user did not provide a file name. In such cases, it prints a usage message and terminates the program with an error.

2. Creating a `Saver` object and reading data from a file:

After validating the command-line argument, the program creates a `Saver` object by importing the `Saver` class from `save.py`. The file name is obtained from `sys.argv[1]`, representing the first command-line argument provided by the user. The `Saver` object is initialized with the file name. Then, the `read` method of the `Saver` object is invoked to read the data from the file. The retrieved data is stored in the `data` list.

3. Creating and using an `AES256` object for password encryption:

The program imports the `AES256` class from `encrypt.py`. After reading the data from the file, the user is prompted to enter a previously created master password. This password is used to instantiate an `AES256` object by passing it the master password during initialization. The `AES256` object will be utilized for encrypting and decrypting passwords.

4. Creating the menu:

In this code snippet, we encounter an infinite loop that continues until the program is explicitly terminated. The loop presents the user with a menu of options. The `while True` statement creates an infinite loop. As long as the condition is true (which is always the case here), the loop will persist. Within the loop, a menu of options is displayed to the user using the `print` function. The options are listed from 1 to 5, each accompanied by a corresponding action. The `input("> ")` statement prompts the user to enter their choice. The input is assigned to the variable `option`.

5. Creating a new password and storing it in the data file:

If the user selects option 1 (create a new password) from the menu, they are prompted to enter an account name and a password. The password is then encrypted using the `encrypt` method of the `AES256` object. The encrypted password, along with the account name, is appended as a new dictionary to the `data` list. Finally, the updated `data` is saved to the file using the `save` method of the `saver` object, ensuring the newly created password is stored in the data file.

6. Retrieving and decrypting a password from the data file:

If the user selects option 2 (retrieve a password) from the menu, they are prompted to enter an account name. The program searches for a dictionary in the `data` list where the account name matches the input. If a matching account is found, the encrypted password is retrieved from the dictionary. The `decrypt` method of the `AES256` object is then employed to decrypt the password. Finally, the decrypted password is displayed on the console. If no matching account is found, a message indicating that the account was not found is shown.

7. Deleting a password from the data file:

If the user selects option 3 (delete a password) from the menu, they are prompted to enter an account name. The program searches for a dictionary in the `data` list where the account name matches the input. If a matching account is found, the dictionary is removed from the `data` list using the `remove` method. The updated data is then saved to the file using the `save` method of the `saver` object. Finally, a message indicating the successful deletion of the password is displayed. If no matching account is found, a message indicating that the account was not found is printed.

8. Viewing all passwords from the data file:

If the user selects option 4 (view all passwords) from the menu, the program iterates through the `data` list. For each dictionary in the list, it retrieves the account name and encrypted password. The `decrypt` method of the `AES256` object is then used to decrypt the password. Finally, the account name and decrypted password are displayed on the console.

9. Exiting the program:

If the user selects option 5 (exit), the program breaks out of the infinite loop, effectively terminating the program.

Conclusion:

In this analysis, we examined in detail three Python programs working together to create a basic password management system. By examining the code snippets and explaining their functionality, we gained insights into implementing encryption techniques, handling files, and facilitating user interaction for password management.

The first program, `encrypt.py`, demonstrated the implementation of the AES-256 encryption algorithm using the `Crypto.Cipher` module. It provided methods for encrypting and decrypting plaintext data, ensuring the security of sensitive information.

The second program, `save.py`, introduced the `Saver` class responsible for saving and retrieving data from a file. It utilized the `json` module for data serialization and deserialization, ensuring the persistence of password data even after the program terminates. The `Saver` class handled scenarios such as empty files, ensuring a seamless user experience.

The third program, `main.py`, served as the main entry point for the password management system. It integrated the functionalities provided by the previous two programs. It validated command-line arguments, created instances of the `Saver` and `AES256` classes, and allowed users to perform various operations such as creating new passwords, retrieving passwords, deleting passwords, and viewing all passwords. The passwords were encrypted using the AES-256 algorithm before being stored in the file, providing an additional layer of security.

Understanding the concepts and techniques presented in this breakdown provides a stepping stone for building more robust and secure systems. With further exploration and enhancements, this basic password management system can be extended to incorporate additional features such as password strength evaluation, secure password generation, and multi-factor authentication, further enhancing the overall security of the system.

This breakdown gives insight into the implementation of encryption and file handling techniques in Python, providing a solid foundation for anyone interested in cybersecurity and password management systems.

Previous

network security and python software engineer

Next

Scraping Contact Info from Web Pages Using Python