This is a follow up from the previous post of this code in https://cyruslab.net/2019/08/17/pythonsample-encrypting-and-decrypting-the-dictionary/
The code snippet is a sample to demonstrate encrypting and decrypting the entire dictionary in a file, however there is a problem with this snippet. if the encryption and decryption is done within the same “session” there is no issue, however if you have encrypted a file and decrypt the file again later you will get an exception raised by Fernet, this is because everytime you run a key is generated again, the previous session already generated a key to encrypt, however if the script is to run again a different key will be generated and hence cannot decrypt the previously encrypted file.
So a feasible solution is to generate a symmetric key and save the key as a file, this key is to be used for decrypting the encrypted file later.
from getpass import getpass import logging from cryptography.fernet import Fernet import json from os.path import exists logging.basicConfig(level=logging.DEBUG) # get credential returns dictionary def get_creds(): username = input("Username: ") password = getpass() return {"username": username, "password": password} # For encrypting and descrypting file, mode=1 is encrypt which is default, 0 is decrypt. def cred_file_security(cipher, filename, creds=None, mode=1): byte_string = json.dumps(creds).encode('utf-8') # print(byte_string) byte_ciphertext = cipher.encrypt(byte_string) if mode == 1: with open(filename, "wb") as encrypt_file: encrypt_file.write(byte_ciphertext) return "credential is encrypted in {}".format(filename) elif mode == 0: print("Decrypting file...") with open(filename, "rb") as decrypt_file: data = decrypt_file.read() # print(data) decrypted_data = cipher.decrypt(data).decode('utf-8') return decrypted_data else: return "{} cannot be opened!!".format(filename) if __name__ == "__main__": # Fernet key generation, if the key is not present # enc.key is the key for encrypting and decrypting keep it safe. if not exists("enc.key"): key = Fernet.generate_key() with open("enc.key", "wb") as key_file: key_file.write(key) # If the key already exists, open the key and use the key to create a cipher with open("enc.key", "rb") as read_key_file: key_file = read_key_file.read() # use the cipher to encrypt and decrypt for later. cipher = Fernet(key_file) # change the encrypted filename anytime. filename = "creds.enc" if not exists(filename): file_response = cred_file_security(cipher, filename, creds=get_creds(), mode=1) print(file_response) else: file_response = cred_file_security(cipher, filename, mode=0) print(file_response)