How can I encrypt .docx files with AES & pycrypto without corrupting the files
Question: I've got this bit of python code that I want to use to encrypt various kinds
of files with AES 256. I am using the pycrypto module. It works fine for most
files (exe, deb, jpg, pdf, txt) but when it comes to office files (docx, xlsx,
ppt etc) the file is corrupted upon decryption and will no open (nor can it be
repaired) in LibreOffice. I am using Linux mint, python 2.7.6, pycrypto 2.6.1.
I'm still a bit of a noob so I'd appreciate it if you could give me code
examples of the corrections you'd recommend.

Thanks

    
    
    from Crypto import Random
    from Crypto.Cipher import AES
    import os
    
    def pad(s):
        return s + b"\0" * (AES.block_size - len(s) % AES.block_size)
    
    def encrypt(message, key, key_size=256):
        message = pad(message)
        iv = Random.new().read(AES.block_size)
        cipher = AES.new(key, AES.MODE_CBC, iv)
        return iv + cipher.encrypt(message)
    
    def decrypt(ciphertext, key):
        iv = ciphertext[:AES.block_size]
        cipher = AES.new(key, AES.MODE_CBC, iv)
        plaintext = cipher.decrypt(ciphertext[AES.block_size:])
        return plaintext.rstrip(b"\0")
    
    def encrypt_file(file_name, key):
        with open(file_name, 'rb') as fo:
            plaintext = fo.read()
        enc = encrypt(plaintext, key)
        with open(file_name + ".enc", 'wb') as fo:
            fo.write(enc)
    
    def decrypt_file(file_name, key):
        with open(file_name, 'rb') as fo:
            ciphertext = fo.read()
        dec = decrypt(ciphertext, key)
        with open(file_name[:-4], 'wb') as fo:
            fo.write(dec)
    
    key = b'\xbf\xc0\x85)\x10nc\x94\x02)j\xdf\xcb\xc4\x94\x9d(\x9e[EX\xc8\xd5\xbfI{\xa2$\x05(\xd5\x18'
    
    encrypt_file('file.docx', key)
    


Answer: If you need to add padding to make the plaintext a multiple of 16 bytes, the
extra bytes need to be stripped before you write the decrypted data. This
means you will need to somehow include the number of pad bytes added with the
padding before you encrypt it. See PKCS#7 for one possible technique. There
are a number of other schemes as well.

