Home > Software engineering >  TypeError: argument should be a bytes-like object or ASCII string, not 'BufferedReader'
TypeError: argument should be a bytes-like object or ASCII string, not 'BufferedReader'

Time:10-25

I am trying to make a password storage system, but am currently struggling with an error from a python module ( cryptography.fernet) . I have tried googling but have come to no avail and am asking here. Does anybody know how to fix this? ( code below )

import PGL
from cryptography.fernet import Fernet as Fn
class APM():
    class database():
        def genkey():
            keyfile = open("D:\\CODING\\Python\\APMKEY.APMKEY", "wb")
            key = Fn.generate_key()
            keyfile.write(key)
        def encrypt(self):
            key = open("D:\\CODING\\Python\\APMKEY.APMKEY", "rb")
            database = open("D:\\CODING\\Python\\APMDatabase.APMDATA", "w")

            newdata = Fn(key).encrypt(database.encode())
            database.write(newdata)
        def decrypt(self):
            key = open("D:\\CODING\\Python\\APMKEY.APMKEY", "rb")
            database = open("D:\\CODING\\Python\\APMDatabase.APMDATA", "w")

            newdata = Fn(key).decrypt(database)
            database.write(newdata)
        def access(self):
            database = open("D:\\CODING\\Python\\APMDatabase.APMDATA", "r")
            content = database.readlines()
            print(content)
        def write(self):
            database = open("D:\\CODING\\Python\\APMDatabase.APMDATA", "a")
            database.write("\"NAME OF SITE\", \"WEBSITE URL\", \"USERNAME\", \"PASSWORD\", \"XTRA INFO\"\n")
        def reencrypt():
            key = Fn.generate_key()
            keyfile = open("D:\\CODING\\Python\\APMKEY.APMKEY", "r")
            oldkey = keyfile.read()
            keyfile.close()
            keyfile = open("D:\\CODING\\Python\\APMKEY.APMKEY", "w")
            keyfile.write(key)
            APM.database.decrypt(oldkey)
            APM.database.encrypt(key)



    class gen():
        def password():
            PGL.gen.password()
        def username():
            PGL.gen.username()

APM.database.encrypt("a")

for more context, PGL is a file which generates a password and a username for me, and the "a" in the function "APM.database.encrypt("a")" is just a filler for self, as i havent implemented it fully. Traceback:

Traceback (most recent call last):
  File "D:\CODING\Python\APM.py", line 51, in <module>
    APM.database.encrypt("a")
  File "D:\CODING\Python\APM.py", line 18, in encrypt
    newdata = Fn(key).encrypt(database.encode())
  File "C:\Users\Anton\AppData\Local\Programs\Python\Python310\lib\site-packages\cryptography\fernet.py", line 33, in __init__
    key = base64.urlsafe_b64decode(key)
  File "C:\Users\Anton\AppData\Local\Programs\Python\Python310\lib\base64.py", line 131, in urlsafe_b64decode
    s = _bytes_from_decode_data(s)
  File "C:\Users\Anton\AppData\Local\Programs\Python\Python310\lib\base64.py", line 45, in _bytes_from_decode_data
    raise TypeError("argument should be a bytes-like object or ASCII "
TypeError: argument should be a bytes-like object or ASCII string, not 'BufferedReader'
Press any key to continue . . .

CodePudding user response:

By the looks of it, you might want something like this. (You should maybe brush up on how classes and instance methods work.)

from cryptography.fernet import Fernet


class APMDatabase:
    def __init__(self, keyfile_path, database_path):
        self.keyfile_path = keyfile_path
        self.database_path = database_path

    def generate_key(self):
        key = Fernet.generate_key()
        with open(self.keyfile_path, "wb") as keyfile:
            keyfile.write(key)

    def read_key(self):
        with open(self.keyfile_path, "rb") as keyfile:
            return keyfile.read()

    def encrypt(self):
        key = self.read_key()
        with open(self.database_path, "rb") as database:
            newdata = Fernet(key).encrypt(database.read())
        with open(self.database_path, "wb") as database:
            database.write(newdata)

    def decrypt(self):
        key = self.read_key()
        with open(self.database_path, "rb") as database:
            newdata = Fernet(key).decrypt(database.read())
        with open(self.database_path, "wb") as database:
            database.write(newdata)

    def write(self, line):
        # NB: database must be decrypted before calling this
        with open(self.database_path, "a") as database:
            database.write(line)

    def reencrypt(self):
        self.decrypt()  # decrypt with current key
        self.generate_key()  # generate and write new key
        self.encrypt()  # encrypt with new key


db = APMDatabase(
    keyfile_path="D:\\CODING\\Python\\APMKEY.APMKEY",
    database_path="D:\\CODING\\Python\\APMDatabase.APMDATA",
)

db.write('"NAME OF SITE", "WEBSITE URL", "USERNAME", "PASSWORD", "XTRA INFO"\n')
db.encrypt()
  • Related