简体   繁体   中英

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)

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.

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM