Untitled
unknown
python
2 months ago
3.9 kB
6
Indexable
#!/usr/bin/env python3 import os import json import base64 import argparse from getpass import getpass from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC from cryptography.fernet import Fernet SALT_FILE = 'salt.bin' DATA_FILE = 'passwords.json.enc' ITERATIONS = 100000 def get_salt(): if os.path.exists(SALT_FILE): with open(SALT_FILE, 'rb') as f: return f.read() else: salt = os.urandom(16) with open(SALT_FILE, 'wb') as f: f.write(salt) return salt def derive_key(master_password, salt): kdf = PBKDF2HMAC( algorithm=hashes.SHA256(), length=32, salt=salt, iterations=ITERATIONS, ) return base64.urlsafe_b64encode(kdf.derive(master_password.encode())) def load_data(fernet): if os.path.exists(DATA_FILE): with open(DATA_FILE, 'rb') as f: encrypted = f.read() try: decrypted = fernet.decrypt(encrypted) return json.loads(decrypted.decode()) except Exception: print("Error al descifrar el archivo. ¿Contraseña maestra incorrecta?") exit(1) else: return {} def save_data(fernet, data): encrypted = fernet.encrypt(json.dumps(data).encode()) with open(DATA_FILE, 'wb') as f: f.write(encrypted) def main(): parser = argparse.ArgumentParser(description="Gestor de contraseñas básico") subparsers = parser.add_subparsers(dest='command', help='Comandos disponibles') parser_add = subparsers.add_parser('add', help='Añadir datos de un servicio') parser_add.add_argument('service', help='Nombre del servicio') parser_get = subparsers.add_parser('get', help='Obtener datos de un servicio') parser_get.add_argument('service', help='Nombre del servicio') parser_list = subparsers.add_parser('list', help='Listar servicios') parser_delete = subparsers.add_parser('delete', help='Eliminar un servicio') parser_delete.add_argument('service', help='Nombre del servicio') args = parser.parse_args() master = getpass("Contraseña maestra: ") salt = get_salt() key = derive_key(master, salt) fernet = Fernet(key) data = load_data(fernet) if args.command == 'add': print("Introduce los datos para el servicio.") print("Escribe el nombre del campo y su valor.") print("Cuando quieras introducir la contraseña, escribe 'pass' como nombre del campo.") fields = {} while True: field = input("Campo (o 'pass' para contraseña): ").strip() if field.lower() == 'pass': fields['password'] = getpass("Contraseña del servicio: ") break else: value = input(f"Valor para {field}: ") fields[field] = value data[args.service] = fields save_data(fernet, data) print(f"Datos para '{args.service}' guardados.") elif args.command == 'get': service_data = data.get(args.service) if service_data: print(f"Datos para {args.service}:") for k, v in service_data.items(): print(f"{k}: {v}") else: print("Servicio no encontrado.") elif args.command == 'list': if data: print("Servicios almacenados:") for s in data.keys(): print(f" - {s}") else: print("No hay servicios almacenados.") elif args.command == 'delete': if args.service in data: del data[args.service] save_data(fernet, data) print(f"Servicio '{args.service}' eliminado.") else: print("Servicio no encontrado.") else: parser.print_help() if __name__ == '__main__': main()
Editor is loading...
Leave a Comment