Search code examples
pythonencryptionbyteaes

byte problems while encrypting with AES


i wrote a code using Crypto.cipher that will go over all the files in the directory/sub-directory and encrypt them using AES-ECB. now the problem is that for some reason i get this error:

raise ValueError("Error %d while encrypting in ECB mode" % result) ValueError: Error 3 while encrypting in ECB mode

i tried converting the bytes to base64 and i still got the same problem, i thought at first that it might just be certain files that are encoded in a different way but then i took a look at the list and some of the files that gave this exception are .txt and just have some numbers in them so im not sure what the problem is.

with open(loc, 'rb') as file:
     data = file.read()
     Edata = Encrypt(data)

This is how i encrypt it:

def Encrypt(msg): #AES
    pad = lambda x: x + (SIZE - len(x) % SIZE) * PADDING
    print(type(msg))
    msg = pad(msg)
    cipher = AES.new(hkey,AES.MODE_ECB)
    cipherTxt = cipher.encrypt(msg)
    return cipherTxt

edit: python 3.6

def Decrypt(msg): #AES
    decipher = AES.new(hkey,AES.MODE_ECB)
    plain = decipher.decrypt(msg)
    index = plain.find(b".")
    original = msg[:index]
    return original

Solution

  • Encrypting binary data works with my crypto package (from anaconda). You may be using a different package - mine will error if you try to encrypt a string. This may just be a straw man, but this works for me:

    from Crypto.Cipher import AES
    from Crypto.Hash import SHA256
    import random
    
    password = "temp"
    hashObj = SHA256.new(password.encode("utf-8"))
    hkey = hashObj.digest()
    
    def Encrypt(msg, blocksize=16):
        """encrypt msg with padding to blocksize. Padding rule is to fill with
        NUL up to the final character which is the padding size as an 8-bit
        integer (retrieved as `msg[-1]`)
        """
        assert blocksize > 2 and blocksize < 256
        last = len(msg) % blocksize
        pad = blocksize - last
        random_pad = bytes(random.sample(range(255), pad-1))
        msg = msg + random_pad + bytes([pad])
        cipher = AES.new(hkey,AES.MODE_ECB)
        cipherTxt = cipher.encrypt(msg)
        return cipherTxt
    
    def Decrypt(msg): #AES
        decipher = AES.new(hkey,AES.MODE_ECB)
        print('msg size', len(msg))
        plain = decipher.decrypt(msg)
        print('plain', plain)
        original = plain[:-plain[-1]]
        return original
    
    
    # test binary data
    sample = bytes(range(41))
    print('sample', sample)
    encrypted = Encrypt(sample, 16)
    print('encrypted', encrypted)
    print(len(sample), len(encrypted))
    decrypted = Decrypt(encrypted)
    print('decrypted', decrypted)
    print('matched', decrypted == sample)
    
    # test blocksize boundary
    sample = bytes(range(48))
    decrypted = Decrypt(Encrypt(sample))
    print('on blocksize', sample==decrypted)