0

I am trying to decrypt an encrypted file that is read from and stored in c_text.

from cryptography.fernet import Fernet

def cipher_decrypt(c_text):
    key = open(key_loc,'rb')
    key.seek(0)
    key_b = key.read()
    print ('Key: ' + str(key_b))
    print ('\nCipher text: ' + str(c_text))
    cipher_suite = Fernet(key_b)
    key.close()
    plain_text = cipher_suite.decrypt(c_text).decode()
    print ('\nPlain text: ' + plain_text)
    return plain_text

When called, this should print the following:

Key: b'z7oCVMrxjjgx3n1HFI9oCkyxMnOrXekYKNMEBDKF704='

Cipher text: b'gAAAAABbQxMuhTmZGb0fgR6eRwQO9_qPv0tMI9GVVtyNZbHmDb6YY0veCrvG8uat5m_huC6ZHjI17V-HhLTrUGgdQGlwowY1t24cAq9ybJgfGeQVwWLsR_0=gAAAAABbQxMvgyBwq3hhMbLLP1VMbbboix4qw_TD0nF164TN2QqLGA5iHtX-dpEkj4ALMUY_dhYMqOfXY0ZUqIiX4Z_7Ud-EB8FHN0RsSiaiTBXHOS6_55A=gAAAAABbQxMwm8dek1OLeJp-sE6qmrXQSgbVqi3Sx2JwafW4YpTWuRJosBWJJpBFQ8zp8_rQ5rsLhhs7mQ4XwhGxND1GXmg8RZSrQ9-eclg6L5qyHH5Rch4='

Plain text: Servicename: gmail\n Username: gmail\n Password: gmail\n\n

However, it only prints the first line of the Plain text. What is wrong?

EDIT: Here is the snippet of the code where I write to the file, along with the encryption function.

            ser_name = pymsgbox.prompt("Enter service name")
            ser_name_s = 'Servicename: ' + str(ser_name) + '\n'
            manager = open(mng_name,'ab')
            manager.write(cipher_encrypt(ser_name_s))
            manager.close()
            acc_name = pymsgbox.prompt("Enter user name or email associated with " + str(ser_name))
            acc_name_s = 'Username/Email: ' + str(acc_name) + '\n'
            manager = open(mng_name,'ab')
            manager.write(cipher_encrypt(acc_name_s))
            manager.close()
            pw_name = pymsgbox.password("Enter password associated with " + str(acc_name))
            pw_name_s = 'Password: ' + str(pw_name) + '\n'
            manager = open(mng_name,'ab')
            manager.write(cipher_encrypt(pw_name_s))
            manager.close()

encrypt function:

def cipher_encrypt(p_text):
    key = open(key_loc,'rb')
    key.seek(0)
    key_b = key.read()
    cipher_suite = Fernet(key_b)
    key.close()
    cipher_text = cipher_suite.encrypt(p_text.encode())
    return cipher_text

EDIT 2: After some testing, I have noticed that the decryption is only taking place for the first write command in the above code (even though the encryption is taking place normally). So there is definitely an issue with that, though I can't for the life of me figure it out...

Ray
  • 3
  • 4
  • Hi @Ray - when you say it only prints the first line of the Plain text, what do you mean? Your example above for "Plain text:..." is only one line, so do you mean it cuts off after the first `\n`? – Phil Sheard Jul 09 '18 at 08:42
  • @PhilSheard It only prints this: >Servicename: gmail – Ray Jul 09 '18 at 08:49

2 Answers2

0

You would get the result you're after by removing the .decode() operation from the plain text object I think. Alternatively, convert the decoded version into a string from its final byte sequence.

Here's a demo version:

>> from cryptography.fernet import Fernet
>> key = Fernet.generate_key()
>> f = Fernet(key)
>> token = f.encrypt(b"Servicename: gmail\n Username: gmail\n Password: gmail\n\n")
>> decrypted = f.decrypt(token)
>> decoded = decrypted.decode()
>> print(decrypted)
b'Servicename: gmail\n Username: gmail\n Password: gmail\n\n'
>> print(decoded)
Servicename: gmail
 Username: gmail
 Password: gmail

The fact that you're only seeing the first line in your version is that the newline characters are being interpreted by the terminal. I tested using iPython (Jupyter) and both versions ouput in full.

Phil Sheard
  • 2,102
  • 1
  • 17
  • 38
  • Disclaimer: I don't use this library in production, this is just from looking at the docs. – Phil Sheard Jul 09 '18 at 08:57
  • I removed the `\n` characters to see if they were causing the problem, but I still got the same result. The answer given by @ScottMcC is the same thing I am getting. So maybe I'm going wrong in my encryption/writing to the file? I added the code to my original post. – Ray Jul 09 '18 at 09:23
0

I actually get less text in your example. Steps to reproduce:

>>> from cryptography.fernet import Fernet
>>> key = b'z7oCVMrxjjgx3n1HFI9oCkyxMnOrXekYKNMEBDKF704='
>>> cipher_text = b'gAAAAABbQxMuhTmZGb0fgR6eRwQO9_qPv0tMI9GVVtyNZbHmDb6YY0veCrvG8uat5m_huC6ZHjI17V-HhLTrUGgdQGlwowY1t24cAq9ybJgfGeQVwWLsR_0=gAAAAABbQxMvgyBwq3hhMbLLP1VMbbboix4qw_TD0nF164TN2QqLGA5iHtX-dpEkj4ALMUY_dhYMqOfXY0ZUqIiX4Z_7Ud-EB8FHN0RsSiaiTBXHOS6_55A=gAAAAABbQxMwm8dek1OLeJp-sE6qmrXQSgbVqi3Sx2JwafW4YpTWuRJosBWJJpBFQ8zp8_rQ5rsLhhs7mQ4XwhGxND1GXmg8RZSrQ9-eclg6L5qyHH5Rch4='
>>> cipher_suite = Fernet(key)
>>> decrypt_result = cipher_suite.decrypt(cipher_text)
>>> decrypt_result
b'Servicename: gmail\n'

It doesn't look like there is any other information stored in this cipher text as far as I can see?

ScottMcC
  • 4,094
  • 1
  • 27
  • 35
  • That is the same output that I am getting. I will add the part of the code where I write to the file in the original post. – Ray Jul 09 '18 at 09:17
  • I have another question. Does the key change everytime I encrypt something? – Ray Jul 09 '18 at 09:54
  • Yes it does, I believe there is a timestamp integrated into the encryption process which gives a different encryption output each time. This gives you the option to add a `ttl` parameter when creating the encrypted string. – ScottMcC Jul 09 '18 at 10:36
  • so is there any way I can store and use the same encryption key multiple times? – Ray Jul 12 '18 at 06:35
  • Yes. The timestamp doesn't effect the encryption process - I read all of the fernet source code. Just use the same key again. – Legorooj Jun 27 '19 at 20:22