0

I am trying to use Fernet to encrypt some text using user input as a key. However, I get an error. I've looked online but I can't find anything that helps. My code (all for testing purposes):

message = 'test message'
message = message.encode('utf-8')
key = input("")
key = key.encode('utf-8')
encrypt = base64.urlsafe_b64encode(key)
fernet = Fernet(encrypt)
encryptedmessage = fernet.encrypt(message)
print(message)

Any ideas on how to fix? I'm not looking for help with generating and using a secure key, I just want to use a user input as the key. Thank you in advance

john
  • 11
  • 4
  • 1
    Fernet needs a 32 bytes key, Base64url encoded. That cannot be changed. So create a 32 bytes input (considering the UTF-8 encoding). Alternatively, you can use a password-based key derivation function in combination with a random salt, e.g. PBKDF2. – Topaco Mar 29 '22 at 20:28
  • @Topaco can you show me an example of PBKDF2. The only tutorial I could find was in indian. Thanks – john Mar 30 '22 at 09:31
  • PBKDF2 is supported by practically all major crypto libraries, e.g. [here](https://cryptography.io/en/latest/hazmat/primitives/key-derivation-functions/#cryptography.hazmat.primitives.kdf.pbkdf2.PBKDF2HMAC) for the Cryptography library. – Topaco Mar 30 '22 at 09:36
  • @Topaco I need something that can have a key and is reversible with that key. This looks like hashing, am I correct by saying that? – john Mar 30 '22 at 13:07
  • With a PBKDF a key of fixed length (e.g. 32 bytes for Fernet) is derived from a random password (e.g. your user input). Usage: Encryption: Create a random salt and derive the key together with the password via PBKDF. Use the key for encryption. Concatenate (the non secret) salt and ciphertext (e.g. your Fernet token). Decryption: Separate salt and ciphertext. Derive the key with salt and password via PBKDF. Decrypt the ciphertext. – Topaco Mar 30 '22 at 13:27

1 Answers1

0

You have to convert the user-input to a Base64, url_safe key.

I would recommend using PBKDF2HMAC to accomplish that you can use a function like this.

def derive_key_from_password(password: str, salt):
    password = bytes(password, "UTF-8")
    # Generate a key from the password and salt using PBKDF2
    kdf = PBKDF2HMAC(
        algorithm=hashes.SHA256(),
        length=32,
        salt=salt,
        iterations=600000,  # 600k is pretty secure
    backend=default_backend()
    )
    key = base64.urlsafe_b64encode(kdf.derive(password))

    return key

For safety concerns I would recommend using salt. You can easily create some: salt = os.urandom(16)

But keep in mind that you need to store the salt to decrypt the message again.

If you need further information you can look at this: https://github.com/timfuerth/pwd_manager/blob/encryption/utils/encrypt.py

Cube
  • 16
  • 3