0

I was trying to do encryption of videos and pdf. After i get the stream of each file, i divided into buffers, then i encrypt each one and combine all buffers into one encrypted file.

For encryption everything works fine but when i am trying to decrypt the file by the same way I am getting error at doFinal which is

{BadPaddingException : pad block corrupted BaseBlockCipher.engineDoFinal(BaseBlockCipher.java:739)}

here is the code I am testing

Encryption

public static byte[] encodeFile(byte[] key, byte[] fileData) throws Exception
    {

        SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);

        byte[] encrypted = cipher.doFinal(fileData);

        return encrypted;
    }

Decryption

public static byte[] decodeFile(byte[] key, byte[] fileData)
{
    byte[] decrypted=new byte[0];
    try {
        SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
        Cipher cipher = Cipher.getInstance("AES");

        cipher.init(Cipher.DECRYPT_MODE, skeySpec);

         decrypted= cipher.doFinal(fileData);
    } catch (IllegalBlockSizeException e) {
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (BadPaddingException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        e.printStackTrace();
    }

    return decrypted;
}

Generate key

   public static byte[] generateKey(String password) throws Exception
    {
        byte[] keyStart = password.getBytes("UTF-8");

        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
        sr.setSeed(keyStart);
        kgen.init(256, sr);
        SecretKey skey = kgen.generateKey();
        return skey.getEncoded();
    }

here is how i decrypt the file

public void decryptStream(String filePath) {

    String outPath = Environment.getExternalStorageDirectory().toString() + "/" + fileName + "de" + "." + fileExtention;
    filePath += "_secured." + fileExtention;
    byte[] data = new byte[1024];
    byte[] decryptData;
    File file = new File((filePath));

    File deFile = new File(outPath);
    InputStream inputStream = null;
    try {
        inputStream = FileUtils.openInputStream(file);
    } catch (IOException e) {
        e.printStackTrace();
    }
    BufferedOutputStream bos = null;
    try {
        bos = new BufferedOutputStream((new FileOutputStream(deFile)));
        while ((inputStream.read(data)) != -1) {
            decryptData = decryptByteArray(data);
            bos.write(decryptData);
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

}
private byte[]  decryptByteArray(byte[] input) {
    Encryption e=new Encryption();
    byte[]decryptedBytes = new byte[0];
    try {
        byte[] yourKey = e.generateKey("password");
        decryptedBytes = e.decodeFile(yourKey, input);

    } catch (FileNotFoundException e1) {
        e1.printStackTrace();
    } catch (IOException e1) {
        e1.printStackTrace();
    } catch (Exception e1) {
        e1.printStackTrace();
    }
    return decryptedBytes;
}
1
  • Apart from the BadPaddingException there are several things not optimal with this code. For example why do you encrypt and decrypt in 1024 byte chunks, restarting the cipher for each chunk, instead of doing the whole file in one go? Commented Oct 8, 2015 at 5:05

1 Answer 1

1

The problem is most likely here:

    while ((inputStream.read(data)) != -1) {
        decryptData = decryptByteArray(data);
        bos.write(decryptData);
    }

When you read a file that is not a multiple of 1024 bytes long, the last read will not completely fill the byte array but you pass the whole array into decryptByteArray.

Also note, that there is no guarantee that read will fill the array completely even for intermediate reads. Always check the return value which gives the number of bytes actually read.

The question does not show how the encryption is done. If padding is used in the cipher, each encryption of a 1024 byte chunk will be longer than 1024 bytes (because of the added padding block). For decryption the whole ciphertext (including the padding) must be processed in one go. Just using the first 1024 bytes will lead to the BadPaddingException.

Sign up to request clarification or add additional context in comments.

4 Comments

But i am using the same way for encrypting and it is working. the problem occurs only when i try to decrypt using doFinal.
You would not notice this when encrypting unless you check that the result is byte wise correct.
If padding is added, the encrypted file must be longer than the original. Is that the case?
you are right the encryption also have problem, it is not correct.

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.