Lorenzo
Lorenzo

Reputation: 11

Error while trying to decrypt using Fernet

After creating a simple python encryption code with fernet library (that worked great) I tried to code a decryptor but unfortunately while trying to use my decryptor i got the following error

['blahblahblah.txt', 'blah.txt']
Traceback (most recent call last):
  File "/home/kali/Desktop/stuff/projects/voldemort/decrypt.py", line 24, in <module>
    contents_decrypted = Fernet(secretkey).decrypt(contents)
  File "/usr/lib/python3/dist-packages/cryptography/fernet.py", line 34, in __init__
    raise ValueError(
ValueError: Fernet key must be 32 url-safe base64-encoded bytes.

The Code:

#!/usr/bin/python3

import os
from cryptography.fernet import Fernet

#find some files
files = []

#Starting the file in a loop
for file in os.listdir():
        if file == "voldemort.py" or file == "thekey.key" or file == "decrypt.py":
                continue
        if os.path.isfile(file):
                files.append(file)

print(files)

with open("thekey.key", "rb") as key:
        secretkey = key.read()

for file in files:
        with open(file, "rb") as thefile:
                contents = thefile.read()
        contents_decrypted = Fernet(secretkey).decrypt(contents)
        with open(file, "wb") as thefile:
                thefile.write(contents_decrypted)

Upvotes: 1

Views: 2524

Answers (2)

s3dev
s3dev

Reputation: 9701

The error simply states the key used is invalid. Fernet is expecting a (url-safe) 32-byte base64 encoded string, as the key.

There are many methods for generating such a string, here are two simpler examples:

Option 1:

Let Fernet do it for you:

from cryptography import fernet

key = fernet.Fernet.generate_key()

Output:

b'd25vYTghWVgkTQWrMFnwW1tfKtn_lWzDr2JJM95f2fs='

Option 2:

Create one yourself using a (unique) randomly generated UUID4 string:

import base64
import uuid

key = base64.b64encode(uuid.uuid4().hex.encode())

Output:

b'M2E4MmQ2MDJlNmZmNDQwN2I3Y2NiN2I0ZDJkMzA4Zjk=' 

Addressing the helpful comment about writing the key to a file, one can use:

with open('keyfile.key', 'wb') as f:
    f.write(key)

Remember, Fernet is looking for a bytestring, so it's important to store the file using the 'wb' (write binary) mode.

Upvotes: 1

eatmeimadanish
eatmeimadanish

Reputation: 3907

Your issue is your Fernet key is not encoded correctly.

*UPDATED TO SUPPORT RAW FILE OUTPUT

from cryptography.fernet import Fernet
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.backends import default_backend
import hashlib
import zlib, base64, json

SALT = 'secretpassword'        

def cryptkey(password=''):
    digest = hashes.Hash(hashes.SHA256(), backend=default_backend())
    digest.update(SALT+password)
    return Fernet(base64.urlsafe_b64encode(digest.finalize()))

def encrypt(meta, password=''):
    meta = str(zlib.compress(meta, 9))
    f = cryptkey(password)
    return base64.urlsafe_b64encode(f.encrypt(bytes(meta)))

def decrypt(meta, password=''):
    meta = base64.urlsafe_b64decode(meta)
    f = cryptkey(password)
    meta = f.decrypt(bytes(meta))
    return zlib.decompress(meta)

Upvotes: 0

Related Questions