0

I'm attempting to read a text file into a string and then decrypt that string but it keeps failing and giving the following error

ValueError: Input strings must be a multiple of 16 in length

I know the encryption works because I've tested it so it has something to do with the Display_All function and presumably how the file is being read, any help would be really appreciated!

class Encryption(object):

    def __init__(self, key):
        self.blockSize = 32
        self.key = key



    def Encrypt(self, plainText):
        plainText = self.Pad_Text(plainText)
        iv = Random.new().read(AES.block_size)
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return base64.b64encode(iv + cipher.encrypt(plainText)) 




    def Decrypt(self, secretText):  
        secretText = base64.b64decode(secretText)
        iv = secretText[:AES.block_size]
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return self.Unpad_Text(cipher.decrypt(secretText[AES.block_size:])).decode('utf-8')




    def Pad_Text(self, text):
         return text + (self.blockSize - len(text) % self.blockSize) * chr(self.blockSize - len(text) % self.blockSize)


    @staticmethod
    def Unpad_Text(text):
        return text[:-ord(text[len(text)-1:])]


def Display_All():
    try:
        if sys.platform == 'win32':
            if os.path.isdir("C:\\APV\\"):           
                file = open("C:\\APV\\Private.txt", "rb")
                string = file.read()
                plain = e.Decrypt(string)
                displayWindow.insert('end', plain)
    except OSError:
        pass

    return None

def Write_Test(event): 
    try:
        if sys.platform == "win32":
            if os.path.isdir("C:\\APV\\"):
                file = open("C:\\APV\\Private.txt", "a")
                temp2 = Test_entry.get()
                encrypted = e.Encrypt(temp2)
                file.write(str(encrypted) + "\n")
                file.close()
                Test_entry.delete(0, END)
    except OSError:
       pass 

I realize there are much better ways of doing this and while I'm more than interested in learning about them my priority is simply learning pycryptos libraries which is why I decided to use an example I found here as a simple test. See below for a small example

e = Encryption("!.o8d@c#)*=_FFsxc*@^;:12axcvbfd|")

tempTest = "This is just a quick dirty example\nshowing that the encryption does work"
random = e.Encrypt(tempTest)
print(random)

decrypted = e.Decrypt(random)
print("\n\n\n\n" + decrypted)

Produces the following output

b'ZiQ1nBUUx3Q+ZKeMlw2IXBlJoSXnWyTkWZsKVivFbENrVt78BV13/aLlFosw5v590y8WECu9f6U3D4sxlQhwbCNiDGSqMIm7Qids1aprD7JeAm/0mTpXhuF5nPJKqlylhweMsxfql7Ba6EplNyehnQ=='




This is just a quick dirty example
showing that the encryption does work
suroh
  • 917
  • 1
  • 10
  • 26
  • Your code looks fine aside from `self.blockSize = 32`. It must be `self.blockSize = 16` for AES. – Artjom B. Jun 17 '16 at 13:15
  • Yeah I tried switching it to 16 but it produces the same result, check out my edit – suroh Jun 17 '16 at 13:18
  • How did you create Private.txt? Can you add a full encryption/decryption cycle? Where do you set the key? – Artjom B. Jun 17 '16 at 13:19
  • The text file is created via a script and it's a generic way of doing so, the full cycle is what I gave here I added an edit to show that the code does work. Is it possible when the file is being read the b' ' is causing the issue? – suroh Jun 17 '16 at 13:23
  • Whether you use `..b` or not doesn't make much difference, because the ciphertext is Base64-encoded. So, since the cycle works correctly, the issue must be in the code which uses this encryption, but you haven't shown it (fully). The append mode in `file = open("C:\\APV\\Private.txt", "a")` seems strange. Maybe you should try to decrypt line by line and not everything at the same time. – Artjom B. Jun 17 '16 at 13:31
  • How is the way the file is being appended strange, I'm not sure what you mean? Also, what you see is what I have the only difference between the rest of my code and what's here is that I've got about 20 other functions that don't use the encryption and the rest is setting up a gui in tkinter I'm not sure providing it would change anything... The only code that uses the encryption is what I've provided :) As for decrypting line by line it only writes one line at a time so I'm only attempting to decrypt one line atm. – suroh Jun 17 '16 at 13:35
  • You're able to write multiple ciphertexts to the same file in separate lines, but since you're reading the file once, the Base64 decoding as part of the decryption of that one file will be broken. You need to decrypt line by line. Anyway, if you're using Python 3, then `str(encrypted)` might be the problem. Bytes and strings need to be treated differently for a reason. But since `encrypted` is Base64-encoded, this should not make a difference. I don't know why you have a problem. – Artjom B. Jun 17 '16 at 13:43
  • I know I can write more than one, I just only want to write one line:! I was thinking the str(encrypted) was the issue but I agree because it's base64 encoded it shouldn't matter and my other tests prove it doesn't. I'll try it again line by line. – suroh Jun 17 '16 at 13:46

0 Answers0