This repository has been archived on 2023-08-08. You can view files and clone it, but cannot push or open issues or pull requests.
PassManager/src/cryptography/other_accounts.py

63 lines
2.1 KiB
Python

import base64
import os
from typing import Iterator
from cryptography.fernet import Fernet
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
def _generate_key(salt: bytes, master_pass: bytes) -> bytes:
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=salt,
iterations=100000,
backend=default_backend(),
)
key = base64.urlsafe_b64encode(kdf.derive(master_pass))
return key
def encrypt_account_info(
login: str, passwd: str, master_pass: str
) -> tuple[bytes, bytes, bytes]:
"""Encrypts login and password of a user using their master
password as a key.
Returns a tuple of encrypted login, password and salt"""
salt = os.urandom(64)
key = _generate_key(salt, master_pass.encode("utf-8"))
f = Fernet(key)
enc_login = base64.urlsafe_b64decode(f.encrypt(login.encode("utf-8")))
enc_password = base64.urlsafe_b64decode(f.encrypt(passwd.encode("utf-8")))
return (enc_login, enc_password, salt)
def decrypt_account_info(
enc_login: bytes,
enc_pass: bytes,
master_pass: str,
salt: bytes,
) -> tuple[str, str]:
"""Decrypts login and password using their
master password as a key.
Returns a tuple of decrypted login and password"""
key = _generate_key(salt, master_pass.encode("utf-8"))
f = Fernet(key)
login = f.decrypt(base64.urlsafe_b64encode(enc_login)).decode("utf-8")
password = f.decrypt(base64.urlsafe_b64encode(enc_pass)).decode("utf-8")
return (login, password)
def decrypt_multiple(
accounts: Iterator[tuple[str, bytes, bytes, bytes]], master_pass: str
) -> Iterator[tuple[str, str, str]]:
"""Gets an iterator of tuples, where values represent account's name, salt,
encrypted login and encrypted password.
Return an iterator of names, logins and passwords as a tuple"""
for account in accounts:
name, salt, enc_login, enc_passwd = account
login, passwd = decrypt_account_info(enc_login, enc_passwd, master_pass, salt)
yield (name, login, passwd)