Skip to content

Commit 2475173

Browse files
committed
CNG: Re-structure to more dynamic and improve most security issue
1 parent c6423b1 commit 2475173

File tree

2 files changed

+175
-161
lines changed

2 files changed

+175
-161
lines changed

passwdmanager.exe

726 KB
Binary file not shown.

passwdmanager.py

Lines changed: 175 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -1,169 +1,183 @@
1-
import mysql.connector
2-
import getpass
3-
import base64
41
import os
2+
import base64
3+
import getpass
4+
import mysql.connector
55
from cryptography.fernet import Fernet
66
from cryptography.hazmat.backends import default_backend
77
from cryptography.hazmat.primitives import hashes
8-
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
9-
10-
def enter():
11-
#enter user and password for database and master password
12-
enter.user = input("Enter database username: ")
13-
enter.passwd = getpass.getpass("Enter database password: ")
14-
enter.k = getpass.getpass("Enter master password: ")
15-
test_login()
16-
17-
def test_login():
18-
try:
19-
#connect to database
20-
mydb = mysql.connector.connect(
21-
host='localhost', #or your hostname/ip-address
22-
user=(enter.user),
23-
password=(enter.passwd)
8+
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
9+
10+
"""
11+
+------------SECTION------------+
12+
- setup : setup dependencies
13+
- db_setup : setup database
14+
- menu : menu prompting
15+
- db_check : check if row exist
16+
- view : view module
17+
- insert : insert module
18+
- delete : delete module
19+
- salter : salt generator
20+
- kdf : _cryption module
21+
+-------------------------------+
22+
"""
23+
24+
def setup():
25+
global login_user
26+
global mysql_passwd
27+
global main_passwd
28+
global mydb
29+
global mysql_cursor
30+
global id_cursor
31+
global password_cursor
32+
global salt_cursor
33+
34+
# login section
35+
login_user = input('Enter user: ')
36+
mysql_passwd = getpass.getpass('Enter password: ')
37+
main_passwd = getpass.getpass('Enter main password: ')
38+
39+
# Database connection
40+
mydb = mysql.connector.connect(
41+
host='localhost', # Change this if you have dedicated Database
42+
user=(login_user),
43+
password=(mysql_passwd)
2444
)
25-
func()
26-
except mysql.connector.Error as err:
27-
print("\033[1;31;40m Error username or password.Plese try again\033[1;37;40m\n")
28-
enter()
29-
30-
def func():
31-
if enter.user=='' or enter.passwd=='' or enter.k=='': #detect blank input
32-
print("\033[1;31;40m Error username or password.Plese try again\033[1;37;40m\n")
33-
enter()
45+
mysql_cursor = mydb.cursor(buffered=True)
46+
id_cursor = mydb.cursor(buffered=True)
47+
password_cursor = mydb.cursor(buffered=True)
48+
salt_cursor = mydb.cursor(buffered=True)
49+
db_setup()
50+
51+
def db_setup():
52+
# Check if Database exist
53+
mysql_cursor.execute(f'CREATE DATABASE IF NOT EXISTS db_password_{login_user}')
54+
55+
# Check if Table exist
56+
mysql_cursor.execute(f'CREATE TABLE IF NOT EXISTS db_password_{login_user}.tb_{login_user} (id INT NOT NULL AUTO_INCREMENT,name VARCHAR(255) NOT NULL,tag VARCHAR(255), password BLOB NOT NULL, salt BLOB NOT NULL, PRIMARY KEY (id))')
57+
menu() # Forward to menu
58+
59+
def menu():
60+
print('\nWelcome!')
61+
print('v to view all your password')
62+
print('i to insert new password')
63+
print('d to delete password')
64+
print('q to quit the program')
65+
cmd = input('> ').lower()
66+
67+
if cmd == 'v':
68+
view()
69+
elif cmd == 'i':
70+
insert()
71+
elif cmd == 'd':
72+
delete()
73+
elif cmd == 'q':
74+
print('\nBye!')
75+
return 0
3476
else:
35-
#connect to database
36-
mydb = mysql.connector.connect(
37-
host='localhost', #or your hostname/ip-address
38-
user=(enter.user),
39-
password=(enter.passwd)
40-
)
41-
42-
#set cursor
43-
mycursor = mydb.cursor(buffered=True)
44-
d = mydb.cursor(buffered=True)
45-
i = mydb.cursor(buffered=True)
46-
47-
#detect and create database
48-
mycursor.execute('CREATE DATABASE IF NOT EXISTS db_password')
49-
mycursor.execute('CREATE TABLE IF NOT EXISTS db_password.tb_nap (id INT NOT NULL AUTO_INCREMENT,name VARCHAR(255) NOT NULL,password VARCHAR(255) NOT NULL,PRIMARY KEY (id))')
50-
51-
#interfaces
52-
print("\n\nWelcome to password manager python! what you want to do?(v to view all your password,i to insert,d to delete,q to exit)")
53-
cmd = input(">")
54-
55-
#view query
56-
if cmd == 'v' or cmd == 'V':
57-
mycursor.execute("SELECT id, name FROM db_password.tb_nap") #select id,name from database
58-
myresult = mycursor.fetchall()
59-
60-
if len(myresult)==0: #detect blank input
61-
print("Nothing here\n")
62-
else:
63-
print("What you wanna see?")
64-
for x in myresult :
65-
print(x)
66-
67-
icmd = input("Enter ID:")
68-
if icmd=='':
69-
print("\033[1;31;40m Error id. \033[1;37;40m\n")
70-
try:
71-
icmd = int(icmd)
72-
except ValueError:
73-
print("\033[1;31;40m Error id. \033[1;37;40m\n")
74-
func()
75-
else:
76-
d.execute("SELECT id,name FROM db_password.tb_nap WHERE id= %s",(icmd,)) #select id,name from id input
77-
i.execute("SELECT password FROM db_password.tb_nap WHERE id= %s",(icmd,)) #select password from id input
78-
p = d.fetchall()
79-
i = i.fetchall()
80-
password = " , ".join( map(str, i) ) #transition list to string
81-
82-
k_encode = enter.k.encode() #encode key to byte
83-
p_encode = password.encode() #encode password to byte
84-
salt = b'`R\xf7\xc0\xf3+@\xdd~\xa4K1Ty\x83\x9a'
85-
kdf = PBKDF2HMAC(
86-
algorithm=hashes.SHA256(),
87-
length=32,
88-
salt=salt,
89-
iterations=100000,
90-
backend=default_backend()
91-
)
92-
key = base64.urlsafe_b64encode(kdf.derive(k_encode))
93-
f = Fernet(key) #ready to decrypt
94-
decrypted = decrypted = f.decrypt(p_encode) #decrypted
95-
ogpasswd = decrypted.decode() #decode from byte to string
96-
97-
print("Password for",p,"is",ogpasswd,"\n\n") #show id,name,password
98-
func()
99-
100-
101-
#insert
102-
elif cmd == 'i' or cmd == 'I':
103-
print("Insert name and password")
104-
n = input("name>")
105-
p = getpass.getpass("password>")
106-
107-
if n=='' or p=='': #detect blank input
108-
print("\033[1;31;40m Can't insert into database.Plese input all of data. \033[1;37;40m\n")
109-
else:
110-
k_encode = enter.k.encode() #encode key to byte
111-
p_encode = p.encode() #encode password input to byte
112-
salt = b'`R\xf7\xc0\xf3+@\xdd~\xa4K1Ty\x83\x9a'
113-
kdf = PBKDF2HMAC(
114-
algorithm=hashes.SHA256(),
115-
length=32,
116-
salt=salt,
117-
iterations=100000,
118-
backend=default_backend()
119-
)
120-
key = base64.urlsafe_b64encode(kdf.derive(k_encode))
121-
122-
f = Fernet(key) #ready to encrypt
123-
encrypted = f.encrypt(p_encode) #encrpyted
124-
125-
sql = "INSERT INTO db_password.tb_nap (name, password) VALUES (%s, %s)" #insert to table query
126-
val = (n, encrypted)
127-
mycursor.execute(sql, val)
128-
mydb.commit() #confirm operation to database
129-
130-
print(mycursor.rowcount, "password inserted\n\n") #show number(s) of query that have inserted
131-
func()
132-
133-
#delete
134-
elif cmd == 'd' or cmd == 'D':
135-
mycursor.execute("SELECT id,name FROM db_password.tb_nap") #select id,name from db
136-
myresult = mycursor.fetchall()
137-
for x in myresult: #show id,name query in database
138-
print("What you want to delete?")
139-
print(x)
140-
141-
i = input("Enter id:") #enter query id
142-
c = input("Confirm deleting?(y/n): ")
143-
144-
if i=='': #detect blank input
145-
print("\033[1;31;40m Error id. \033[1;37;40m")
146-
else:
147-
if c == 'y' or c =='Y':
148-
sql = "DELETE FROM db_password.tb_nap WHERE id = %s" #delete from query id
149-
mycursor.execute(sql, (i,))
150-
mydb.commit() #confirm operation to database
151-
152-
print(mycursor.rowcount, "name and password deleted\n\n") #show number(s) of query that have deleted
153-
else:
154-
print("Cancled...")
155-
func()
77+
print('\nNot an option!')
78+
return menu()
79+
80+
def db_check():
81+
# Query id, name
82+
mysql_cursor.execute(f"SELECT id, name FROM db_password_{login_user}.tb_{login_user}")
83+
myresult = mysql_cursor.fetchall()
84+
85+
# If query return 0
86+
if len(myresult) == 0:
87+
print('Nothing to show.')
88+
else: # If there's data
89+
for item in myresult:
90+
print(item)
91+
pass
92+
93+
def view():
94+
db_check()
15695

157-
elif cmd == 'q' or cmd == 'Q':
158-
print("See you next time\n")
159-
end()
96+
view_id = input('Enter id: ')
97+
try:
98+
view_id = int(view_id) # Check if ID is INT or not
99+
100+
# Check if data exist on ID
101+
id_cursor.execute(f"SELECT id, COUNT(*) FROM db_password_{login_user}.tb_{login_user} WHERE id = {view_id} GROUP BY id")
102+
check_id = id_cursor.rowcount
103+
if check_id == 0:
104+
print('\nInvalid ID')
105+
return view()
106+
except:
107+
print('\nInvalid ID')
108+
109+
# Query id, name, salt, password
110+
id_cursor.execute(f"SELECT id,name FROM db_password_{login_user}.tb_{login_user} WHERE id={view_id}")
111+
salt_cursor.execute(f"SELECT salt FROM db_password_{login_user}.tb_{login_user} WHERE id={view_id}")
112+
password_cursor.execute(f"SELECT password FROM db_password_{login_user}.tb_{login_user} WHERE id={view_id}")
113+
114+
# Clean Query
115+
id_for_view = id_cursor.fetchall()[0][1]
116+
salt_for_view = salt_cursor.fetchall()[0][0]
117+
password_for_view = password_cursor.fetchall()[0][0]
118+
119+
kdf(salt_for_view) # Pass salt to KDF module
120+
decrypted = crypter.decrypt(password_for_view) # Decrypt password
121+
showed_password = decrypted.decode() # Decode byte object to normal string
122+
print("Password for",id_for_view,"is",showed_password)
123+
menu()
124+
125+
def insert():
126+
name = input('Name: ')
127+
tag = input('Tag: ')
128+
password = input('Password: ')
129+
130+
if name == '' or password == '':
131+
print('Please enter something')
132+
else:
133+
try:
134+
salt = salter() # Gen Salt
135+
kdf(salt) # Pass salt to KDF module
136+
password = crypter.encrypt(password.encode()) # Encrypt password(.encode() to turn into byte object)
137+
138+
# Insert name, tag, password, salt to Database
139+
sql = f"INSERT INTO db_password_{login_user}.tb_{login_user} (name, tag, password, salt) VALUES (%s, %s, %s, %s)"
140+
value = (name, tag, password, salt)
141+
mysql_cursor.execute(sql, value)
142+
mydb.commit()
143+
print(mysql_cursor.rowcount, 'password inserted')
144+
menu()
145+
except:
146+
print('Something wrong')
147+
148+
def delete():
149+
db_check()
150+
151+
del_id = input('Enter id: ')
152+
del_confirm = input('Confirm deleting?(y/N): ').lower()
160153

161-
#error
162-
else :
163-
print("\033[1;31;40m Error,Can't define command...plese try again \033[1;37;40m\n")
164-
func()
165-
166-
def end():
167-
os.system('pause')
168-
169-
enter()
154+
if del_id == '':
155+
print('Invalid id')
156+
else:
157+
if del_confirm == 'y':
158+
# Delete entire row by ID
159+
mysql_cursor.execute(f"DELETE FROM db_password_{login_user}.tb_{login_user} WHERE id ={del_id}")
160+
mydb.commit()
161+
print(mysql_cursor.rowcount, "name and password deleted")
162+
menu()
163+
else:
164+
print("Cancled...")
165+
166+
def salter():
167+
return os.urandom(16) # Generate random byte for lenght of 16
168+
169+
def kdf(salt):
170+
global crypter
171+
172+
kdf = PBKDF2HMAC(
173+
algorithm=hashes.SHA256(), # Algorithm SHA256
174+
length=32,
175+
salt=salt,
176+
iterations=100000, # Iterations can be changed
177+
backend=default_backend()
178+
)
179+
key = base64.urlsafe_b64encode(kdf.derive(main_passwd.encode()))
180+
crypter = Fernet(key) # Crypter
181+
182+
if __name__ == '__main__':
183+
setup()

0 commit comments

Comments
 (0)