Search code examples
pythonencryptionfernet

Decrypt with Fernet, TypeError: token must be bytes


Programming language: Python

i have three files, one is to generate the key, 2nd is to encrypt, and the other is to decrypt.. the 1st and the 2nd files work.. but the decrypt file won't work

generate key file:

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)

generate_key()

encrypt file -

from cryptography.fernet import Fernet

def load_key():
    return open("secret.key", "rb").read()

def encrypt_message(message):
    key = load_key()
    encoded_message = message.encode()
    f = Fernet(key)
    encrypted_message = f.encrypt(encoded_message)
    
    print(encrypted_message)

    EncryptedTextWriteFile = open("encrypt.txt", "r+")
    EncryptedTextWriteFile.write(str(encrypted_message))

notEncryptedFile = open("text.txt", "r")
notEncryptedText = notEncryptedFile.read()

if __name__ == "__main__":
    encrypt_message(notEncryptedText)

notEncryptedFile.close()

Decrypt file -

from cryptography.fernet import Fernet

def load_key():
    return open("secret.key", "rb").read()

def decrypt_message(encrypted_message):
    key = load_key()
    f = Fernet(key)
    decrypted_message = f.decrypt(encrypted_message)
    shit = decrypted_message.decode()

    print(shit)

    DencryptedTextWriteFile = open("decrypt.txt", "r+")
    DencryptedTextWriteFile.write(shit)

EncryptedFile = open("decrypt.txt", "r")
EncryptedText = EncryptedFile.read()

if __name__ == "__main__":
    decrypt_message(EncryptedText)

the string i tried - ( this test is in the text.txt )

hirusha

the error i get:

Traceback (most recent call last):
  File "d:/development/Python/Everything/Releases/0.2/Build 02/_Releases/Encoder and Decoder/decrypt.py", line 27, in <module>
    decrypt_message(EncryptedText)
  File "d:/development/Python/Everything/Releases/0.2/Build 02/_Releases/Encoder and Decoder/decrypt.py", line 15, in decrypt_message
    decrypted_message = f.decrypt(encrypted_message)
  File "C:\Users\hirusha\AppData\Local\Programs\Python\Python38\lib\site-packages\cryptography\fernet.py", line 75, in decrypt
    timestamp, data = Fernet._get_unverified_token_data(token)
  File "C:\Users\hirusha\AppData\Local\Programs\Python\Python38\lib\site-packages\cryptography\fernet.py", line 100, in _get_unverified_token_data
    utils._check_bytes("token", token)
  File "C:\Users\hirusha\AppData\Local\Programs\Python\Python38\lib\site-packages\cryptography\utils.py", line 29, in _check_bytes
    raise TypeError("{} must be bytes".format(name))
TypeError: token must be byte

Solution

  • The problem is that when you open the file decrypt.txt and read the file, it gets converted into string. But the .decrypt function only accepts input in byte.

    I think this should solve your problem:

    Generates a key and stores it in key.key file:

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

    Encrypts a file and stores it in enc_text.txt file:

    from cryptography.fernet import Fernet
    with open("key.key","rb") as f:
        key=f.read()
    f = Fernet(key)
    
    with open('text.txt', 'rb') as original_file:
        original = original_file.read()
    
    encrypted = f.encrypt(original)
    
    with open ('enc_text.txt', 'wb') as encrypted_file:
        encrypted_file.write(encrypted)
    

    Decrypts the enc_text.txt file and writes the output in decrypt.txt

    from cryptography.fernet import Fernet
    with open("key.key","rb") as f:
        key=f.read()
    f = Fernet(key)
    
    with open('enc_text.txt', 'rb') as encrypted_file:
        encrypted = encrypted_file.read()
    
    decrypted = f.decrypt(encrypted)
    
    with open('decrypt.txt', 'wb') as decrypted_file:
        decrypted_file.write(decrypted)