fernet: cryptography.fernet.InvalidToken when decrypting a file - python

I'm trying to decrypt a string using fernet. My code (assume files already exist with pre-filled data):
import hashlib
import bcrypt
from cryptography.fernet import Fernet
import base64
#encrypting
############################################################
file = open('message.txt', 'r+')
message = file.read()
file.close()
password = input("Enter password: ")
file = open('passsalt.txt', 'r+')
salt = file.read()
file.close()
passwordnhash = str(password) + str(salt)
passwordnhash = passwordnhash.encode('utf-8')
hash = hashlib.sha256(passwordnhash).digest()
key = base64.urlsafe_b64encode(hash)
fernet = Fernet(key)
encMessage = fernet.encrypt(message.encode())
file = open('message.ivf', 'w+')
file.write(str(encMessage))
file.close()
############################################################
#decrypting
file = open('message.ivf', 'r+')
token = file.read()
file.close()
token = token.encode('utf-8')
file = open('passsalt.txt', 'r+')
salt = file.read()
file.close()
passwordnhash = str(password) + str(salt)
passwordnhash = passwordnhash.encode('utf-8')
hash = hashlib.sha256(passwordnhash).digest()
key = base64.urlsafe_b64encode(hash)
fernet = Fernet(key)
#token = fernet.encrypt(message)
d = fernet.decrypt(token)
print(d)
This returns the error
cryptography.fernet.InvalidToken
While decrypting. I'm unsure on what to do. I have viewed many questions but none have a fix for me. Links:
Stack Overflow question 1
Stack Overflow question 2
Stack Overflow question 3
Thanks in advance

Related

How to decrypt config.ini file keeping its original (before encyrpt) format and extension (Python - cryptography fernet)

Here is my code to encrypt the config.ini file which has sql connection details (username and pw) and some file paths.
from cryptography.fernet import Fernet
key = Fernet.generate_key()
i_file = 'conf.ini'
o_file = 'Conf_encry.ini'
with open(i_file,'rb') as f:
data = f.read()
fernet = Fernet(key)
encrypt = fernet.encrypt(data)
with open(o_file,'wb') as f:
f.write(encrypt)
print(key)
This will encrypt my file to Conf_encry.ini
And this is my code to decrypt the Conf_encry.ini file
from cryptography.fernet import Fernet
k_file = 'key.txt'
i_file = 'Conf_encry.ini'
with open(k_file, 'rb') as k:
key = k.read()
with open(i_file, 'rb') as f:
data = f.read()
fernet = Fernet(key)
decry = fernet.decrypt(data)
print(decry)
But problem is after decrypting the i_file its getting converted into usual txt file with lots of \r , \n and spaces. And that's why code (configparser) which reads this conf file as dict gives an error
# Original Configuration file before encrypt
[ABC]
host= a01
port = 1234
database = DB_1
user = DB_u_1
password = DB_p_1
[XYZ]
host = b01
database = DB_2
[URLList]
U1 = http://findbest.com
U2 = http://findall.com
[FPath]
filepath1 = r1.csv
# File after decrypting
b'[ABC]\r\nhost= a01 \r\nport = 1234\r\ndatabase = DB_1\r\nuser = DB_u_1\r\npassword = DB_p_1\r\n\r\n[XYZ]\r\nhost = b01 \r\ndatabase = DB_2\r\n\r\n[URLList]\r\nU1 = http://findbest.com\r\nU2 = http://findall.com\r\n\r\n[FPath]\r\nfilepath1 = r1.csv'
Any clue to resolve this?
Solution was simple. We can just write decrypted output to some file again
with open(o_file,'wb') as f:
f.write(decry)
Thanks for the explanation President James K. Polk

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

Python3 - Encrypting and decrypting an image (Fernet) Issue

Good day,
I am doing an assignment for cryptography. It's an easy task I need to take any image, turn it into HEX, encrypt it and then decrypt it.
As I am working in Python and there was no specific encryption method in the task I just use Fernet.
I have an encryptor and decryptor scripts.
Encryption seems to be working because as a test I create a txt document with original HEX and after decryption the program states that original HEX and decrypted one are the same, however the decrypted image is not loading.
Could anyone help out a newbie?
Encryptor:
import binascii
from cryptography.fernet import Fernet
img = 'panda.png'
with open(img, 'rb') as f:
content = f.read()
hexValue = binascii.hexlify(content)
key = Fernet.generate_key()
with open('info/key.txt', mode='w+') as keyValue:
keyValue.write(key)
keyValue.seek(0)
f = Fernet(key)
encHexVal = f.encrypt(hexValue)
with open('info/encryptedHex.txt', mode='w+') as hexValueFile:
hexValueFile.write(encHexVal)
hexValueFile.seek(0)
a = f.decrypt(encHexVal)
with open('info/realValue.txt', mode='w+') as writeHex:
originalHex = writeHex.write(hexValue)
with open('info/realValue.txt', mode='r') as reading:
realValue = reading.read()
if realValue == a:
print("We're good to go!")
else:
print("Oops something went wrong. Check the source code.")
Decryptor:
import binascii
from cryptography.fernet import Fernet
with open('info/key.txt', mode='rb') as keyValue:
key = keyValue.read()
f = Fernet(key)
with open('info/encryptedHex.txt', mode='rb') as imageHexValue:
hexValue = imageHexValue.read()
a = f.decrypt(hexValue)
with open('info/realValue.txt', mode='r') as compare:
realContents = compare.read()
print("Small test in safe environment...")
if realContents == a:
print("All good!")
else:
print("Something is wrong...")
data = a.encode()
data = data.strip()
data = data.replace(' ', '')
data = data.replace('\n', '')
with open('newImage.png', 'wb') as file:
file.write(data)
I am using a random image from the internet of Po from Kung Fu Panda:
The principle problem is that although you hexlify then encrypt in the encryptor you don't unhexlify after decrypting in the decryptor. Its far more common to do things the other way, encrypt then hexlify so that the encrypted binary can be stored in regular text files or sent via http.
You have several problems with trying to write bytes objects to files open in text. I fixed those along the way. But it does leave me puzzled why a file called 'info/encryptedHex.txt' would be binary.
Encryptor
import binascii
from cryptography.fernet import Fernet
# Generate keyfile
#
# TODO: Overwrites key file on each run, invalidating previous
# saves. You could do `if not os.path.exists('info/key.txt'):`
key = Fernet.generate_key()
with open('info/key.txt', mode='wb') as keyValue:
keyValue.write(key)
# Encrypt image
img = 'panda.png'
with open(img, 'rb') as f:
content = f.read()
hexValue = binascii.hexlify(content)
f = Fernet(key)
encHexVal = f.encrypt(hexValue)
with open('info/encryptedHex.txt', mode='wb') as hexValueFile:
hexValueFile.write(encHexVal)
# Verification checks
a = f.decrypt(encHexVal)
# hexed bytes is same encoding as 'ascii'
with open('info/realValue.txt', mode='wb') as writeHex:
originalHex = writeHex.write(hexValue)
with open('info/realValue.txt', mode='r', encoding='ascii') as reading:
realValue = reading.read()
if realValue == a.decode('ascii'):
print("We're good to go!")
else:
print("Oops something went wrong. Check the source code.")
Decryptor
import binascii
from cryptography.fernet import Fernet
# Generate keyfile
#
# TODO: Overwrites key file on each run, invalidating previous
# saves. You could do `if not os.path.exists('info/key.txt'):`
key = Fernet.generate_key()
with open('info/key.txt', mode='wb') as keyValue:
keyValue.write(key)
# Encrypt image
img = 'panda.png'
with open(img, 'rb') as f:
content = f.read()
hexValue = binascii.hexlify(content)
f = Fernet(key)
encHexVal = f.encrypt(hexValue)
with open('info/encryptedHex.txt', mode='wb') as hexValueFile:
hexValueFile.write(encHexVal)
# Verification checks
a = f.decrypt(encHexVal)
# hexed bytes is same encoding as 'ascii'
with open('info/realValue.txt', mode='wb') as writeHex:
originalHex = writeHex.write(hexValue)
with open('info/realValue.txt', mode='r', encoding='ascii') as reading:
realValue = reading.read()
if realValue == a.decode('ascii'):
print("We're good to go!")
else:
print("Oops something went wrong. Check the source code.")
(base) td#timpad:~/dev/SO/Encrypting and decrypting in image$ cat de.py
import binascii
from cryptography.fernet import Fernet
with open('info/key.txt', mode='rb') as keyValue:
key = keyValue.read()
f = Fernet(key)
with open('info/encryptedHex.txt', mode='rb') as imageHexValue:
encHexValue = imageHexValue.read()
hexValue = f.decrypt(encHexValue)
binValue = binascii.unhexlify(hexValue)
with open('info/realValue.txt', mode='rb') as compare:
realContents = compare.read()
print("Small test in safe environment...")
if realContents == hexValue:
print("All good!")
else:
print("Something is wrong...")
with open('newImage.png', 'wb') as file:
file.write(binValue)

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()

RSA encryption and decryption in Python

I need help using RSA encryption and decryption in Python.
I am creating a private/public key pair, encrypting a message with keys and writing message to a file. Then I am reading ciphertext from file and decrypting text using key.
I am having trouble with the decryption portion. As you can see in my code below, when I put in decrypted = key.decrypt(message) that the program works, yet the decrypted message is encrypted again. It seems like it is not reading the ciphertext from the file.
Can anyone help me write this code so decryption reads ciphertext from file and then uses key to decrypt ciphertext?
import Crypto
from Crypto.PublicKey import RSA
from Crypto import Random
random_generator = Random.new().read
key = RSA.generate(1024, random_generator) #generate public and private keys
publickey = key.publickey # pub key export for exchange
encrypted = publickey.encrypt('encrypt this message', 32)
#message to encrypt is in the above line 'encrypt this message'
print 'encrypted message:', encrypted #ciphertext
f = open ('encryption.txt', 'w'w)
f.write(str(encrypted)) #write ciphertext to file
f.close()
#decrypted code below
f = open ('encryption.txt', 'r')
message = f.read()
decrypted = key.decrypt(message)
print 'decrypted', decrypted
f = open ('encryption.txt', 'w')
f.write(str(message))
f.write(str(decrypted))
f.close()
In order to make it work you need to convert key from str to tuple before decryption(ast.literal_eval function). Here is fixed code:
import Crypto
from Crypto.PublicKey import RSA
from Crypto import Random
import ast
random_generator = Random.new().read
key = RSA.generate(1024, random_generator) #generate pub and priv key
publickey = key.publickey() # pub key export for exchange
encrypted = publickey.encrypt('encrypt this message', 32)
#message to encrypt is in the above line 'encrypt this message'
print('encrypted message:', encrypted) #ciphertext
f = open ('encryption.txt', 'w')
f.write(str(encrypted)) #write ciphertext to file
f.close()
#decrypted code below
f = open('encryption.txt', 'r')
message = f.read()
decrypted = key.decrypt(ast.literal_eval(str(encrypted)))
print('decrypted', decrypted)
f = open ('encryption.txt', 'w')
f.write(str(message))
f.write(str(decrypted))
f.close()
PKCS#1 OAEP is an asymmetric cipher based on RSA and the OAEP padding
from Crypto.PublicKey import RSA
from Crypto import Random
from Crypto.Cipher import PKCS1_OAEP
def rsa_encrypt_decrypt():
key = RSA.generate(2048)
private_key = key.export_key('PEM')
public_key = key.publickey().exportKey('PEM')
message = input('plain text for RSA encryption and decryption:')
message = str.encode(message)
rsa_public_key = RSA.importKey(public_key)
rsa_public_key = PKCS1_OAEP.new(rsa_public_key)
encrypted_text = rsa_public_key.encrypt(message)
#encrypted_text = b64encode(encrypted_text)
print('your encrypted_text is : {}'.format(encrypted_text))
rsa_private_key = RSA.importKey(private_key)
rsa_private_key = PKCS1_OAEP.new(rsa_private_key)
decrypted_text = rsa_private_key.decrypt(encrypted_text)
print('your decrypted_text is : {}'.format(decrypted_text))
# coding: utf-8
from __future__ import unicode_literals
import base64
import os
import six
from Crypto import Random
from Crypto.PublicKey import RSA
class PublicKeyFileExists(Exception): pass
class RSAEncryption(object):
PRIVATE_KEY_FILE_PATH = None
PUBLIC_KEY_FILE_PATH = None
def encrypt(self, message):
public_key = self._get_public_key()
public_key_object = RSA.importKey(public_key)
random_phrase = 'M'
encrypted_message = public_key_object.encrypt(self._to_format_for_encrypt(message), random_phrase)[0]
# use base64 for save encrypted_message in database without problems with encoding
return base64.b64encode(encrypted_message)
def decrypt(self, encoded_encrypted_message):
encrypted_message = base64.b64decode(encoded_encrypted_message)
private_key = self._get_private_key()
private_key_object = RSA.importKey(private_key)
decrypted_message = private_key_object.decrypt(encrypted_message)
return six.text_type(decrypted_message, encoding='utf8')
def generate_keys(self):
"""Be careful rewrite your keys"""
random_generator = Random.new().read
key = RSA.generate(1024, random_generator)
private, public = key.exportKey(), key.publickey().exportKey()
if os.path.isfile(self.PUBLIC_KEY_FILE_PATH):
raise PublicKeyFileExists('Файл с публичным ключом существует. Удалите ключ')
self.create_directories()
with open(self.PRIVATE_KEY_FILE_PATH, 'w') as private_file:
private_file.write(private)
with open(self.PUBLIC_KEY_FILE_PATH, 'w') as public_file:
public_file.write(public)
return private, public
def create_directories(self, for_private_key=True):
public_key_path = self.PUBLIC_KEY_FILE_PATH.rsplit('/', 1)
if not os.path.exists(public_key_path):
os.makedirs(public_key_path)
if for_private_key:
private_key_path = self.PRIVATE_KEY_FILE_PATH.rsplit('/', 1)
if not os.path.exists(private_key_path):
os.makedirs(private_key_path)
def _get_public_key(self):
"""run generate_keys() before get keys """
with open(self.PUBLIC_KEY_FILE_PATH, 'r') as _file:
return _file.read()
def _get_private_key(self):
"""run generate_keys() before get keys """
with open(self.PRIVATE_KEY_FILE_PATH, 'r') as _file:
return _file.read()
def _to_format_for_encrypt(self, value):
if isinstance(value, int):
return six.binary_type(value)
for str_type in six.string_types:
if isinstance(value, str_type):
return value.encode('utf8')
if isinstance(value, six.binary_type):
return value
And use
KEYS_DIRECTORY = settings.SURVEY_DIR_WITH_ENCRYPTED_KEYS
class TestingEncryption(RSAEncryption):
PRIVATE_KEY_FILE_PATH = KEYS_DIRECTORY + 'private.key'
PUBLIC_KEY_FILE_PATH = KEYS_DIRECTORY + 'public.key'
# django/flask
from django.core.files import File
class ProductionEncryption(RSAEncryption):
PUBLIC_KEY_FILE_PATH = settings.SURVEY_DIR_WITH_ENCRYPTED_KEYS + 'public.key'
def _get_private_key(self):
"""run generate_keys() before get keys """
from corportal.utils import global_elements
private_key = global_elements.request.FILES.get('private_key')
if private_key:
private_key_file = File(private_key)
return private_key_file.read()
message = 'Hello мой friend'
encrypted_mes = ProductionEncryption().encrypt(message)
decrypted_mes = ProductionEncryption().decrypt(message)
Here is my implementation for python 3 and pycrypto
from Crypto.PublicKey import RSA
key = RSA.generate(4096)
f = open('/home/john/Desktop/my_rsa_public.pem', 'wb')
f.write(key.publickey().exportKey('PEM'))
f.close()
f = open('/home/john/Desktop/my_rsa_private.pem', 'wb')
f.write(key.exportKey('PEM'))
f.close()
f = open('/home/john/Desktop/my_rsa_public.pem', 'rb')
f1 = open('/home/john/Desktop/my_rsa_private.pem', 'rb')
key = RSA.importKey(f.read())
key1 = RSA.importKey(f1.read())
x = key.encrypt(b"dddddd",32)
print(x)
z = key1.decrypt(x)
print(z)
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
secret_message = b'ATTACK AT DAWN'
### First, make a key and save it
key = RSA.generate(2048)
with open( 'mykey.pem', 'wb' ) as f:
f.write( key.exportKey( 'PEM' ))
### Then use key to encrypt and save our message
public_crypter = PKCS1_OAEP.new( key )
enc_data = public_crypter.encrypt( secret_message )
with open( 'encrypted.txt', 'wb' ) as f:
f.write( enc_data )
### And later on load and decode
with open( 'mykey.pem', 'r' ) as f:
key = RSA.importKey( f.read() )
with open( 'encrypted.txt', 'rb' ) as f:
encrypted_data = f.read()
public_crypter = PKCS1_OAEP.new( key )
decrypted_data = public_crypter.decrypt( encrypted_data )
You can use simple way for genarate RSA . Use rsa library
pip install rsa
Watch out using Crypto!!!
It is a wonderful library but it has an issue in python3.8 'cause from the library time was removed the attribute clock(). To fix it just modify the source in /usr/lib/python3.8/site-packages/Crypto/Random/_UserFriendlyRNG.pyline 77 changing t = time.clock() int t = time.perf_counter()

Categories

Resources