Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to save a fernet key for a later session?

I am very new at python, I was working on a program that encrypts a text string, then saves it to a file. My program works perfectly when I encrypt then decrypt it in the same session. What I would like to do is: encrypt a file, then close the program, come back to it later and decrypt it. I don't know how the cryptography module works, but judging how it is called the "key" I assume it would be important for security, but I do not know. When I try to save the fernet key to a text file it displays an error message. When I try to decrypt a message that was encrypted in a previous session it displays 4 errors referencing the cryptography module. To conclude, I was wondering if it is possible to use the cryptography module to decrypt data between sessions. If not, is there an alternate way I could complete this task? Thanks for any help. here is my code:

from cryptography.fernet import Fernet
key = Fernet.generate_key()
f = Fernet(key)
sel = input("Would you like to encrypt or decrypt? (1 = encrypt, 2 = decrypt) ")
if sel == 1:
    inp = raw_input("Enter Text: ")  # Type here
    encoded = f.encrypt(inp)
    a, b = encoded[:len(encoded)/2], encoded[len(encoded)/2:]
    print ("YOUR PASSWORD: ")
    print b
    file = open('password.txt', 'w')
    file.write(a)
elif sel == 2:
    inp = raw_input("Enter Password: ")
    file = open('password.txt', 'r')
    a = file.readline()
    combine = (a + inp)
    out = f.decrypt(combine)
    print out

here is the error that occurs when you enter a "password" from a previous session:

Traceback (most recent call last):
  File "/Users/Zak/PycharmProjects/Password/test.py", line 18, in <module>
    out = f.decrypt(combine)
  File "/Users/Zak/PycharmProjects/Password/venv/lib/python2.7/site-packages/cryptography/fernet.py", line 75, in decrypt
    return self._decrypt_data(data, timestamp, ttl)
  File "/Users/Zak/PycharmProjects/Password/venv/lib/python2.7/site-packages/cryptography/fernet.py", line 119, in _decrypt_data
    self._verify_signature(data)
  File "/Users/Zak/PycharmProjects/Password/venv/lib/python2.7/site-packages/cryptography/fernet.py", line 108, in _verify_signature
    raise InvalidToken
cryptography.fernet.InvalidToken

Also this is what happens when you edit the code to save the key to a blank .txt file. Keep in mind this error does not reflect the code above.

Traceback (most recent call last):
  File "/Users/Zak/PycharmProjects/Password/test.py", line 5, in <module>
    file.write(f)
TypeError: expected a character buffer object
like image 657
Zak35 Avatar asked Oct 07 '18 03:10

Zak35


People also ask

How do you save a Fernet key?

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) def load_key(): """ Loads the key from the current directory named `key.

How do I make a Fernet key?

derive(password)) f = Fernet(key) token = f. encrypt(b"Secret message!") token # b'...' f. decrypt(token) # b'Secret message!

Is Fernet secure?

The result of this encryption is known as a “Fernet token” and has strong privacy and authenticity guarantees. data (bytes) – The message you would like to encrypt. A secure message that cannot be read or altered without the key. It is URL-safe base64-encoded.

What does Fernet key do?

A fernet key is used to encrypt and decrypt fernet tokens. Each key is actually composed of two smaller keys: a 128-bit AES encryption key and a 128-bit SHA256 HMAC signing key. The keys are held in a key repository that keystone passes to a library that handles the encryption and decryption of tokens.


Video Answer


1 Answers

With a few modifications, your script can be made to work the way you intended (but read the answer until the end to learn why this might no be an entirely good idea):

from cryptography.fernet import Fernet
sel = input("Would you like to encrypt or decrypt? (1 = encrypt, 2 = decrypt) ")
if sel == 1:
    key = Fernet.generate_key()
    print ("YOUR KEY: ")
    print key
    f = Fernet(key)
    inp = raw_input("Enter Text: ")  # Type here
    encoded = f.encrypt(inp)
    with open('encoded.txt', 'w') as file:
        file.write(encoded)
elif sel == 2:
    inp = raw_input("Enter Key: ")
    f = Fernet(inp)
    with open('encoded.txt', 'r') as file:
        encoded = file.readline()
    out = f.decrypt(encoded)
    print out

Testing it:

$ python2 test.py 
Would you like to encrypt or decrypt? (1 = encrypt, 2 = decrypt) 1
YOUR KEY: 
gRNCcDPDnSzqT2RT4nFJA6MYtsJkBG85sMEy9TogRYg=
Enter Text: This is a secret
$ python2 test.py 
Would you like to encrypt or decrypt? (1 = encrypt, 2 = decrypt) 2
Enter Key: gRNCcDPDnSzqT2RT4nFJA6MYtsJkBG85sMEy9TogRYg=
This is a secret

You may have noticed that I changed the word PASSWORD into KEY -- because that long string of characters is actually the key (in a URL-safe, base64-encoded form) used for the encrypt() and decrypt() transformations.

In practice, this is normally not what you would be doing. The key can not be memorized and people would typically store it somewhere in a file and use copy-paste to enter it. This increases the risk that the key will leak.

As an alternative, a so-called key-derivation mechanism can be used. In that case, the key bytes are not generated randomly with the Fernet.generate_key() function, but they are calculated using a key-derivation function that is applied to a, easier to memorize but well-chosen, passphrase. For an example of that, see the section Using passwords with Fernet.

like image 139
Reinier Torenbeek Avatar answered Oct 06 '22 01:10

Reinier Torenbeek