Skip to content

Commit e1170d0

Browse files
authored
Added program and requirements.txt
1 parent ffdee25 commit e1170d0

File tree

2 files changed

+348
-0
lines changed

2 files changed

+348
-0
lines changed

password-manager.py

Lines changed: 303 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,303 @@
1+
import sqlite3
2+
import hashlib
3+
import secrets
4+
import base64
5+
import string
6+
from cryptography.fernet import Fernet
7+
from cryptography.hazmat.primitives import hashes
8+
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
9+
import getpass
10+
import sys
11+
import pyperclip
12+
13+
class PasswordManager:
14+
def __init__(self, database_name="passwords.db"):
15+
self.database_name = database_name
16+
self.key = None
17+
self.cipher_suite = None
18+
self.setup_database()
19+
20+
def setup_database(self):
21+
# Uzsāk SQLite datubāzi ar vajadzīgajām tabulām
22+
conn = sqlite3.connect(self.database_name)
23+
cursor = conn.cursor()
24+
25+
# Veido master paroles tabulu (priekš hash un salta)
26+
cursor.execute('''
27+
CREATE TABLE IF NOT EXISTS master_password (
28+
id INTEGER PRIMARY KEY,
29+
password_hash TEXT NOT NULL,
30+
salt TEXT NOT NULL
31+
)''')
32+
33+
# Veido paroles tabulu (glabā šifrētus datus)
34+
cursor.execute('''
35+
CREATE TABLE IF NOT EXISTS passwords (
36+
id INTEGER PRIMARY KEY,
37+
service TEXT NOT NULL,
38+
username TEXT NOT NULL,
39+
encrypted_password TEXT NOT NULL
40+
)''')
41+
42+
conn.commit()
43+
conn.close()
44+
45+
def generate_password(self, length=16, copy_to_clipboard=True):
46+
# Izveidot drošu paroli un pēc izvēles kopējiet to.
47+
if length < 8:
48+
raise ValueError("Paroles garumam ir jābūt vismaz 8 rakstzīmēm")
49+
50+
# Iekļauj visas rakstzīmes
51+
lowercase = string.ascii_lowercase
52+
uppercase = string.ascii_uppercase
53+
digits = string.digits
54+
special = "!@#$%^&*()_+-=[]{}|;:,.<>?"
55+
56+
# Nodrošina vismaz vienu rakstzīmi no visiem
57+
password = [
58+
secrets.choice(lowercase),
59+
secrets.choice(uppercase),
60+
secrets.choice(digits),
61+
secrets.choice(special)
62+
]
63+
64+
# Iepilda pārējo ar random rakstzīmēm
65+
all_chars = lowercase + uppercase + digits + special
66+
remaining_length = length - len(password)
67+
password.extend(secrets.choice(all_chars) for _ in range(remaining_length))
68+
69+
# Sajauc paroli
70+
password_list = list(password)
71+
secrets.SystemRandom().shuffle(password_list)
72+
73+
final_password = ''.join(password_list)
74+
75+
# Nokopē paroli ja tas ir nepieciešams
76+
if copy_to_clipboard:
77+
pyperclip.copy(final_password)
78+
79+
return final_password
80+
81+
def generate_key(self, password: str, salt: bytes = None) -> bytes:
82+
# Izveido šifrēšanas atslēgu no paroles izmantojot PBKDF2
83+
if salt is None:
84+
salt = secrets.token_bytes(16)
85+
86+
kdf = PBKDF2HMAC(
87+
algorithm=hashes.SHA256(),
88+
length=32,
89+
salt=salt,
90+
iterations=100000,
91+
)
92+
key = base64.urlsafe_b64encode(kdf.derive(password.encode()))
93+
return key, salt
94+
95+
def hash_password(self, password: str, salt: bytes = None) -> tuple:
96+
# Hasho paroli ar saltu izmantojot SHA-256
97+
if salt is None:
98+
salt = secrets.token_bytes(16)
99+
100+
hasher = hashlib.sha256()
101+
hasher.update(salt + password.encode())
102+
password_hash = hasher.hexdigest()
103+
104+
return password_hash, salt
105+
106+
def initialize_master_password(self, master_password: str):
107+
# Iestata master paroli pirmo reizi
108+
conn = sqlite3.connect(self.database_name)
109+
cursor = conn.cursor()
110+
111+
# Pārbauda vai master parole jau eksistē
112+
cursor.execute("SELECT COUNT(*) FROM master_password")
113+
if cursor.fetchone()[0] > 0:
114+
raise Exception("Master parole jau inicializēta")
115+
116+
# Hasho master paroli ar jaunu saltu
117+
password_hash, salt = self.hash_password(master_password)
118+
119+
# Glabā hashu un saltu
120+
cursor.execute(
121+
"INSERT INTO master_password (password_hash, salt) VALUES (?, ?)",
122+
(password_hash, base64.b64encode(salt).decode())
123+
)
124+
125+
conn.commit()
126+
conn.close()
127+
128+
# Uzāk šifrēšanas atslēgu
129+
self.key, _ = self.generate_key(master_password, salt)
130+
self.cipher_suite = Fernet(self.key)
131+
132+
def unlock(self, master_password: str) -> bool:
133+
# Pārbaude master paroli un uzsāk šifrēšanas atslēgu
134+
conn = sqlite3.connect(self.database_name)
135+
cursor = conn.cursor()
136+
137+
cursor.execute("SELECT password_hash, salt FROM master_password")
138+
stored_hash, stored_salt = cursor.fetchone()
139+
stored_salt = base64.b64decode(stored_salt)
140+
141+
# Pārbauda paroli
142+
password_hash, _ = self.hash_password(master_password, stored_salt)
143+
if password_hash != stored_hash:
144+
conn.close()
145+
return False
146+
147+
# Uzsāk šifrēsanas atslēgu
148+
self.key, _ = self.generate_key(master_password, stored_salt)
149+
self.cipher_suite = Fernet(self.key)
150+
151+
conn.close()
152+
return True
153+
154+
def add_password(self, service: str, username: str, password: str):
155+
# Pievieno jaunu paroli
156+
if not self.cipher_suite:
157+
raise Exception("Paroļu pārvaldnieks ir slēgts")
158+
159+
encrypted_password = self.cipher_suite.encrypt(password.encode())
160+
161+
conn = sqlite3.connect(self.database_name)
162+
cursor = conn.cursor()
163+
164+
cursor.execute(
165+
"INSERT INTO passwords (service, username, encrypted_password) VALUES (?, ?, ?)",
166+
(service, username, encrypted_password.decode())
167+
)
168+
169+
conn.commit()
170+
conn.close()
171+
172+
def get_password(self, service: str, username: str) -> str:
173+
# Ņem paroli priekš specifiskā pakalpojuma un lietotājvārda
174+
if not self.cipher_suite:
175+
raise Exception("Paroļu pārvaldnieks ir slēgts")
176+
177+
conn = sqlite3.connect(self.database_name)
178+
cursor = conn.cursor()
179+
180+
cursor.execute(
181+
"SELECT encrypted_password FROM passwords WHERE service = ? AND username = ?",
182+
(service, username)
183+
)
184+
185+
result = cursor.fetchone()
186+
if not result:
187+
conn.close()
188+
raise Exception("Parole nav atrasta")
189+
190+
encrypted_password = result[0]
191+
decrypted_password = self.cipher_suite.decrypt(encrypted_password.encode()).decode()
192+
193+
conn.close()
194+
return decrypted_password
195+
196+
def list_services(self) -> list:
197+
# Norāda visus glabātos pakalpojumus un lietotājvārdus
198+
conn = sqlite3.connect(self.database_name)
199+
cursor = conn.cursor()
200+
201+
cursor.execute("SELECT service, username FROM passwords")
202+
services = cursor.fetchall()
203+
204+
conn.close()
205+
return services
206+
207+
def main():
208+
# Mēģina importēt pyperclip, ja datorā tas nav instalēts tad to izprintē
209+
try:
210+
import pyperclip
211+
except ImportError:
212+
print("Pyperclip bibliotēka ir nepieciešama priekš kopēšanas funkcionalitātes")
213+
print("Lūdzu instalējat to izmantojot: pip install pyperclip")
214+
return
215+
216+
pm = PasswordManager()
217+
218+
# Pārbauda vai master parolei vajag būt uzsāktai
219+
conn = sqlite3.connect(pm.database_name)
220+
cursor = conn.cursor()
221+
cursor.execute("SELECT COUNT(*) FROM master_password")
222+
is_initialized = cursor.fetchone()[0] > 0
223+
conn.close()
224+
225+
if not is_initialized:
226+
print("Inicializējiet savu paroļu pārvaldnieku:")
227+
master_password = getpass.getpass("Izveidojiet master paroli: ")
228+
confirm_password = getpass.getpass("Apstipriniet galveno paroli: ")
229+
230+
if master_password != confirm_password:
231+
print("Paroles nesakrīt")
232+
return
233+
234+
pm.initialize_master_password(master_password)
235+
print("Master parole veiksmīgi inicializēta!")
236+
237+
# Galvenais loops
238+
while True:
239+
if not pm.cipher_suite:
240+
master_password = getpass.getpass("Ievadiet master paroli: ")
241+
if not pm.unlock(master_password):
242+
print("Nederīga master parole!")
243+
continue
244+
245+
print("\n1. Pievienot paroli")
246+
print("2. Dabūt paroli")
247+
print("3. Izveidot drošu paroli")
248+
print("4. Norādīt glabātos datus")
249+
print("5. Iziet")
250+
251+
choice = input("\nIzvēlies opciju: ")
252+
253+
try:
254+
if choice == "1":
255+
service = input("\nPakalpojums: ")
256+
username = input("Lietotājvārds: ")
257+
use_generated = input("Izmantot drošu paroli? (y/n): ").lower() == 'y'
258+
259+
if use_generated:
260+
length = int(input("Password length (minimum 8): "))
261+
password = pm.generate_password(length)
262+
print(f"Izveidotā parole: {password}")
263+
print("Parole tika nokopēta!")
264+
else:
265+
password = getpass.getpass("Parole: ")
266+
267+
pm.add_password(service, username, password)
268+
print("Parole tika pievienota!")
269+
270+
elif choice == "2":
271+
service = input("\nPakalpojums: ")
272+
username = input("Lietotajvards: ")
273+
password = pm.get_password(service, username)
274+
pyperclip.copy(password)
275+
print(f"Parole: {password}")
276+
print("Parole tika nokopēta!")
277+
278+
elif choice == "3":
279+
length = int(input("Paroles garums (minimums 8): "))
280+
password = pm.generate_password(length)
281+
print(f"Izveidotā parole: {password}")
282+
print("Parole tika nokopēta!")
283+
284+
elif choice == "4":
285+
services = pm.list_services()
286+
print("\nGlabātie dati:")
287+
for service, username in services:
288+
print(f"Pakalpojums: {service}, Lietotājvārds: {username}")
289+
290+
elif choice == "5":
291+
print("Uz redzēšanos!")
292+
break
293+
294+
else:
295+
print("Nederīga opcija!")
296+
297+
# Ja kaut kas gāja greizi tad izprintēt kas notikās
298+
except Exception as e:
299+
print(f"Error: {e}")
300+
301+
# Lai šo var izmantot citās programmās
302+
if __name__ == "__main__":
303+
main()

requirements.txt

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
bcrypt==4.2.1
2+
capstone==6.0.0a2
3+
certifi==2024.12.14
4+
cffi==1.17.1
5+
charset-normalizer==3.4.1
6+
colorama==0.4.6
7+
colored-traceback==0.4.2
8+
cryptography==44.0.0
9+
docopt==0.6.2
10+
idna==3.10
11+
iniconfig==2.0.0
12+
intervaltree==3.1.0
13+
langdetect==1.0.9
14+
Mako==1.3.8
15+
MarkupSafe==3.0.2
16+
mypy==1.13.0
17+
mypy-extensions==1.0.0
18+
packaging==24.1
19+
paramiko==3.5.0
20+
pipreqs==0.4.13
21+
pluggy==1.5.0
22+
plumbum==1.9.0
23+
psutil==6.1.1
24+
pwntools==4.13.1
25+
pycparser==2.22
26+
pyelftools==0.31
27+
Pygments==2.18.0
28+
PyNaCl==1.5.0
29+
pyperclip==1.9.0
30+
pyserial==3.5
31+
PySocks==1.7.1
32+
pytest==8.3.3
33+
python-dateutil==2.9.0.post0
34+
pywin32==308
35+
requests==2.32.3
36+
ROPGadget==7.5
37+
rpyc==6.0.1
38+
six==1.17.0
39+
sortedcontainers==2.4.0
40+
typing_extensions==4.12.2
41+
unicorn==2.1.1
42+
unix-ar==0.2.1
43+
urllib3==2.3.0
44+
yarg==0.1.10
45+
zstandard==0.23.0

0 commit comments

Comments
 (0)