0

I'm playing with encryption and have come across this cryptography.fernet.InvalidToken error, which obviously means that the tokens don't match. The encrypter works fine, but the error is raised when running the decrypter. I can't figure out what's wrong with my code. Any help is appreciated!

Encrypter

from cryptography.fernet import Fernet

class Encrypter:
    def __init__(self,key,data):
        self.key = key
        self.data = data

    def generate_key(self):
        key = Fernet.generate_key()
        return key

    def create_key_file(self):
        with open('key.key', 'wb') as keyfile:
            keyfile.write(self.generate_key())

    def encrypt_file(self):
        fernet = Fernet(self.generate_key())
        with open('sample_file.csv', 'rb') as tf:
            tf_bytes = tf.read()

        tf_bytes_enc = fernet.encrypt(tf_bytes)
        with open('sample_file.csv', 'wb') as tf:
            tf.write(tf_bytes_enc)

key_obj = Encrypter(key='key.key',data='sample_file.csv')
key_obj.create_key_file()
key_obj.encrypt_file()

Decrypter

class Decrypter:
    def __init__(self,key,data):
        self.key = key
        self.data = data

    def get_key(self):
        with open('key.key', 'rb') as keyfile:
            key = keyfile.read()
        return key

    def open_encrypted_file(self):
        with open('sample_file.csv', 'rb') as tf:
            tf_bytes = tf.read()

        fernet = Fernet(self.get_key())
        tf_bytes_dec = fernet.decrypt(tf_bytes)
        return tf_bytes_dec

    def decrypt_file(self):
        with open('sample_file.csv', 'wb') as tf:
            tf.write(self.open_encrypted_file())
        return tf

key_obj = Decrypter(key='key.key',data='sample_file.csv')
key_obj.get_key()
key_obj.decrypt_file()
CUI
  • 51
  • 5
  • You generate a key when you call `create_key_file`, and that's the key you write to the file, but in `encrypt_file`, you call `generate_key` AGAIN. It's that second key you use for the encoding, and that's NOT the key you saved to file. You should probably cache the key in the object, and only generate it if you haven't already. – Tim Roberts Feb 21 '23 at 19:34
  • There no point in calling `get_key` in your mainline code in the decrypter. You don't save the key anywhere. Just let `open_encrypted_file` do it when it needs it. – Tim Roberts Feb 21 '23 at 19:39
  • Hey @TimRoberts, thanks for helping. I understand your explanation, but I'm still confused. You said that I don't save the key, anywhere. Well, I do. That's what the create_key_file() function is for. And indeed, the file does get created. Then, my idea was to create the open_encrypted_file() function to save the file data into a variable, which is then passed into the fernet.decrypt(function. Finally, I would write the decrypted values into the csv. So, I guess my biggest problem is to use the key that I had saved, which is why iI built the get_key() function. Can you show me your solution? – CUI Feb 21 '23 at 22:59
  • I posted my solution 3 hours before you asked this question. Yes, the file gets created, but the key you save in the file is NOT the key you use to do the encryption. That's why you have a problem. – Tim Roberts Feb 22 '23 at 02:09

1 Answers1

0

Here's a design that only generates the key once. This should work.

class Encrypter:
    def __init__(self,keyfile,data):
        self.keyfile = keyfile
        self.data = data
        self.key = None

    def generate_key(self):
        if not self.key:
            self.key = Fernet.generate_key()
        return self.key
Tim Roberts
  • 48,973
  • 4
  • 21
  • 30