Why does my cryptography python program not work? - python

I am trying to write a program to encrypt and decrypt messages. Here is the traceback:
Traceback (most recent call last):
File "C:\Users\notelling\OneDrive\Desktop\pyprojects\crypto.py", line 15, in
f = Fernet(key)
NameError: name 'key' is not defined
Here is my code:
from cryptography.fernet import Fernet
import os
if os.path.isfile("encryption.key"):
file = open("encryption.key", "rb")
filec = file.read().decode()
else:
key = Fernet.generate_key()
file = open('encryption.key', 'wb')
file.write(key.encode()) # The key is type bytes still
file.close()
print("Key generated.")
mode = input("Please enter mode (e/d):")
if mode == 'e':
message = input("What is your message to encrypt?").encode()
f = Fernet(key)
encrypted = f.encrypt(message)
passkey = open("encryptedmsg.txt", "wb")
passkey.write(encrypted)
passkey.close()
elif mode == 'd':
passread = open("encryptedmsg.txt", "rb")
contents = passread.read()
f = Fernet(key)
decrypted = f.decrypt(encrypted).decode()
print("Decrypted message is ", decrypted)
input()

This is not related to cryptography, but pure Python specific error.
The variable key is assigned in the first 'else' block, line no. 7.
This variable won't available outside that block, unless defined specifically.
More references:
https://docs.python.org/3.8/tutorial/classes.html#class-and-instance-variables
https://docs.python.org/3.8/tutorial/classes.html#private-variables

Related

I am having an error with decryption with the cryptography module

I am writing a password manager, but am getting this error when run all of a sudden, ive tried googling, and couldnt find anything. the code runs, but then suddenly gives an error.
Traceback:
hello, thank you for using APM. enter 'help' for help. enjoy!
> find google
"google", "google.com", "AntispleneticMoonlighty", "#{6P=,U{;%^AMO+", "number- 1"
Traceback (most recent call last):
File "D:\CODING\Python\APM.py", line 80, in <module>
db.decrypt()
File "D:\CODING\Python\APM.py", line 44, in decrypt
decrypted = fernet.decrypt(original)
File "C:\Users\Anton\AppData\Local\Programs\Python\Python310\lib\site-packages\cryptography\fernet.py", line 85, in decrypt
timestamp, data = Fernet._get_unverified_token_data(token)
File "C:\Users\Anton\AppData\Local\Programs\Python\Python310\lib\site-packages\cryptography\fernet.py", line 121, in _get_unverified_token_data
raise InvalidToken
cryptography.fernet.InvalidToken
Press any key to continue . . .
the code is listed below (trimmed), the error is referring to line 44(shown below):
Code:
import PGL
from cryptography.fernet import Fernet
import os
import logging as lg
class APMDatabase:
def __init__(self, keyfile_path, database_path):
global start
self.keyfile_path = keyfile_path
self.database_path = database_path
print(start)
def read_key(self):
with open(self.keyfile_path, "rb") as keyfile:
return keyfile.read()
def encrypt(self):
key = self.read_key()
fernet = Fernet(key)
with open(self.database_path, "rb") as file:
original = file.read()
encrypted = fernet.encrypt(original)
with open(self.database_path, "wb") as encfile:
encfile.write(encrypted)
def decrypt(self):
key = self.read_key()
fernet = Fernet(key)
with open(self.database_path, "rb") as file:
original = file.read()
decrypted = fernet.decrypt(original) #THIS IS THE LINE WITH THE ERROR
with open(self.database_path, "wb") as decfile:
decfile.write(decrypted)
def find(self, name):
db.decrypt()
with open(self.database_path, "r") as database:
content = database.readlines()
for i in content:
if name in i:
print(i)
return i
db.encrypt()
db = APMDatabase(
keyfile_path="D:\\CODING\\Python\\APMKEY.APMKEY",
database_path="D:\\CODING\\Python\\APMDatabase.APMDATA",
)
while True:
db.decrypt()
number = len((open("D:\\CODING\\Python\\APMDatabase.APMDATA")).readlines())
db.encrypt()
query = input("> ")
elif "find" in query:
data = query.split(" ")[1]
if data == "(all)":
try:
db.find('"')
except:
lg.error("404")
try:
db.find(data)
except:
lg.error("404")

ValueError: not enough values to unpack error in python3 while coding a very basic passwd manager

i'm a noob to programming and i keep getting this error while using the vedere() function. Sorry if it's a stupid question but i am totally new to python and to this forum. Also sorry if some part of the code is in italian. Btw it's a very basic password manager with some encryption for the passwords, here is the code:
import pyfiglet
from cryptography.fernet import Fernet
r = pyfiglet.figlet_format("Petrux Passwd Manager", font="slant")
print(r)
'''def write_key():
key = Fernet.generate_key()
with open("key.key", "wb") as k:
k.write(key)'''
def load_key():
file = open("key.key", "rb")
key = file.read()
file.close()
return key
pwd = input("Inserisci la pswd master:\n")
key = load_key() + pwd.encode()
fernet = Fernet(key)
def aggiungi():
dominio = input("Dominio:\n")
email = input("Email o username:\n")
passwd = input("Password:\n")
with open("5f4dcc3b5aa765d61d8327deb882cf99.txt", "a") as f:
f.write(dominio + "|" + email + "|" + fernet.encrypt(passwd.encode()).decode() + "\n")
print("Credenziali aggiunte con successo!")
def vedi():
with open("5f4dcc3b5aa765d61d8327deb882cf99.txt", "r") as f:
for line in f.readlines():
data = line.rstrip()
dominio, user, passw = data.split("|")
print("Dominio: ", dominio,"User: ", user, "| Password: ",
fernet.decrypt(passw.encode()).decode())
while True:
if pwd == "p3truxx":
mode = input("Vuoi aggiungere una password o vedere le esistenti?\n(aggiungere/vedere)\n \nOppure scrivi q per uscire\n").lower()
if mode == "vedere":
vedi()
elif mode == "aggiungere":
aggiungi()
elif mode == "q":
quit()
else:
print("Input non valido coglione")
else:
print("Password sbagliata")
continue
And here is the error:
Traceback (most recent call last):
File "C:\Users\invic\PycharmProjects\adventure\main.py", line 43, in <module>
vedi()
File "C:\Users\invic\PycharmProjects\adventure\main.py", line 35, in vedi
dominio, user, passw = data.split("|")
ValueError: not enough values to unpack (expected 3, got 1)
Thanks to an user who responded in the comment i tried to create a new file with the same code and worked just fine.
Probably the older .txt file contains some line that doesn't have a "|".

Decrypt with Fernet, TypeError: token must be bytes

Programming language: Python
i have three files, one is to generate the key, 2nd is to encrypt, and the other is to decrypt.. the 1st and the 2nd files work.. but the decrypt file won't work
generate key file:
from cryptography.fernet import Fernet
def generate_key():
"""
Generates a key and save it into a file
"""
key = Fernet.generate_key()
with open("secret.key", "wb") as key_file:
key_file.write(key)
generate_key()
encrypt file -
from cryptography.fernet import Fernet
def load_key():
return open("secret.key", "rb").read()
def encrypt_message(message):
key = load_key()
encoded_message = message.encode()
f = Fernet(key)
encrypted_message = f.encrypt(encoded_message)
print(encrypted_message)
EncryptedTextWriteFile = open("encrypt.txt", "r+")
EncryptedTextWriteFile.write(str(encrypted_message))
notEncryptedFile = open("text.txt", "r")
notEncryptedText = notEncryptedFile.read()
if __name__ == "__main__":
encrypt_message(notEncryptedText)
notEncryptedFile.close()
Decrypt file -
from cryptography.fernet import Fernet
def load_key():
return open("secret.key", "rb").read()
def decrypt_message(encrypted_message):
key = load_key()
f = Fernet(key)
decrypted_message = f.decrypt(encrypted_message)
shit = decrypted_message.decode()
print(shit)
DencryptedTextWriteFile = open("decrypt.txt", "r+")
DencryptedTextWriteFile.write(shit)
EncryptedFile = open("decrypt.txt", "r")
EncryptedText = EncryptedFile.read()
if __name__ == "__main__":
decrypt_message(EncryptedText)
the string i tried - ( this test is in the text.txt )
hirusha
the error i get:
Traceback (most recent call last):
File "d:/development/Python/Everything/Releases/0.2/Build 02/_Releases/Encoder and Decoder/decrypt.py", line 27, in <module>
decrypt_message(EncryptedText)
File "d:/development/Python/Everything/Releases/0.2/Build 02/_Releases/Encoder and Decoder/decrypt.py", line 15, in decrypt_message
decrypted_message = f.decrypt(encrypted_message)
File "C:\Users\hirusha\AppData\Local\Programs\Python\Python38\lib\site-packages\cryptography\fernet.py", line 75, in decrypt
timestamp, data = Fernet._get_unverified_token_data(token)
File "C:\Users\hirusha\AppData\Local\Programs\Python\Python38\lib\site-packages\cryptography\fernet.py", line 100, in _get_unverified_token_data
utils._check_bytes("token", token)
File "C:\Users\hirusha\AppData\Local\Programs\Python\Python38\lib\site-packages\cryptography\utils.py", line 29, in _check_bytes
raise TypeError("{} must be bytes".format(name))
TypeError: token must be byte
The problem is that when you open the file decrypt.txt and read the file, it gets converted into string. But the .decrypt function only accepts input in byte.
I think this should solve your problem:
Generates a key and stores it in key.key file:
from cryptography.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)
write_key()
Encrypts a file and stores it in enc_text.txt file:
from cryptography.fernet import Fernet
with open("key.key","rb") as f:
key=f.read()
f = Fernet(key)
with open('text.txt', 'rb') as original_file:
original = original_file.read()
encrypted = f.encrypt(original)
with open ('enc_text.txt', 'wb') as encrypted_file:
encrypted_file.write(encrypted)
Decrypts the enc_text.txt file and writes the output in decrypt.txt
from cryptography.fernet import Fernet
with open("key.key","rb") as f:
key=f.read()
f = Fernet(key)
with open('enc_text.txt', 'rb') as encrypted_file:
encrypted = encrypted_file.read()
decrypted = f.decrypt(encrypted)
with open('decrypt.txt', 'wb') as decrypted_file:
decrypted_file.write(decrypted)
Sujay's answer was posted while I was writing this one. It is correct, but I still wanted to post this to perhaps give some more insight into what this means.
Most (if not all) encryption tools work on bytes, not str. This is both because these days encrypting binary (non-string) data is more common, and because the encryption algorithms work on numbers, and bytes are strings of numbers in range(0, 256).
In the decryption program, you are loading the ciphertext in this line:
EncryptedFile = open("decrypt.txt", "r")
Contrast this to how you load the encryption key:
def load_key():
return open("secret.key", "rb").read()
The difference is the mode parameter to open: if there is a b in the string, it means it operates in binary mode, working on bytes rather than str. Here's an example:
>>> text = open('test.txt', 'r').read()
>>> text
'Hello World!\n'
>>> binary = open('test.txt', 'rb').read()
>>> binary
b'Hello World!\n'
>>> type(text)
<class 'str'>
>>> type(binary)
<class 'bytes'>
This distinction is important because str represents character sequences, and those can be encoded into binary in vastly different ways. Which of these you choose will affect what ones and zeros go into the encryption algorithm, and consequently what comes out.
The reason the encryption program worked, despite also reading the plaintext file in text mode, is because of this line:
encoded_message = message.encode()
str.encode converts the string into bytes using the encoding supplied, or the default one (usually UTF-8) if it is not specified. The bytes.decode method, seen in the decryption program, does the opposite: it converts bytes to str.
>>> text = '稲妻の腕を借らん草枕'
>>> text.encode()
b'\xe7\xa8\xb2\xe5\xa6\xbb\xe3\x81\xae\xe8\x85\x95\xe3\x82\x92\xe5\x80\x9f\xe3\x82\x89\xe3\x82\x93\xe8\x8d\x89\xe6\x9e\x95'
>>> text.encode('utf-16')
b'\xff\xfe2z\xbbYn0U\x81\x920\x1fP\x890\x930I\x83\x95g'
>>> u16_data = text.encode('utf-16')
>>> u16_data.decode('utf-16')
'稲妻の腕を借らん草枕'
>>> u16_data.decode() # this is why specifying the encoding is important
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte

AttributeError: '_io.TextIOWrapper' object has no attribute 'encrypt'

Im trying to add on to a project listed on https://www.thepythoncode.com/article/encrypt-decrypt-files-symmetric-python which is a text/file encryption setup with python, but every time I try to run the code, I hit the part of the code where it is actually encrypting the file and I'm getting the attribute error listed above
Full Error:
Traceback (most recent call last):
File "/Users/--------/Desktop/CODE/Python/TFEncrypter/TFEncrypter.py", line 38, in
<module>
encrypted_data = f.encrypt(file_data)
AttributeError: '_io.TextIOWrapper' object has no attribute 'encrypt'
Relevant Code:
""" IMPORTING AND DEFINITIONS """
import os
from cryptography.fernet import Fernet
def write_key():
key = Fernet.generate_key()
with open("key.tfe", "wb") as key_file:
key_file.write(key)
def load_key():
return open("key.tfe", "rb").read()
def make_file():
open("tte.txt", "x")
def encrypt(filename, key):
f = Fernet(key)
""" START OF PROGRAM """
path="key.tfe"
if os.path.isfile(path):
load_key()
task = input("Would You Like To Encrypt Or Decrypt A File?")
if type(task) == str:
if task == "Encrypt" or "encrypt":
task = input("Would You Like To Create A New File To Encrypt, Or Encrypt A Pre-Existing File (Note: Pre-Existing Files Must Be Named tte.txt) ANSWER AS: 'NEW FILE' or 'OLD FILE'")
if task == "NEW FILE":
path="tte.txt"
if os.path.isfile(path):
towrite = input("Text to encrypt in file:")
f = open("tte.txt", "w")
f.write(towrite)
with open("tte.txt", "rb") as file:
file_data = file.read()
encrypted_data = f.encrypt(file_data)
with open("encrypted.tfe", "wb") as file:
file.write(encrypted_data)
else:
make_file()
towrite = input("Text to encrypt in file:")
f = open("tte.txt", "w")
f.write(towrite)
with open("tte.txt", "rb") as file:
file_data = file.read()
encrypted_data = f.encrypt(file_data)
with open("encrypted.tfe", "wb") as file:
file.write(encrypted_data)
I have faced similar experience many times using Fernet. Try with simple library called
simplecrypt. You can install this library using pip install simple-crypt
Below is one example for the usage of the simplecrypt
import pandas as pd
from io import StringIO
from simplecrypt import encrypt, decrypt
#Create a dataframe
data = {'Date': ['2019-10-10', '2019-10-12', '2019-10-15'], \
'Credit Amount (SGD)': [40.00, 500.00, 60.00],\
'Transaction type': ['CC *1234', 'Bank transfer', 'CC *1234']}
df = pd.DataFrame(data)
#store in csv format
data_csv = df.to_csv(index=False)
#Encrypt the data by giving password
encdata = encrypt("provide password", data_csv)
#Store encrypted data in file
file_w = open('file.enc', 'wb')
file_w.write(encdata)
file_w.close()
#Decrypt the data from the file
file_r = open('file.enc','rb').read()
CSVplaintext = decrypt("provide the same password", file_r).decode('utf8')
DATA=StringIO(CSVplaintext)
df = pd.read_csv(DATA)
This is very simple to use for encryption and decryptionenter code here

Error cryptography Fernet read token from file

I create the key and I encrypt the message send by user, and store this message in a file and after i try to decrypt this message in the file, but i get this error cryptography.fernet.InvalidToken. I don't use the time for the token and I have also converted in byte after.
My code is:
from cryptography.fernet import Fernet
key = Fernet.generate_key()
f = Fernet(key)
def encry():
global f
what = input("What i need to encrypt?")
what_b = str.encode(what)
token = f.encrypt(what_b)
print("key generated")
print("encrypted")
file1=open("string.txt", "w")
file1.write(str(token))
file1.close()
file2=open("key.txt", "w")
file2.write(str(key))
file2.close()
def decry():
global f
print("decrypted")
file1=open("string.txt", "r").read()
file_de=str.encode(file1)
file2=open("de.txt", "w")
what_d = f.decrypt(file_de)
file1.close()
file2.write(str(what_d))
file2.close()
choose = input("Do you want, encrypt or decrypt?" + " " + "(e/d)")
if choose == "e":
encry()
elif choose == "d":
decry()
else:
print("Nothing to do")
The problem comes from the way you write and read the message and the key to and from the files. Indeed, the encrypted text and the keys are not strings, but byte strings and need to be treated in a different way.
In your case, when reading and writing it is enough to specify that you do it in binary mode and you can do it by adding the b flag. See the documentation for more detailed information.
Moreover, in your decrypt you also need to read the key from the file.
def encry():
key = Fernet.generate_key()
f = Fernet(key)
what = "example"
what_b = str.encode(what)
token = f.encrypt(what_b)
with open("string.txt", "wb") as f1, open("key.txt", "wb") as f2:
f1.write(token)
f2.write(key)
def decry():
with open("string.txt", "rb") as f1, open("key.txt", "rb") as f2:
token = f1.read()
key = f2.read()
f = Fernet(key)
what_d = str(f.decrypt(token),'utf-8') #converting back to string
encry()
decry()

Categories

Resources