-1

I created a small script to encrypt and decrypt a file, however the file is zero bytes and the decrypted file is not created

Code:

from hashlib import md5
from Crypto import Random
from Crypto.Cipher import AES
import os
from Crypto import *

def encrypt(in_file, out_file, key, iv):
    bs = AES.block_size
    cipher = AES.new(key, AES.MODE_CBC, iv)
    finished = False
    while not finished:
        chunk = in_file.read(1024 * bs)
        if len(chunk) == 0 or len(chunk) % bs != 0:
            padding_length = bs - (len(chunk) % bs)
            chunk += bytes(padding_length) * chr(padding_length)
            finished = True
    out_file.write(cipher.encrypt(chunk))

def decrypt(in_file, out_file, key, iv):
    bs = AES.block_size
    cipher = AES.new(key, AES.MODE_CBC, iv)
    next_chunk = ''
    finished = False
    while not finished:
        chunk, next_chunk = next_chunk, cipher.decrypt(in_file.read(1024 * bs))
    if len(next_chunk) == 0:
        padding_length = ord(chunk[-1])
        if padding_length < 1 or padding_length > bs:
            raise ValueError("bad decrypt pad (%d)" % padding_length)
        if chunk[-padding_length:] != (padding_length * chr(padding_length)):
            raise ValueError("bad decrypt")
        chunk = chunk[:-padding_length]
        finished = True
    out_file.write(chunk)


in_file = open('C:/Users/saeed/Desktop/ImportantFolder/arrest.jpg', 'rb')
out_file = open('C:/Users/saeed/Desktop/ImportantFolder/arrest_enc.jpg', 'wb')
key = os.urandom(32)
iv = os.urandom(16)
encrypt(in_file, out_file, key, iv)
in_file.close()
out_file.close()
print('Encrypted!')

in_file = open('C:/Users/saeed/Desktop/ImportantFolder/arrest_enc.jpg', 'rb')
out_file = open('C:/Users/saeed/Desktop/ImportantFolder/arrest_dec.jpg', 'wb')
decrypt(in_file, out_file, key, iv)
in_file.close()
out_file.close()
print('Decrypted!')

The file that is encrypted, _enc is created but is zero bytes, and cannot be decrypted as the code stops. It gets stuck in the encryption process and never prints Encrypted!. Errors:

Traceback (most recent call last):
  File "C:/Users/saeed/IdeaProjects/encryptor/encryption.py", line 41, in <module>

encrypt(in_file, out_file, key, iv)

File "C:/Users/saeed/IdeaProjects/encryptor/encryption.py", line 15, in 
encrypt

chunk += padding_length * chr(padding_length)
TypeError: can't concat bytes to str

What does this mean and how do I fix it?

SDurrani
  • 33
  • 5
  • It would really help you to get a Python IDE where you can step through the code to examine the execution. – zaph Mar 14 '17 at 16:21
  • You should add which python version you are using, that is important here. Probably python3, where you can't mix bytes ans str. `bytestr[idx]` gives you the value as int directly (don't use `ord()`), and instead of `chr(byteval)` you can use `bytes([byteval])` – mata Mar 14 '17 at 16:29

1 Answers1

1

When reading from a file the type of the read data is a bytes type and not a str type. If you instead use chunk += bytes( padding_length ) the padding will be appended to the chunk.

FluxIX
  • 325
  • 1
  • 2
  • 13
  • When using this, I get: chunk += bytes(padding_length) * chr(padding_length) TypeError: can't multiply sequence by non-int of type 'str' – SDurrani Mar 14 '17 at 16:10
  • 1
    That should probably be `chunk += bytes([padding_length]) * padding_length` – mata Mar 14 '17 at 16:33
  • I wasn't sure what padding character was desired. `bytes( padding_length )` will produce a sequence of null-characters `padding_length` in length. – FluxIX Mar 14 '17 at 16:44