Switched to the ChaCha20Poly1305 encryption algorithm for better security
This commit is contained in:
parent
3686195396
commit
c051c14f1f
@ -1,17 +1,22 @@
|
|||||||
import base64
|
|
||||||
import os
|
import os
|
||||||
|
from typing import Self
|
||||||
|
|
||||||
from cryptography.fernet import Fernet
|
|
||||||
from cryptography.hazmat.backends import default_backend
|
from cryptography.hazmat.backends import default_backend
|
||||||
from cryptography.hazmat.primitives import hashes
|
from cryptography.hazmat.primitives import hashes
|
||||||
|
from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305
|
||||||
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
|
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
|
||||||
|
|
||||||
from ..db.models import Account
|
from ..db.models import Account
|
||||||
from ..decrypted_account import DecryptedAccount
|
from ..decrypted_account import DecryptedAccount
|
||||||
|
|
||||||
|
|
||||||
def _generate_key(salt: bytes, master_pass: bytes) -> bytes:
|
class Cipher:
|
||||||
"""Generates key for fernet encryption"""
|
def __init__(self, key: bytes) -> None:
|
||||||
|
self._chacha = ChaCha20Poly1305(key)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def generate_cipher(cls, salt: bytes, password: bytes) -> Self:
|
||||||
|
"""Generates cipher which uses key derived from a given password"""
|
||||||
kdf = PBKDF2HMAC(
|
kdf = PBKDF2HMAC(
|
||||||
algorithm=hashes.SHA256(),
|
algorithm=hashes.SHA256(),
|
||||||
length=32,
|
length=32,
|
||||||
@ -19,8 +24,22 @@ def _generate_key(salt: bytes, master_pass: bytes) -> bytes:
|
|||||||
iterations=100000,
|
iterations=100000,
|
||||||
backend=default_backend(),
|
backend=default_backend(),
|
||||||
)
|
)
|
||||||
key = base64.urlsafe_b64encode(kdf.derive(master_pass))
|
return cls(kdf.derive(password))
|
||||||
return key
|
|
||||||
|
def encrypt(self, data: bytes) -> bytes:
|
||||||
|
nonce = os.urandom(12)
|
||||||
|
return nonce + self._chacha.encrypt(
|
||||||
|
nonce,
|
||||||
|
data,
|
||||||
|
associated_data=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
def decrypt(self, data: bytes) -> bytes:
|
||||||
|
return self._chacha.decrypt(
|
||||||
|
nonce=data[:12],
|
||||||
|
data=data[12:],
|
||||||
|
associated_data=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def encrypt(
|
def encrypt(
|
||||||
@ -29,15 +48,10 @@ def encrypt(
|
|||||||
) -> Account:
|
) -> Account:
|
||||||
"""Encrypts account using master password and returns Account object"""
|
"""Encrypts account using master password and returns Account object"""
|
||||||
salt = os.urandom(64)
|
salt = os.urandom(64)
|
||||||
key = _generate_key(salt, master_pass.encode("utf-8"))
|
cipher = Cipher.generate_cipher(salt, master_pass.encode("utf-8"))
|
||||||
f = Fernet(key)
|
|
||||||
|
|
||||||
enc_login = base64.urlsafe_b64decode(
|
enc_login = cipher.encrypt(account.login.encode("utf-8"))
|
||||||
f.encrypt(account.login.encode("utf-8")),
|
enc_password = cipher.encrypt(account.password.encode("utf-8"))
|
||||||
)
|
|
||||||
enc_password = base64.urlsafe_b64decode(
|
|
||||||
f.encrypt(account.password.encode("utf-8")),
|
|
||||||
)
|
|
||||||
|
|
||||||
return Account(
|
return Account(
|
||||||
user_id=account.user_id,
|
user_id=account.user_id,
|
||||||
@ -54,15 +68,10 @@ def decrypt(
|
|||||||
) -> DecryptedAccount:
|
) -> DecryptedAccount:
|
||||||
"""Decrypts account using master password and returns
|
"""Decrypts account using master password and returns
|
||||||
DecryptedAccount object"""
|
DecryptedAccount object"""
|
||||||
key = _generate_key(account.salt, master_pass.encode("utf-8"))
|
cipher = Cipher.generate_cipher(account.salt, master_pass.encode("utf-8"))
|
||||||
f = Fernet(key)
|
|
||||||
|
|
||||||
login = f.decrypt(
|
login = cipher.decrypt(account.enc_login).decode("utf-8")
|
||||||
base64.urlsafe_b64encode(account.enc_login),
|
password = cipher.decrypt(account.enc_password).decode("utf-8")
|
||||||
).decode("utf-8")
|
|
||||||
password = f.decrypt(
|
|
||||||
base64.urlsafe_b64encode(account.enc_password),
|
|
||||||
).decode("utf-8")
|
|
||||||
|
|
||||||
return DecryptedAccount(
|
return DecryptedAccount(
|
||||||
user_id=account.user_id,
|
user_id=account.user_id,
|
||||||
|
Reference in New Issue
Block a user