1

I have been trying to decrypt a file in android, encrypted from python, Here is python code i used in decrypting.

import os, random, struct
from Crypto.Cipher import AES
import sys
import hashlib

print("trying")

def encrypt_file(key, in_filename, out_filename=None, chunksize=64*1024):
    """ Encrypts a file using AES (CBC mode) with the
        given key.

        key:
            The encryption key - a string that must be
            either 16, 24 or 32 bytes long. Longer keys
            are more secure.

        in_filename:
            Name of the input file

        out_filename:
            If None, '<in_filename>.enc' will be used.

        chunksize:
            Sets the size of the chunk which the function
            uses to read and encrypt the file. Larger chunk
            sizes can be faster for some files and machines.
            chunksize must be divisible by 16.
    """
    if not out_filename:
        out_filename = in_filename + '.mjt'

    iv = 16 * '\x00'
    encryptor = AES.new(key, AES.MODE_CBC, iv)
    filesize = os.path.getsize(in_filename)

    with open(in_filename, 'rb') as infile:
        with open(out_filename, 'wb') as outfile:
            outfile.write(struct.pack('<Q', filesize))
            # outfile.write(iv)
            outfile.write(bytes(iv, 'UTF-8'))

            while True:
                chunk = infile.read(chunksize)
                if len(chunk) == 0:
                    break
                elif len(chunk) % 16 != 0:
                    chunk += b' ' * (16 - len(chunk) % 16)

                outfile.write(encryptor.encrypt(chunk))
                # outfile.write(bytes(encryptor.encrypt(chunk), 'UTF-8'))


def main():
    filename1 = sys.argv[-2]
    filename2 = sys.argv[-1]
    key = '0123456789abcdef'
    encrypt_file(key, filename1, filename2)
    print("done")


if __name__ == '__main__':
    main()

and here is my android function trying to decrypt with

private static byte[] ivBytes = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

public static void decrypt(String inputFile, String outputFile, String password) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException {
        FileInputStream fis = new FileInputStream(inputFile);

        FileOutputStream fos = new FileOutputStream(outputFile);

        IvParameterSpec iv = new IvParameterSpec(ivBytes);
        SecretKeySpec sks = new SecretKeySpec(password.getBytes(), "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
        cipher.init(Cipher.DECRYPT_MODE, sks, iv);
        CipherInputStream cis = new CipherInputStream(fis, cipher);

        int b;
        byte[] d = new byte[1024];
        while((b = cis.read(d)) != -1) {
            fos.write(d, 0, b);
        }
        fos.flush();
        fos.close();
        cis.close();
    }

this gives while using AES/CBC/NoPadding java.io.IOException: data not block size aligned and when AES/CBC/PKCS5Padding is used, it gives java.io.IOException: last block incomplete in decryption

1 Answer 1

1

AES is a block cipher so the messages need to be padded to exactly the multiple of the block size, both at encryption and decryption. Your encryption is fine. It reads the filesize, writes to first 8 bytes of your file, then writes 16 bytes IV and finally the content of file chunk by chunk ensuring the padding. However, your decryption does not follow the same pattern for decryption. AES is a 128 bit block cipher so you don't have to worry much about specifying PKCS5Padding, just need to follow the same routine in reverse as your encryption. There was a bug in your code related to iv too.

Try the following and it should work:

private static byte[] filesize = new byte[8];
private static byte[] ivBytes = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

public static void decrypt(String inputFile, String outputFile, String password) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException {
    FileInputStream fis = new FileInputStream(inputFile);
    FileOutputStream fos = new FileOutputStream(outputFile);
    fis.read(filesize, 0, 8);
    System.out.println(new String(filesize));
    fis.mark(9);
    fis.read(ivBytes, 0, 16);
    System.out.println(new String(ivBytes));
    fis.mark(25);
    IvParameterSpec iv = new IvParameterSpec(ivBytes);
    SecretKeySpec sks = new SecretKeySpec(password.getBytes(), "AES");
    Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
    cipher.init(Cipher.DECRYPT_MODE, sks, iv);
    File file = new File(inputFile);
    int byteLength = (int) file.length() - 24;
    System.out.println(Integer.toString(byteLength));
    byte[] bytes = new byte[byteLength];
    byteLength = fis.read(bytes);
    System.out.println(Integer.toString(byteLength));
    System.out.println(new String(bytes));
    InputStream bytesStream = new ByteArrayInputStream(bytes);
    CipherInputStream cis = new CipherInputStream(bytesStream, cipher);

    int b;
    byte[] d = new byte[1024];
    while((b = cis.read(d)) != -1) {
        fos.write(d, 0, b);
    }
    fos.flush();
    fos.close();
    cis.close();
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.