Search code examples
pythonhashaespycrypto

PyCrypto returns a keysize error for AES


I'm trying to write a program to encrypt files using AES, however I get a

ValueError: AES key must be either 16, 24, or 32 bytes long

error no matter the size of the key.

My code for generating the AES object is

def AESEncryptor(Seed, Block = 16): #Generate AES key and Cipher
    iv = Random.new().read(Block)
    cipher = AES.new(Seed.encode('utf8'), AES.MODE_CBC, iv)
    return cipher, iv

And my code for generating the key is

def genNewSeed(k=2048): #Generate seed for new AES key
    return hashlib.sha256(os.urandom(32)).hexdigest()[:11]

Which, according to sys.getsizeof() is equal to 32 bits yet it still returns the error


Solution

  • The problem is that you're slicing off only 11 bytes from a hex-encoded "seed" of 64 characters. Keep in mind that keys are supposed to have high entropy, otherwise it's easier to brute force them.

    I suggest you use:

    def AESEncryptor(Seed, Block = 16): #Generate AES key and Cipher
        iv = Random.new().read(Block)
        cipher = AES.new(Seed, AES.MODE_CBC, iv)
        return cipher, iv
    
    def genNewSeed(k=2048): #Generate seed for new AES key
        return hashlib.sha256(os.urandom(32)).digest()
    

    This will give you a 32 byte key which makes this AES-256. If you want AES-128, then you can slice the last 16 bytes off:

    hashlib.sha256(os.urandom(32)).digest()[:16]
    

    You cannot use sys.getsizeof() to determine the size of a key, because it includes all kinds of internal counters and data. For example, an empty string has already a size of 21 bytes. That's why you would thought that you got 32 byte when you only got 11 (21 + 11 = 32). Use the built-in len(key) instead.