How to make sure the Fernet key stays the same when initialized?

2.4k Views Asked by At

So, I am making a password manager and I am using the cryptography module. The problem with this program is when decrypting. It will work fine when I encrypt and decrypt in the same session but when I encrypt, close, and then decrypt in a different session, errors will be raised. This error isn't happening because I am generating a random key every time, but I think the key is changing when I initialize it using the Fernet() method. How do I solve this?

#The Dependicies and Packages required for this script
import sqlite3 
from cryptography.fernet import Fernet


def generate_key():
    """
    Generates a key and save it into a file
    """
    key = Fernet.generate_key()
    with open("secret.key", "wb") as key_file:
        key_file.write(key)


def load_key():
    """
    Loads the key named `secret.key` from the current directory.
    """
    return open("secret.key", "rb").read()

#These are the keys for encryption
Key = load_key()

f = Fernet(Key)


def decode_data(datas):
    new_name = f.decrypt(datas)
    final_name = new_name.decode()
    return final_name 
def find_password():
    """
    This function is to get the password of the website that the user expected
    """
    website_name = input("What is the website's name for which you need a password>")
    c.execute("SELECT * FROM passwords")
    data = c.fetchall()
    print(data)
    for row in data:
        print(row[0])
        name = decode_data(row[0])
        if name == website_name:
            password = decode_data(row[2])
            print(f'The password to {website_name} is {password}')


def main():
    go_on = True
    while go_on:
        direction_question = input("This is your password manager. Press 1 to create a new pasword, Press 2 to search for a password, or Press 3 to exit the program>")
        if direction_question.lower() == "1":
            create_password()
        if direction_question.lower() == "2":
            find_password()
        if direction_question.lower() == "3":
            go_on = False
        else:
            print("Invalid response")
    db.commit()
    db.close()


if __name__ == "__main__":
    db = sqlite3.connect('password.db')
    c = db.cursor()
    main()


These errors were raised

  File "/usr/local/lib/python3.7/site-packages/cryptography/fernet.py", line 114, in _verify_signature
    h.verify(data[-32:])
  File "/usr/local/lib/python3.7/site-packages/cryptography/hazmat/primitives/hmac.py", line 68, in verify
    ctx.verify(signature)
  File "/usr/local/lib/python3.7/site-packages/cryptography/hazmat/backends/openssl/hmac.py", line 78, in verify
    raise InvalidSignature("Signature did not match digest.")
cryptography.exceptions.InvalidSignature: Signature did not match digest.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "password_manager.py", line 86, in <module>
    main()
  File "password_manager.py", line 74, in main
    find_password()
  File "password_manager.py", line 61, in find_password
    name = decode_data(row[0])
  File "password_manager.py", line 28, in decode_data
    new_name = f.decrypt(datas)
  File "/usr/local/lib/python3.7/site-packages/cryptography/fernet.py", line 77, in decrypt
    return self._decrypt_data(data, timestamp, ttl, int(time.time()))
  File "/usr/local/lib/python3.7/site-packages/cryptography/fernet.py", line 126, in _decrypt_data
    self._verify_signature(data)
  File "/usr/local/lib/python3.7/site-packages/cryptography/fernet.py", line 116, in _verify_signature
    raise InvalidToken
cryptography.fernet.InvalidToken
1

There are 1 best solutions below

0
On

You have done a good job storing once generated keys to a separate file.I've run your scrip and it works fine. The only issue I found is that the following part should be within the main() method.

Key = load_key() 
f = Fernet(Key)

As the main() method is actually getting an empty string as a key rather than reading the stored key in the .key file.Hence, it is throwing

raise InvalidSignature("Signature did not match digest.")

cryptography.exceptions.InvalidSignature: Signature did not match digest.

and

raise InvalidToken

cryptography.fernet.InvalidToken