secure-password-manager 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,5 @@
1
+ """Secure Password Manager package."""
2
+ from secure_password_manager.core import PasswordManager
3
+
4
+ __version__ = "0.1.0"
5
+ __all__ = ["PasswordManager"]
@@ -0,0 +1,3 @@
1
+ """Core functionality for the password manager."""
2
+ # Move the entire PasswordManager class here from your original file
3
+ # Remove the main() function as it will go in cli.py
@@ -0,0 +1,252 @@
1
+ import hashlib
2
+ import os
3
+ from typing import Optional, Tuple, List
4
+ import base64
5
+ from cryptography.fernet import Fernet
6
+ from cryptography.hazmat.primitives import hashes
7
+ from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
8
+ import sqlite3
9
+ from datetime import datetime
10
+ import getpass
11
+
12
+ class PasswordManager:
13
+ def __init__(self, db_path: str = "passwords.db"):
14
+ """Initialize the password manager with database connection"""
15
+ self.db_path = db_path
16
+ self.key = Fernet.generate_key()
17
+ self.cipher_suite = Fernet(self.key)
18
+ self._init_database()
19
+
20
+ def _init_database(self):
21
+ """Initialize SQLite database with required tables"""
22
+ with sqlite3.connect(self.db_path) as conn:
23
+ cursor = conn.cursor()
24
+
25
+ # Create users table
26
+ cursor.execute('''
27
+ CREATE TABLE IF NOT EXISTS users (
28
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
29
+ username TEXT UNIQUE NOT NULL,
30
+ password_hash TEXT NOT NULL,
31
+ salt BLOB NOT NULL,
32
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
33
+ last_login TIMESTAMP
34
+ )
35
+ ''')
36
+
37
+ # Create stored_passwords table
38
+ cursor.execute('''
39
+ CREATE TABLE IF NOT EXISTS stored_passwords (
40
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
41
+ user_id INTEGER NOT NULL,
42
+ service_name TEXT NOT NULL,
43
+ username TEXT NOT NULL,
44
+ encrypted_password BLOB NOT NULL,
45
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
46
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
47
+ FOREIGN KEY (user_id) REFERENCES users (id),
48
+ UNIQUE (user_id, service_name)
49
+ )
50
+ ''')
51
+
52
+ conn.commit()
53
+
54
+ def hash_password(self, password: str, salt: Optional[bytes] = None) -> tuple[str, bytes]:
55
+ """Hash a password using PBKDF2 with a random salt"""
56
+ if salt is None:
57
+ salt = os.urandom(16)
58
+
59
+ kdf = PBKDF2HMAC(
60
+ algorithm=hashes.SHA256(),
61
+ length=32,
62
+ salt=salt,
63
+ iterations=100000,
64
+ )
65
+
66
+ key = base64.b64encode(kdf.derive(password.encode()))
67
+ return key.decode('utf-8'), salt
68
+
69
+ def register_user(self, username: str, master_password: str) -> bool:
70
+ """Register a new user with a master password"""
71
+ try:
72
+ hashed_password, salt = self.hash_password(master_password)
73
+
74
+ with sqlite3.connect(self.db_path) as conn:
75
+ cursor = conn.cursor()
76
+ cursor.execute(
77
+ 'INSERT INTO users (username, password_hash, salt) VALUES (?, ?, ?)',
78
+ (username, hashed_password, salt)
79
+ )
80
+ conn.commit()
81
+ return True
82
+ except sqlite3.IntegrityError:
83
+ return False # Username already exists
84
+
85
+ def authenticate_user(self, username: str, password: str) -> Optional[int]:
86
+ """Authenticate a user and return user_id if successful"""
87
+ with sqlite3.connect(self.db_path) as conn:
88
+ cursor = conn.cursor()
89
+ cursor.execute(
90
+ 'SELECT id, password_hash, salt FROM users WHERE username = ?',
91
+ (username,)
92
+ )
93
+ result = cursor.fetchone()
94
+
95
+ if result:
96
+ user_id, stored_hash, salt = result
97
+ hashed_password, _ = self.hash_password(password, salt)
98
+
99
+ if stored_hash == hashed_password:
100
+ # Update last login timestamp
101
+ cursor.execute(
102
+ 'UPDATE users SET last_login = CURRENT_TIMESTAMP WHERE id = ?',
103
+ (user_id,)
104
+ )
105
+ conn.commit()
106
+ return user_id
107
+ return None
108
+
109
+ def store_password(self, user_id: int, service_name: str, username: str, password: str) -> bool:
110
+ """Store an encrypted password for a service"""
111
+ encrypted_password = self.cipher_suite.encrypt(password.encode())
112
+
113
+ try:
114
+ with sqlite3.connect(self.db_path) as conn:
115
+ cursor = conn.cursor()
116
+ cursor.execute('''
117
+ INSERT OR REPLACE INTO stored_passwords
118
+ (user_id, service_name, username, encrypted_password, updated_at)
119
+ VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP)
120
+ ''', (user_id, service_name, username, encrypted_password))
121
+ conn.commit()
122
+ return True
123
+ except sqlite3.Error:
124
+ return False
125
+
126
+ def get_password(self, user_id: int, service_name: str) -> Optional[Tuple[str, str]]:
127
+ """Retrieve a stored password for a service"""
128
+ with sqlite3.connect(self.db_path) as conn:
129
+ cursor = conn.cursor()
130
+ cursor.execute(
131
+ 'SELECT username, encrypted_password FROM stored_passwords WHERE user_id = ? AND service_name = ?',
132
+ (user_id, service_name)
133
+ )
134
+ result = cursor.fetchone()
135
+
136
+ if result:
137
+ username, encrypted_password = result
138
+ decrypted_password = self.cipher_suite.decrypt(encrypted_password).decode()
139
+ return username, decrypted_password
140
+ return None
141
+
142
+ def list_services(self, user_id: int) -> List[Tuple[str, str, str]]:
143
+ """List all stored services for a user"""
144
+ with sqlite3.connect(self.db_path) as conn:
145
+ cursor = conn.cursor()
146
+ cursor.execute(
147
+ '''SELECT service_name, username, created_at
148
+ FROM stored_passwords
149
+ WHERE user_id = ?
150
+ ORDER BY service_name''',
151
+ (user_id,)
152
+ )
153
+ return cursor.fetchall()
154
+
155
+ def delete_password(self, user_id: int, service_name: str) -> bool:
156
+ """Delete a stored password for a service"""
157
+ try:
158
+ with sqlite3.connect(self.db_path) as conn:
159
+ cursor = conn.cursor()
160
+ cursor.execute(
161
+ 'DELETE FROM stored_passwords WHERE user_id = ? AND service_name = ?',
162
+ (user_id, service_name)
163
+ )
164
+ conn.commit()
165
+ return cursor.rowcount > 0
166
+ except sqlite3.Error:
167
+ return False
168
+
169
+ def main():
170
+ """Main function demonstrating the password manager usage"""
171
+ pm = PasswordManager()
172
+
173
+ while True:
174
+ print("\nPassword Manager")
175
+ print("1. Register")
176
+ print("2. Login")
177
+ print("3. Exit")
178
+
179
+ choice = input("Choose an option: ")
180
+
181
+ if choice == "1":
182
+ username = input("Enter username: ")
183
+ password = getpass.getpass("Enter master password: ")
184
+
185
+ if pm.register_user(username, password):
186
+ print("Registration successful!")
187
+ else:
188
+ print("Username already exists!")
189
+
190
+ elif choice == "2":
191
+ username = input("Enter username: ")
192
+ password = getpass.getpass("Enter master password: ")
193
+
194
+ user_id = pm.authenticate_user(username, password)
195
+ if user_id:
196
+ while True:
197
+ print("\nPassword Management")
198
+ print("1. Store password")
199
+ print("2. Get password")
200
+ print("3. List services")
201
+ print("4. Delete password")
202
+ print("5. Logout")
203
+
204
+ subchoice = input("Choose an option: ")
205
+
206
+ if subchoice == "1":
207
+ service = input("Enter service name: ")
208
+ service_username = input("Enter username for service: ")
209
+ service_password = getpass.getpass("Enter password for service: ")
210
+
211
+ if pm.store_password(user_id, service, service_username, service_password):
212
+ print("Password stored successfully!")
213
+ else:
214
+ print("Error storing password!")
215
+
216
+ elif subchoice == "2":
217
+ service = input("Enter service name: ")
218
+ result = pm.get_password(user_id, service)
219
+
220
+ if result:
221
+ username, password = result
222
+ print(f"Username: {username}")
223
+ print(f"Password: {password}")
224
+ else:
225
+ print("Service not found!")
226
+
227
+ elif subchoice == "3":
228
+ services = pm.list_services(user_id)
229
+ if services:
230
+ print("\nStored Services:")
231
+ for service, username, created_at in services:
232
+ print(f"Service: {service}, Username: {username}, Created: {created_at}")
233
+ else:
234
+ print("No stored passwords!")
235
+
236
+ elif subchoice == "4":
237
+ service = input("Enter service name: ")
238
+ if pm.delete_password(user_id, service):
239
+ print("Password deleted successfully!")
240
+ else:
241
+ print("Service not found!")
242
+
243
+ elif subchoice == "5":
244
+ break
245
+ else:
246
+ print("Authentication failed!")
247
+
248
+ elif choice == "3":
249
+ break
250
+
251
+ if __name__ == "__main__":
252
+ main()
@@ -0,0 +1,79 @@
1
+ Metadata-Version: 2.2
2
+ Name: secure-password-manager
3
+ Version: 0.1.0
4
+ Summary: A secure password manager with SQLite storage
5
+ Author-email: Nirjhar <chatnirjhar12345@gmail.com>
6
+ Project-URL: Homepage, https://github.com/nirjhr/secure-password-manager
7
+ Project-URL: Repository, https://github.com/nirjhr/secure-password-manager.git
8
+ Keywords: password,security,encryption,manager
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: End Users/Desktop
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.7
14
+ Classifier: Programming Language :: Python :: 3.8
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Topic :: Security
18
+ Requires-Python: >=3.7
19
+ Description-Content-Type: text/markdown
20
+ Requires-Dist: cryptography>=36.0.0
21
+
22
+ # Secure Password Manager
23
+
24
+ A secure password manager that uses SQLite for storage and strong encryption for password protection.
25
+
26
+ ## Features
27
+
28
+ - User registration and authentication
29
+ - Secure password storage using Fernet encryption
30
+ - SQLite database backend
31
+ - Command-line interface
32
+ - List, add, retrieve, and delete passwords
33
+ - Master password protection
34
+
35
+ ## Installation
36
+
37
+ ```bash
38
+ pip install secure-password-manager
39
+ ```
40
+
41
+ ## Usage
42
+
43
+ ```python
44
+ from secure_password_manager import PasswordManager
45
+
46
+ # Create a new password manager instance
47
+ pm = PasswordManager()
48
+
49
+ # Register a new user
50
+ pm.register_user("username", "master_password")
51
+
52
+ # Authenticate and get user ID
53
+ user_id = pm.authenticate_user("username", "master_password")
54
+
55
+ # Store a password
56
+ pm.store_password(user_id, "github.com", "githubuser", "password123")
57
+
58
+ # Retrieve a password
59
+ username, password = pm.get_password(user_id, "github.com")
60
+ ```
61
+
62
+ ## Command Line Interface
63
+
64
+ You can also use the password manager from the command line:
65
+
66
+ ```bash
67
+ password-manager
68
+ ```
69
+
70
+ ## Security
71
+
72
+ - Passwords are encrypted using Fernet (symmetric encryption)
73
+ - Master password is hashed using PBKDF2 with SHA256
74
+ - Secure random salt generation
75
+ - SQLite database for persistent storage
76
+
77
+ ## License
78
+
79
+ MIT License - see LICENSE file for details.
@@ -0,0 +1,8 @@
1
+ secure_password_manager/__init__.py,sha256=7F40T6wcxwbyeOwb8PdJbDAsfr1rFYwSZ3fxYYteLfA,152
2
+ secure_password_manager/core.py,sha256=J7WOYj18ZKKbqp_3oyuDu-cocKZAyl3Mmf2WKDoQTBc,174
3
+ secure_password_manager/crypt.py,sha256=x5AkFk8eeJeFczRX6WO48kAM1L6TAbQLZv8N0S6gbYs,10435
4
+ secure_password_manager-0.1.0.dist-info/METADATA,sha256=IClN58ZiTC_5UFUKN3FRbVfM6IEV93gqkrdAV8JOyps,2256
5
+ secure_password_manager-0.1.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
6
+ secure_password_manager-0.1.0.dist-info/entry_points.txt,sha256=L7misCz3k7EUW6daiun775lPVf5P7Mrn_1vBCaLeWPY,70
7
+ secure_password_manager-0.1.0.dist-info/top_level.txt,sha256=QbgksLZA9vrdQng6SUkTuk8wdjCTm2eid9bBP-l_1Z8,24
8
+ secure_password_manager-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (75.8.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ password-manager = secure_password_manager.cli:main
@@ -0,0 +1 @@
1
+ secure_password_manager