-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPasswordManager.py
108 lines (94 loc) · 3.92 KB
/
PasswordManager.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import base64
import os
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives.kdf.scrypt import Scrypt
class PasswordManager:
def __init__(self) -> None:
self.password_dir = os.path.expanduser('~') + '/.password_manager'
self.initialized = os.path.exists(self.password_dir)
def init_app(self):
if not self.initialized:
os.makedirs(self.password_dir)
self.salt = os.urandom(16)
with open(self.password_dir + '/salt', 'wb') as salt_file:
salt_file.write(self.salt)
return True
else:
return False
def generate_key(self, main_password: str, method='scrypt'):
with open(self.password_dir + '/salt', 'rb') as salt_file:
self.salt = salt_file.read()
if method == 'pbkdf2hmac':
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=self.salt,
iterations=390000,
)
elif method == 'scrypt':
kdf = Scrypt(
salt=self.salt,
length=32,
n=2**20,
r=8,
p=1,
)
key = base64.urlsafe_b64encode(kdf.derive(main_password.encode()))
return key
def encrypt_password(self, password, key):
encrypted_password = Fernet(key).encrypt(password.encode())
return encrypted_password
def add_password(self, siteName: str, username: str, site_password: str, main_password: str):
if not self.initialized:
return False
try:
folder = self.password_dir + '/' + siteName
if not os.path.exists(folder):
os.makedirs(folder)
encrypted_password = self.encrypt_password(
site_password, self.generate_key(main_password))
with open(folder + '/' + username + '.pass', 'wb') as password_file:
password_file.write(encrypted_password)
return True
except:
return False
def delete_password(self, siteName, username, main_password):
if not self.initialized:
raise Exception('Password manager not initialized')
try:
folder = self.password_dir + '/' + siteName
password_file_path = folder + '/' + username + '.pass'
key = self.generate_key(main_password)
with open(password_file_path, 'rb') as password_file:
encrypted_password = password_file.read()
# try to decrypt the password
_ = Fernet(key).decrypt(encrypted_password)
# if decrypted, delete the file
os.remove(password_file_path)
return True
except:
return False
def get_list_password_file_path(self):
if not self.initialized:
raise Exception('Password manager not initialized')
list_password_file_path = []
for root, dirs, files in os.walk(self.password_dir):
for file in files:
if file.endswith('.pass'):
list_password_file_path.append(os.path.join(root, file))
return list_password_file_path
def get_password(self, site: str, username: str, main_password: str):
password_file_path = self.password_dir + '/' + site + '/' + username + '.pass'
if not self.initialized:
raise Exception('Password manager not initialized')
try:
key = self.generate_key(main_password)
with open(password_file_path, 'rb') as password_file:
encrypted_password = password_file.read()
decrypted_password = Fernet(key).decrypt(encrypted_password)
return decrypted_password.decode()
except Exception as e:
print(e)
return False