Untitled
unknown
python
9 months ago
3.9 kB
8
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