1+ from cryptography .fernet import Fernet
2+ # Symmetric Key Encyrption Class
3+
4+ # Password Manager Class that will create & load passwords from an encrypted file
5+ class PasswordManager :
6+ def __init__ (self ):
7+ self .key = None
8+ self .pwd_file = None
9+ self .pwd_dict = {}
10+
11+ def create_key (self , path ):
12+ self .key = Fernet .generate_key ()
13+ with open (path , 'wb' ) as f :
14+ f .write (self .key )
15+
16+ def load_key (self , path ):
17+ with open (path , 'rb' ) as f :
18+ self .key = f .read ()
19+
20+ # init_values is a dictionary
21+ def create_pwd_file (self , path , init_values = None ):
22+ self .pwd_file = path
23+ if init_values is not None :
24+ for key , values in init_values .items ():
25+ self .add_password (self , key , values )
26+
27+ def load_pwd_file (self , path ):
28+ self .pwd_file = path
29+ with open (path , 'r' ) as f :
30+ for line in f :
31+ site , encrypted = line .split (":" )
32+ # Loads the site and the associated encrypted password. Password must be encoded before decyprtion and decoded before returning text
33+ self .pwd_dict [site ] = Fernet (self .key ).decrypt (encrypted .encode ()).decode ()
34+
35+ def add_password (self , site , password ):
36+ self .pwd_dict [site ] = password
37+ if self .pwd_file is not None :
38+ with open (self .pwd_file , 'a' ) as f :
39+ encrypted = Fernet (self .key ).encrypt (password .encode ())
40+ s = ":"
41+ written = site + s + encrypted .decode () + "\n "
42+ f .write (written )
43+
44+ def get_password (self , site ):
45+ return self .pwd_dict [site ]
46+
47+ def get_sites (self ):
48+ print ("List of Sites:" )
49+ for a in self .pwd_dict .keys ():
50+ print (a )
51+
52+ def main ():
53+ pm = PasswordManager ()
54+ print ("""What would you like to do?
55+ (1) Create a new key
56+ (2) Load an existing key
57+ (3) Create new password file
58+ (4) Load existing password file
59+ (5) Add a new password
60+ (6) Get a password for a site
61+ (7) Get the list of sites
62+ (m) Menu
63+ (h) Help
64+ (q) Quit""" )
65+ done = False
66+
67+ while not done :
68+
69+ choice = input ("Enter your choice: " )
70+ choice = choice .lower ()
71+ match choice :
72+ case "1" :
73+ path = input ("Enter the path: " )
74+ pm .create_key (path )
75+ case "2" :
76+ path = input ("Enter the path: " )
77+ pm .load_key (path )
78+ case "3" :
79+ path = input ("Enter the path: " )
80+ pm .create_pwd_file (path , init_values = None )
81+ case "4" :
82+ path = input ("Enter the path: " )
83+ pm .load_pwd_file (path )
84+ case "5" :
85+ site = input ("Enter the site: " )
86+ password = input ("Enter the password: " )
87+ pm .add_password (site , password )
88+ case "6" :
89+ site = input ("What site do you want: " )
90+ print (pm .get_password (site ))
91+ case "7" :
92+ pm .get_sites ()
93+ case "m" :
94+ print ("""What would you like to do?
95+ (1) Create a new key
96+ (2) Load an existing key
97+ (3) Create new password file
98+ (4) Load existing password file
99+ (5) Add a new password
100+ (6) Get a password for a site
101+ (m) Menu
102+ (h) Help
103+ (q) Quit""" )
104+ case "h" :
105+ print ("""Getting Started:
106+ 1. Select Option (1) Create a new key that will be used to encrypt your password file.
107+ 2. Select Option (3) Create a new password file that will be used to hold your encrypted passwords.
108+ 3. Select Option (5) Add a new password to the password file. \n
109+ Retrieving or Adding Passords:
110+ 1. Select Option (2) Load the existing key so it can be used to encrypt new passwords or retrieve passwords from the password file.
111+ 2. Select Option (4) Load the existing password file so it can be used to add or retrieve passwords.
112+ 3a. Select Option (5) Add a new password to the password file.
113+ 3b. Select Option (6) Retrieve a password for a site.""" )
114+ case "q" :
115+ done = True
116+ print ("Bye!" )
117+ case _:
118+ print ("Invalid Choice!" )
119+
120+ if __name__ == '__main__' :
121+ main ()
0 commit comments