1+ import random , datetime , base64 , argparse , os
2+ from cryptography .fernet import Fernet
3+
4+ # 🔑 File where secret key will be stored
5+ KEY_FILE = "secret.key"
6+
7+ # ------------------------------------------------------
8+ # STEP 1: Generate a new encryption key (only once))
9+ def generate_key ():
10+ key = Fernet .generate_key ()
11+ with open (KEY_FILE , "wb" ) as f :
12+ f .write (key )
13+
14+ # STEP 2: Load the ecryption key
15+ def load_key ():
16+ if not os .path .exists (KEY_FILE ):
17+ print ("No Key found. Creating a new one..." )
18+ generate_key ()
19+ with open (KEY_FILE , "rb" ) as f :
20+ return f .read ()
21+
22+ # STEP 3: Generate password based on user settings
23+ def generate_password (length , use_lower , use_upper , use_digits , use_specials ):
24+ lowercase = 'abcdefghijklmnopqrstuvwxyz'
25+ uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
26+ digits = '0123456789'
27+ specials = '!@#$%^&*()'
28+
29+ # Build character set based on user input
30+ character_set = ''
31+
32+ if use_lower :
33+ character_set = character_set + lowercase
34+ if use_upper :
35+ character_set = character_set + uppercase
36+ if use_digits :
37+ character_set = character_set + digits
38+ if use_specials :
39+ character_set = character_set + specials
40+
41+ if not character_set :
42+ return "Error: No character sets selected. Cannot generate password."
43+
44+ password = ''
45+ for i in range (length ):
46+ password = password + random .choice (character_set )
47+ return password
48+
49+ # STEP 4: Check password strength
50+ def check_strength (length , use_lower , use_upper , use_digits , use_specials ):
51+ score = 0
52+
53+ # Add points for character variety
54+ score = score + use_lower + use_upper + use_digits + use_specials
55+
56+ if length >= 12 :
57+ score = score + 1
58+
59+ if score <= 2 :
60+ return "Weak"
61+ elif score == 3 or score == 4 :
62+ return "Medium"
63+ else :
64+ return "Strong"
65+
66+ # STEP 5: Command-line interface using argparse
67+ def main ():
68+ parser = argparse .ArgumentParser (description = "🔐 Password Generator Tool" )
69+
70+ parser .add_argument ('--length' , type = int , required = True , help = 'Password length (e.g., 8, 12, 16)' )
71+ parser .add_argument ('--label' , type = str , required = True , help = 'Purpose or label for the password (e.g, Google, Gmail)' )
72+ parser .add_argument ('--lower' , action = 'store_true' , help = 'Include lowercase letters' )
73+ parser .add_argument ('--upper' , action = 'store_true' , help = 'Include uppercase letters' )
74+ parser .add_argument ('--digits' , action = 'store_true' , help = 'Include digits' )
75+ parser .add_argument ('--specials' , action = 'store_true' , help = 'Include special characters' )
76+
77+ args = parser .parse_args ()
78+
79+ # Validate length
80+ if args .length <= 0 :
81+ print ("❌ Password length must be positive. Try again." )
82+ return
83+
84+ # Generate and evaluate password
85+ password = generate_password (args .length , args .lower , args .upper , args .digits , args .specials )
86+ if password .startswith ("Error" ):
87+ print (password )
88+ return
89+
90+ print (f"✅ Your generated password is: { password } " )
91+ strength = check_strength (args .length , args .lower , args .upper , args .digits , args .specials )
92+ print (f"💪 Password Strenght: { strength } " )
93+
94+ # STEP 6: Encrypt password using Fernet
95+ key = load_key ()
96+ fernet = Fernet (key )
97+ encrypted_password = fernet .encrypt (password .encode ()).decode () # This variable already holds the Fernet encrypted string.
98+
99+ # STEP 7: Save encrypted password to file
100+ with open ("saved_passwords.txt" , "a" ) as file :
101+ timestamp = datetime .datetime .now ().strftime ("%d-%m-%Y %H:%M:%S" )
102+ # The 'encoded_password' (base64 of original password) was being saved previously.
103+ # We should save the 'encrypted_password' (Fernet encrypted string) instead.
104+ file .write (f"\n [{ timestamp } ]\n " )
105+ file .write (f"Label: { args .label } \n " )
106+ file .write (f"Encrypted Password: { encrypted_password } \n " ) # Save the Fernet encrypted password and use "Encrypted Password:" label
107+ file .write (f"Included - Lowercase: { args .lower } , Uppercase: { args .upper } , Digits: { args .digits } , Special Characters: { args .specials } \n " )
108+ file .write ("-" * 40 + "\n " )
109+
110+ print ("🔒 Password encrypted and saved to 'saved_passwords.txt" )
111+
112+
113+ if __name__ == '__main__' :
114+ main ()
0 commit comments