8

I want to make a script to decrypt my filess, but when I try to run my script then show me this message , how can I fix it?

Traceback (most recent call last): File "F:\bug_bounty\decrypt.py", line 46, in File "F:\bug_bounty\decrypt.py", line 24, in decrypt File "C:\Python27\lib\site-packages\Crypto\Cipher\blockalgo.py", line 295, in decrypt return self._cipher.decrypt(ciphertext) ValueError: Input strings must be a multiple of 16 in length

from Crypto.Hash import SHA256
from Crypto.Cipher import AES
import os
import random
import sys


def decrypt(key, filename):
    outFile = os.path.join(os.path.dirname(filename),
                           os.path.basename(filename[11:]))
    chunksize = 64 * 1024
    with open(filename, 'rb') as infile:
        filesize = infile.read(16)
        IV = infile.read(16)

        decryptor = AES.new(key, AES.MODE_CBC, IV)

        with open(outFile, 'wb') as outfile:
            while True:
                chunk = infile.read(chunksize)
                if len(chunk) == 0:
                    break

                outfile.write(decryptor.decrypt(chunk))

            outfile.truncate(int(filesize))


def allfiles():
    allFiles = []
    for (root, subfiles, files) in os.walk(os.getcwd()):
        for names in files:
            allFiles.append(os.path.join(root, names))

    return allFiles


password = 'M4st3rRul3zs'
files = allfiles();
for filename in files:
    if os.path.basename(filename).startswith("(encrypted)"):
       print "%s is already encrypted" %filename
       pass

    else:  
        decrypt(SHA256.new(password).digest(), filename)
        print "Done decrypting %s" %filename
        """os.remove(filename)"""
Chankey Pathak
  • 21,187
  • 12
  • 85
  • 133
Aron Imperial
  • 99
  • 1
  • 1
  • 7

4 Answers4

7

Here is the small trick you could use while encrypting the data if your data size is not large.

plaintext = "some text"
encryptor = AES.new(key, AES.MODE_CBC, iv)
ciphertext = encryptor.encrypt(plaintext*16)

This will ensure that your input data is a multiple of 16. And of course, you would like to get the original data back when decrypting.

cipher = AES.new(key, AES.MODE_CBC, iv)
decrypttext = cipher.decrypt(ciphertext)
decrypttext = decrypttext[0:len(plaintext)]

Now, decrpyttext has your original plaintext.

B. Go
  • 1,436
  • 4
  • 15
  • 22
Mayank Pathela
  • 453
  • 1
  • 6
  • 15
5

From Crypto++ wiki.

The block size is determined by AES::BLOCKSIZE. For AES, this is always 16 bytes

AES is a block cipher, it works on 16-byte (128-bit) blocks. It can't work with data smaller or bigger than 16 bytes. Smaller data needs to be padded until they're 16 bytes, and larger data needs to be split into 16-byte blocks.

Also there are algorithms that help you achieve just that (work on data larger than the cipher's block size), they're called block cipher modes of operation.

Have a look at this How to encrypt more than 16 bytes using AES?

McGrady
  • 10,869
  • 13
  • 47
  • 69
2

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

That is because AES works with blocks of 128 bits (16 chars). You can consider adding padding to fix this.

Chankey Pathak
  • 21,187
  • 12
  • 85
  • 133
1

AES works with blocks of 16 chars. This how you can add extra padding

import random
import string
plaintext = "Encrypt me"
encryptor = AES.new(key, AES.MODE_CBC, iv)

while len(bytes(plaintext, encoding='utf-8')) % 16 != 0:
     plaintext = plaintext + random.choice(string.ascii_letters)

ciphertext = encryptor.encrypt(plaintext)
Sawan Chauhan
  • 621
  • 7
  • 9
  • 2
    While this code may solve the question, [including an explanation](//meta.stackexchange.com/q/114762) of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please [edit] your answer to add explanations and give an indication of what limitations and assumptions apply. – Dharman Oct 02 '20 at 21:58