-1

I wrote this prototype code to encrypt some text (and vice - versa). I keep getting this error when I set the command to self.get() while self.write works as it should. I have no idea what causes this error or how to solve it...Help...

from cryptography.fernet import Fernet

class EncodingText:
    def __init__(self):
        self.key = Fernet.generate_key()
        self.f = Fernet(self.key)
        self.get()

    def write(self):
        stuff = "hello there".encode()
        token = self.f.encrypt(stuff)
        open_file_for_edit = open("file.txt", 'wb')
        open_file_for_edit.write(token)
        open_file_for_edit.close()

    def get(self):
        read_file = open("file.txt", 'rb')
        reading = read_file.read()
        print(reading)
        token = self.f.decrypt(reading)
        print(token)
        read_file.close()


if __name__ == "__main__":
    EncodingText()

The error I get is as follows:

Traceback (most recent call last):
  File "C:\Users\xoxo\AppData\Local\Programs\Python\Python38-32\lib\site-packages\cryptography\fernet.py", line 113, in _verify_signature
    h.verify(data[-32:])
  File "C:\Users\xoxo\AppData\Local\Programs\Python\Python38-32\lib\site-packages\cryptography\hazmat\primitives\hmac.py", line 70, in verify
    ctx.verify(signature)
  File "C:\Users\xoxo\AppData\Local\Programs\Python\Python38-32\lib\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 "c:/Users/xoxo/Desktop/Python Programs/xoxo/xoxo.py", line 26, in <module>
    EncodingText()
  File "c:/Users/xoxo/Desktop/Python Programs/xoxo/xoxo.py", line 7, in __init__
    self.get()
  File "c:/Users/xoxo/Desktop/Python Programs/xoxo/xoxo.py", line 20, in get
    tokenf = self.f.decrypt(reading)
  File "C:\Users\xoxo\AppData\Local\Programs\Python\Python38-32\lib\site-packages\cryptography\fernet.py", line 76, in 
decrypt
    return self._decrypt_data(data, timestamp, ttl, int(time.time()))
  File "C:\Users\xoxo\AppData\Local\Programs\Python\Python38-32\lib\site-packages\cryptography\fernet.py", line 125, in _decrypt_data
    self._verify_signature(data)
  File "C:\Users\xoxo\AppData\Local\Programs\Python\Python38-32\lib\site-packages\cryptography\fernet.py", line 115, in _verify_signature
    raise InvalidToken
cryptography.fernet.InvalidToken
Anonymous
  • 25
  • 1
  • 5
  • Assuming `write` method was not called, the code is bound to fail. – arunanshub Nov 03 '20 at 08:32
  • Another possible cause would be: Each instantiation of `EncodingText` creates a _new_ key. So if you encrypt with one instance (with `self.write()` in the constructor) and decrypt with another using the above code, it should also fail because of different keys. – Topaco Nov 03 '20 at 08:35
  • @Topaco That is the other (potential) reason. I'll demonstrate it as a complete answer. – arunanshub Nov 03 '20 at 08:39
  • If the problem is solved, please accept the answer. – arunanshub Nov 04 '20 at 04:15

1 Answers1

1

Let us go through the code line by line:

  1. In the method __init__:

    1. Line 1: key generation.

      self.key = Fernet.generate_key()  # this is called
      

      We are generating a random key every time the method is called.

    2. Line 2: Cipher generation

      self.f = Fernet(self.key)
      

      We are creating a cipher with a completely random key.

    3. Line 3: Decryption

      self.get()
      

      We are calling a new method.

  2. In method get:

    1. Line 1, 2 and 3: Reading a file

      read_file = open("file.txt", 'rb')
      reading = read_file.read()
      print(reading)
      

      Here, 2 things are possible.

      1. The file is missing from the path, and FileNotFoundError is raised and the program halts.

      2. The file is present.

      Assuming, the file is present (#2). The file contents will be read and the contents will be printed.

    2. Line 4: Decryption

      token = self.f.decrypt(reading)
      

      Here, our file contents will be decrypted. Remember that, from point 1.1.1 and 1.1.2, each time our program is called, a random key is generated and the cipher is generated with a random key.

      Since Fernet, by implementation, uses AES, which is a symmetric cipher, we require the same key for encryption and decryption.

      But, by 1.1.1 and 1.1.2, we are generating a random key each time the program runs.

      This explains the error message. The cipher is trying to decrypt the data from the file which was encrypted with a completely random key with another random key, which leads to incorrect decryption.


If you insert self.write() before self.get(), the program runs. This is because the same key is used to decrypt the data.

arunanshub
  • 581
  • 5
  • 15