def _verify_password(self, password, derived_password, salt): """ :param password: clear text received from the user that wants to be authenticated :param password: str :return: true if password received matches the one stored :rtype: bool """ derived_password = b64decode(derived_password) salt = b64decode(salt) password = bytes(password, "utf-8") kdf = Scrypt( salt = salt, length = 32, n = 2**14, r = 8, p = 1, backend = default_backend() ) try: kdf.verify(password, derived_password) return True except InvalidKey: return False
def api_token(): user = request.form["user"] password = request.form["password"].encode("utf8") conn = sqlite3.connect("user.db") c = conn.cursor() result = c.execute( "SELECT salt, pass, admin from users where user=?", [user] ).fetchone() conn.close() if result is None: abort(403) salt, spass, admin = result kdf = Scrypt( salt=salt, length=32, n=2**14, r=8, p=1, backend=default_backend() ) try: kdf.verify(password, spass) except InvalidKey: print("invalid password") abort(403) payload = json.dumps({"admin": admin, "user": user}, sort_keys=True) # encrypt the payload return _encrypt(payload)
def verify_password_scrypt(password_to_verify: bytes, derived_password: bytes, password_salt: bytes): """Check if the input password correspond to the instance derived password and salt. :param password_to_verify: The password to verify as bytes. :param derived_password: The derived password used to verify the given password as bytes. :param password_salt: The salt used to derive the password as bytes. :return: True if is verified, else False. """ password_correct = False kdf = Scrypt( salt=password_salt, length=32, n=2**14, r=8, p=1, ) try: kdf.verify(password_to_verify, derived_password) password_correct = True except InvalidKey: pass except AlreadyFinalized: pass return password_correct
def verify_hash(self, password): backend = default_backend() kdf = Scrypt(salt=self.salt, length=32, n=2**14, r=8, p=1, backend=backend) kdf.verify(password, self.password_hash)
def enterFolderPwd(self, folder_path): #user has to enter folder password #compared to stored hash #repeated until the correct password was entered while True: folder_pwd = input( "This is your first access to this folder. Please enter the folder password: "******"salt"], length=32, n=2**4, r=8, p=1, backend=default_backend()) try: kdf.verify(folder_pwd.encode(), self.pwd_db[folder_path]) except InvalidKey: print("The password is wrong.") continue else: break print("Folder password will be stored for access in the future.") #get correct user password to encrypt the folder password for this user while True: pwd = input("Please enter the user password: "******"salt"], length=32, n=2**4, r=8, p=1, backend=default_backend()) try: kdf.verify(pwd.encode(), self.users[self.currentUser]["pwd"]) except InvalidKey: print("The password is wrong.") continue else: break #encrypt the folder password using the user password and store it kdf = PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt=self.users[self.currentUser]["salt"], iterations=100000, backend=default_backend()) pwd_key = kdf.derive(pwd.encode()) f = Fernet(urlsafe_b64encode(pwd_key)) encrypted_folder_pwd = f.encrypt(folder_pwd.encode()) self.users[self.currentUser]["folders"].update( {folder_path: encrypted_folder_pwd})
def test_invalid_verify(self, backend): password = b"password" work_factor = 1024 block_size = 8 parallelization_factor = 16 length = 64 salt = b"NaCl" derived_key = b"fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e773" scrypt = Scrypt(salt, length, work_factor, block_size, parallelization_factor, backend) with pytest.raises(InvalidKey): scrypt.verify(password, binascii.unhexlify(derived_key))
class Login(): """Class that creates a simple password protection to th dahsboard""" def __init__(self, pw_hashed, salt, callback, *cback_args, **cback_kwargs): """ pw_hashed: binary string This is the string that must be entered to access the dahsboard. salt: binary string The salt used for the hashing process of the password callback: function Function to call if the user enters the right password. cback_args: any the arguments for your callback function (e.g. "my_title") cback_kwargs: any the named arguments for your callback function (e.g. name='Bob') """ self.password = pw_hashed self.callback = callback self.cback_args = cback_args self.cback_kwargs = cback_kwargs self._backend = default_backend() self.salt = salt self.password_text = bk.models.Div( text="Enter the password then press OK") self.password_field = bk.models.widgets.inputs.PasswordInput() self.wrong_password_text = bk.models.Div( text="Wrong password. Try again.") self.confirm_button = bk.models.Button(label="OK", button_type="primary") self.confirm_button.on_click(self.verify_password) self.col = pn.Column(self.password_text, self.password_field, self.confirm_button) # If i did not use Panel, it would be like this: # self.col = bk.models.Column(self.password_text, # self.password_field, self.confirm_button) def verify_password(self, *e): self.kdf = Scrypt(salt=self.salt, length=32, n=2**14, r=8, p=1, backend=self._backend) try: self.kdf.verify(str(self.password_field.value).encode(), self.password) self.password_text.text = "Success" self.callback(*self.cback_args, **self.cback_kwargs) except InvalidKey: if self.wrong_password_text not in self.col: self.col.append(self.wrong_password_text)
def verify_scrypt_key(salt, passphrase, key_bytes): passphrase_bytes = bytes(passphrase, 'utf8') salt_bytes = bytes(salt, 'utf8') # Verify key kdf = Scrypt(salt=salt_bytes, length=32, n=2**18, p=1, r=8, backend=default_backend()) try: kdf.verify(passphrase_bytes, key_bytes) except InvalidKey: return False else: return True
async def check_credentials(email: str, password: str, domain: str) -> bool: key_material = password.encode("utf-8") try: user = await User.objects.filter(active=True, email=email, domain=domain).get() expected_key = b64decode(user.password) except NoMatch: debug(f"No active user '{email}' from domain '{domain}' found") key_material = b"Password that 100% not matching, I swear" expected_key = b"Password that 100% not matching, trust me" kdf = Scrypt(conf.SALT, length=32, n=2**16, r=8, p=1) try: kdf.verify(key_material, expected_key) return True except InvalidKey: return False
def verificate_hash_token(access_token: Dict[str, str], jti_token: str) -> bool: resp = False backend = default_backend() token_hashed = Scrypt(salt=binascii.unhexlify(access_token['salt']), length=NUMBER_OF_BYTES, n=SCRYPT_N, r=SCRYPT_R, p=SCRYPT_P, backend=backend) try: token_hashed.verify(binascii.unhexlify(jti_token), binascii.unhexlify(access_token['jti'])) resp = True except InvalidKey: rollbar.report_message('Error: Access token does not match', 'error') return resp
def test_verify(self, backend, params): _skip_if_memory_limited(_MEM_LIMIT, params) password = params["password"] work_factor = int(params["n"]) block_size = int(params["r"]) parallelization_factor = int(params["p"]) length = int(params["length"]) salt = params["salt"] derived_key = params["derived_key"] scrypt = Scrypt( salt, length, work_factor, block_size, parallelization_factor, backend, ) scrypt.verify(password, binascii.unhexlify(derived_key))
def get_passphrase(): if os.path.exists(PASSPHRASE_FILEPATH): prompt = 'Passphrase: ' else: prompt = 'Define passphrase: ' passphrase = getpass(prompt=prompt).encode() if os.path.exists(PASSPHRASE_FILEPATH): with open(SALT_FILEPATH, 'rb') as file: salt = file.read() with open(PASSPHRASE_FILEPATH, 'rb') as file: passphrase_key = file.read() kdf = Scrypt(salt=salt, length=32, n=2**14, r=8, p=1, backend=default_backend()) kdf.verify(passphrase, passphrase_key) else: salt = os.urandom(16) with open(SALT_FILEPATH, 'wb') as file: file.write(salt) kdf = Scrypt(salt=salt, length=32, n=2**14, r=8, p=1, backend=default_backend()) passphrase_key = kdf.derive(passphrase) with open(PASSPHRASE_FILEPATH, 'wb') as file: file.write(passphrase_key) return passphrase
def scrypt_key(password, mcf='', bits=512): """ RFC 7914 recommends values of r=8 and p=1 while scaling n as appropriate for your system. The scrypt paper suggests a minimum value of n=2**14 for interactive logins (t < 100ms), or n=2**20 for more sensitive files (t < 5s). """ if isinstance(password, unicode): password = password.encode('utf-8') if not mcf: salt = os.urandom(16) # NIST SP 800-132 recommends 128-bits or longer cost = 2**14 kdf = Scrypt(salt=salt, length=bits / 8, n=cost, r=8, p=1, backend=default_backend()) key = kdf.derive(password) # Verify key, or derive with specific iterations and/or salt elif mcf[0] == '$': fields = mcf.split('$') if len(fields) > 4 and fields[1] == 'scrypt': if not fields[2]: cost = 2**14 else: cost = int(fields[2]) if not fields[3]: salt = os.urandom(16) else: salt = base64.b64decode(fields[3]) kdf = Scrypt(salt=salt, length=bits / 8, n=cost, r=8, p=1, backend=default_backend()) try: kdf.verify(password, base64.b64decode(fields[4])) except InvalidKey: return '' return '$scrypt$' + str(cost) + '$' + base64.b64encode( salt) + '$' + base64.b64encode(key)
def test_verify(self, backend, params): password = params["password"] work_factor = int(params["n"]) block_size = int(params["r"]) parallelization_factor = int(params["p"]) length = int(params["length"]) salt = params["salt"] derived_key = params["derived_key"] scrypt = Scrypt(salt, length, work_factor, block_size, parallelization_factor, backend) assert scrypt.verify(password, binascii.unhexlify(derived_key)) is None
def crack_scrypt(key, salt): try: salt = unhexlify(sys.argv[1].encode()) key = unhexlify(sys.argv[2].encode()) except binascii.Error: print('Non-hexadecimal data on salt and/or key', file=sys.stderr) return False backend = default_backend() for number in range(10000): kdf = Scrypt(salt=salt, length=32, n=2**14, r=8, p=1, backend=backend) try: kdf.verify(str(number).encode(), key) print('Cracked! Password:', number) break except InvalidKey: pass
def verify_secret_key(password): try: with open(SYM_KEY_PATH, "rb") as file: salt_and_key = file.read() except FileNotFoundError: return False, "No secret key found" salt = salt_and_key[:SALT_SIZE] key = salt_and_key[SALT_SIZE:] length = len(key) kdf = Scrypt(salt=salt, length=length, n=SCRYPT_COST_PARAMETER, r=SCRYPT_BLOCK_SIZE_PARAMETER, p=SCRYPT_PARALLELIZATION_PARAMETER) try: kdf.verify(bytes(password, encoding='utf-8'), key) except InvalidKey: return False, "Invalid key", None except AlreadyFinalized: return False, "Error was encountered during the verification process", None return True, "Password successfully verified", key
def secretGenerator(self) : password = self.readPassword() backend = default_backend() # Salts should be randomly generated salt = os.urandom(16) kdf = Scrypt( salt=salt, length=32, n=2**14, r=8, p=1, backend=backend ) key = kdf.derive(password) # verify kdf = Scrypt( salt=salt, length=32, n=2**14, r=8, p=1, backend=backend ) kdf.verify(password, key) # return the passphrase return key
def login(username, password, **kwargs): conn = sqlite3.connect('db_users.sqlite') conn.set_trace_callback(print) conn.row_factory = sqlite3.Row c = conn.cursor() user = c.execute("SELECT * FROM users WHERE username = ?", (username, )).fetchone() if not user: #print('The user doesnt exists') return False backend = default_backend() kdf = Scrypt(salt=unhexlify(user['salt']), length=32, n=2**14, r=8, p=1, backend=backend) try: kdf.verify(password.encode(), unhexlify(user['password'])) #print('valid') return username except InvalidKey: #print('invalid1') return False except Exception as e: #print('invalid2', e) return False #print('No deberia haber llegado aca') return False
#import os import base64 from cryptography.hazmat.primitives.kdf.scrypt import Scrypt from cryptography.hazmat.backends import default_backend backend = default_backend() #Salt should be generated randomly salt = open("salt.txt", "rb").read() #print(salt) #derive kdf = Scrypt(salt=salt, length=32, n=2**14, r=8, p=1, backend=backend) key = kdf.derive(b"the pass word") newkey = base64.urlsafe_b64encode(key) with open("derivedKey.key", "wb") as deKey: deKey.write(newkey) #print(key) #verify kdf = Scrypt(salt=salt, length=32, n=2**14, r=8, p=1, backend=backend) kdf.verify(b"the pass word", key)
import sys import os import binascii from binascii import unhexlify from cryptography.hazmat.primitives.kdf.scrypt import Scrypt from cryptography.hazmat.backends import default_backend from cryptography.exceptions import InvalidKey password = sys.argv[1].encode() try: salt = unhexlify(sys.argv[2].encode()) key = unhexlify(sys.argv[3].encode()) except binascii.Error: print('Non-hexadecimal data on salt and/or key', file=sys.stderr) sys.exit(1) backend = default_backend() #print(hexlify(key).decode()) # verify kdf = Scrypt(salt=salt, length=32, n=2**14, r=8, p=1, backend=backend) try: kdf.verify(password, key) print('Valid') except InvalidKey: print('Invalid')
from cryptography.hazmat.primitives.kdf.scrypt import Scrypt from cryptography.hazmat.backends import default_backend import os key = b'\x95\xda\nr\x0b\xed\xe8:4Q\xb7\x9f\xf8\xe0\x953\xadBvUN\x17KC\xbd\xdb\x93?:\x91O\x9f' salt = b'\x1dkC;\xda\x11^\xa4zMb\xcfr`\r\x1b' kdf = Scrypt(salt=salt, length=32, r=8, p=1, n=2**14, backend=default_backend()) kdf.verify(b'motherfucking password', key) print("Success! (Exception if mismatch)")
import base64 import os from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.kdf.scrypt import Scrypt from cryptography.hazmat.backends import default_backend salt = os.urandom(16) kdf = Scrypt(salt=salt, length=32, n=2**14, r=8, p=1, backend=default_backend()) #scrytp Derive key key = kdf.derive(b"my password") print base64.b64encode(key) # ANSI X9.63 verify Function kdf = Scrypt(salt=salt, length=32, n=2**14, r=8, p=1, backend=default_backend()) kdf.verify(b"my password", key)
import os from cryptography.hazmat.primitives.kdf.scrypt import Scrypt from cryptography.hazmat.backends import default_backend salt = os.urandom(16) kdf = Scrypt(salt=salt, length=32, n=2**14, r=8, p=1, backend=default_backend()) key = kdf.derive(b"my great password") print("KDF output:", key.hex()) kdf = Scrypt(salt=salt, length=32, n=2**14, r=8, p=1, backend=default_backend()) kdf.verify(b"my great password", key) print("Success! (Exception if mismatch)") # If we got here, we passed print("[PASS]")
import os from cryptography.hazmat.primitives.kdf.scrypt import Scrypt from cryptography.hazmat.backends import default_backend # Generate random salt salt = os.urandom(16) scrypt_config = { "salt": salt, "length": 32, "n": 2**14, "r": 8, "p": 1, "backend": default_backend(), } kdf = Scrypt(**scrypt_config) key = kdf.derive(b"my great password") # Scrypt instances can only be used once kdf2 = Scrypt(**scrypt_config) try: kdf2.verify(b"blblblbl", key) except: print("Wrong password") kdf3 = Scrypt(**scrypt_config) kdf3.verify(b"my great password", key) print("success!")
def addDek(self, file_name, dek, tag, iv): #get folder path by eliminating filename from file path contained in <file_name> folder_path = "/".join(file_name.split("/")[0:-1]) name = file_name.split("/")[-1] print(name) #user has to input user password until the hash of it is equal to the stored user password hash (until the password is correct) while True: pwd = input("user password: "******"salt"], length=32, n=2**4, r=8, p=1, backend=default_backend()) try: kdf.verify(pwd.encode(), self.users[self.currentUser]["pwd"]) except InvalidKey: print("The password is wrong.") continue else: break #get encrypted folder password and encrypted kek encrypted_folder_pwd = self.users[ self.currentUser]["folders"][folder_path] stored_kek = self.getEncryptionFolderKek(folder_path) #decrypt folder password using the user password kdf = PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt=self.users[self.currentUser]["salt"], iterations=100000, backend=default_backend()) pwd_key = kdf.derive(pwd.encode()) f = Fernet(urlsafe_b64encode(pwd_key)) folder_pwd = f.decrypt(encrypted_folder_pwd) #decrypt the kek using the decrypted folder password kdf = PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt=self.kek_db[folder_path]["salt"], iterations=100000, backend=default_backend()) folder_key = kdf.derive(folder_pwd) f = Fernet(urlsafe_b64encode(folder_key)) folder_kek = f.decrypt(stored_kek) if self.kek_db[folder_path]["rotate"]: print( "Key rotation happened. Reencrypting all DEKs of files in this directory with the new KEK." ) new_kek = Fernet.generate_key() new_f = Fernet(new_kek) f = Fernet(folder_kek) for currentFile in os.listdir(path_secure + folder_path): if currentFile == name: continue file_encrypted_dek = self.dek_db[folder_path + "/" + currentFile]['dek'] file_dek = f.decrypt(file_encrypted_dek) new_file_encrypted_dek = new_f.encrypt(file_dek) self.dek_db[folder_path + "/" + currentFile].update( {"dek": new_file_encrypted_dek}) f = Fernet(urlsafe_b64encode(folder_key)) new_encrypted_kek = f.encrypt(new_kek) self.kek_db[folder_path].update({ "decryption_kek": new_encrypted_kek, "encryption_kek": new_encrypted_kek }) self.kek_db[folder_path].update({"rotate": False}) folder_kek = new_kek #encrypt dek using the decrypted folder kek f = Fernet(folder_kek) dek = f.encrypt(dek) #store encrypted data encrytion key, authentication tag and initialization vector in dek database self.dek_db[file_name].update({'dek': dek, 'tag': tag, 'iv': iv})
def getDek(self, file_name): #get folder path by eliminating the file name of file path folder_path = "/".join(file_name.split("/")[0:-1]) #get user password #compare entered password to stored hash of correct user password #repeated until they are equal while True: pwd = input("Enter your user password") kdf = Scrypt(salt=self.users[self.currentUser]["salt"], length=32, n=2**4, r=8, p=1, backend=default_backend()) try: kdf.verify(pwd.encode(), self.users[self.currentUser]["pwd"]) except InvalidKey: print("The password is wrong.") continue else: break #get encrypted folder password and folder kek encrypted_folder_pwd = self.users[ self.currentUser]["folders"][folder_path] encrypted_kek = self.getDecryptionFolderKek(folder_path) #decrypt folder password kdf = PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt=self.users[self.currentUser]["salt"], iterations=100000, backend=default_backend()) pwd_key = kdf.derive(pwd.encode()) f = Fernet(urlsafe_b64encode(pwd_key)) folder_pwd = f.decrypt(encrypted_folder_pwd) #decrypt kek kdf = PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt=self.kek_db[folder_path]["salt"], iterations=100000, backend=default_backend()) folder_key = kdf.derive(folder_pwd) f = Fernet(urlsafe_b64encode(folder_key)) kek = f.decrypt(encrypted_kek) #decrypt dek f = Fernet(kek) dek = f.decrypt(self.dek_db[file_name]['dek']) if self.kek_db[folder_path]["rotate"]: print( "Key rotation happened. Reencrypting all DEKs of files in this directory with the new KEK." ) new_kek = Fernet.generate_key() new_f = Fernet(new_kek) for currentFile in os.listdir(path_secure + folder_path): file_encrypted_dek = self.dek_db[folder_path + "/" + currentFile]['dek'] file_dek = f.decrypt(file_encrypted_dek) new_file_encrypted_dek = new_f.encrypt(file_dek) self.dek_db[folder_path + "/" + currentFile].update( {"dek": new_file_encrypted_dek}) f = Fernet(urlsafe_b64encode(folder_key)) new_encrypted_kek = f.encrypt(new_kek) self.kek_db[folder_path].update({ "decryption_kek": new_encrypted_kek, "encryption_kek": new_encrypted_kek }) self.kek_db[folder_path].update({"rotate": False}) return dek
def oauth2_token(request): """ * In the case of an incoming authentication request a POST is made with the following structure. POST /token HTTP/1.1 Host: server.example.com Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW Content-Type: application/x-www-form-urlencoded grant_type=password&username=johndoe&password=A3ddj3w The basic auth header contains the client_id:client_secret base64 encoded for client authentication. The username and password are form encoded as part of the body. This request *must* be made over https. The response to this request will be, assuming no error: HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Cache-Control: no-store Pragma: no-cache { "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"bearer", "expires_in":3600, "refresh_token":"tGzv3JOkF0XG5Qx2TlKW", "user_id":1234, } * In the case of a token refresh request a POST with the following structure is required: POST /token HTTP/1.1 Host: server.example.com Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW Content-Type: application/x-www-form-urlencoded grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKW&user_id=1234 The response will be the same as above with a new access_token and refresh_token. """ # Make sure this is a POST. if request.method != 'POST': log.info('rejected request due to invalid method: %s' % request.method) return HTTPMethodNotAllowed( 'This endpoint only supports the POST method.') getClientCredentials(request) # Make sure we got a client_id and secret through the authorization # policy. Note that you should only get here if not using the Oauth2 # authorization policy or access was granted through the AuthTKt policy. if (not hasattr(request, 'client_id') or not hasattr(request, 'client_secret')): log.info('did not receive client credentials') return HTTPUnauthorized('Invalid client credentials') client = db.query(Oauth2Client).filter_by( client_id=request.client_id).first() # Again, the authorization policy should catch this, but check again. if not oauth2_settings('salt'): raise ValueError('oauth2_provider.salt configuration required.') salt = b64decode(oauth2_settings('salt').encode('utf-8')) kdf = Scrypt( salt=salt, length=64, n=2 ** 14, r=8, p=1, backend=backend ) try: client_secret = request.client_secret try: client_secret = bytes(client_secret, 'utf-8') except TypeError: client_secret = client_secret.encode('utf-8') kdf.verify(client_secret, client.client_secret) bad_secret = False except (AttributeError, InvalidKey): bad_secret = True if not client or bad_secret: log.info('received invalid client credentials') return HTTPBadRequest(InvalidRequest( error_description='Invalid client credentials')) # Check for supported grant type. This is a required field of the form # submission. resp = None grant_type = request.POST.get('grant_type') if grant_type == 'password': resp = handle_password(request, client) elif grant_type == 'refresh_token': resp = handle_refresh_token(request, client) else: log.info('invalid grant type: %s' % grant_type) return HTTPBadRequest(UnsupportedGrantType(error_description='Only ' 'password and refresh_token grant types are supported by this ' 'authentication server')) add_cache_headers(request) return resp
def addFolderKek(self, folder_path): #set folder password which allows user to gain access to shared_folder folder_pwd = input("Set folder password used for first access: ") #store hash of folder password to verify that entered password is the correct one later (needed on first access to folder) salt = os.urandom(16) kdf = Scrypt(salt=salt, length=32, n=2**4, r=8, p=1, backend=default_backend()) key = kdf.derive(folder_pwd.encode()) self.pwd_db.update({folder_path: key}) #generate kek of folder generated_kek = Fernet.generate_key() #encrypt the kek using the folder password and store the encrypted kek kdf = PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt=salt, iterations=100000, backend=default_backend()) folder_key = kdf.derive(folder_pwd.encode()) f = Fernet(urlsafe_b64encode(folder_key)) folder_kek = f.encrypt(generated_kek) self.kek_db.update({ folder_path: { "decryption_kek": folder_kek, "encryption_kek": folder_kek, "salt": salt, "rotate": False } }) while True: user_pwd = input("Enter your user password: "******"salt"], length=32, n=2**4, r=8, p=1, backend=default_backend()) try: kdf.verify(user_pwd.encode(), self.users[self.currentUser]["pwd"]) except InvalidKey: print("The password is wrong.") continue else: break #store folder password which was encrypted using user password kdf = PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt=self.users[self.currentUser]["salt"], iterations=100000, backend=default_backend()) user_key = kdf.derive(user_pwd.encode()) f = Fernet(urlsafe_b64encode(user_key)) encrypted_folder_pwd = f.encrypt(folder_pwd.encode()) self.users[self.currentUser]["folders"].update( {folder_path: encrypted_folder_pwd})