kelheor
kelheor

Reputation: 174

How to encrypt/decrypt files with PBE AES using BouncyCastle Lightweight API?

I'm trying to encrypt/decrypt files with PBE using AES. I'm using Bouncy Casle library(lightweight API), because I need to ignoring restrictions on key length. I found function and changed some code in it.

public void decryptLW(InputStream in, OutputStream out, String password, byte[] salt, final int iterationCount) throws Exception {

    PKCS12ParametersGenerator pGen = new PKCS12ParametersGenerator(new SHA256Digest());
    char[] passwordChars = password.toCharArray();
    final byte[] pkcs12PasswordBytes = PBEParametersGenerator.PKCS12PasswordToBytes(passwordChars);
    pGen.init(pkcs12PasswordBytes, salt, iterationCount);
    CBCBlockCipher aesCBC = new CBCBlockCipher(new AESEngine());
    ParametersWithIV aesCBCParams = (ParametersWithIV) pGen.generateDerivedParameters(256, 128);
    aesCBC.init(false, aesCBCParams);
    PaddedBufferedBlockCipher aesCipher = new PaddedBufferedBlockCipher(aesCBC, new PKCS7Padding());

    try {

        // Read in the decrypted bytes and write the cleartext to out
        int numRead = 0;
        while ((numRead = in.read(buf)) >= 0) {

            byte[] plainTemp = new byte[aesCipher.getOutputSize(buf.length)];
            int offset = aesCipher.processBytes(buf, 0, buf.length, plainTemp, 0);
            int last = aesCipher.doFinal(plainTemp, offset);
            final byte[] plain = new byte[offset + last];
            System.arraycopy(plainTemp, 0, plain, 0, plain.length);

            out.write(plain, 0, numRead);
        }
        out.close();
        in.close();
    } catch (java.io.IOException e) {
    }

}

And I have an error:

org.bouncycastle.crypto.InvalidCipherTextException: pad block corrupted
at org.bouncycastle.crypto.paddings.PKCS7Padding.padCount(Unknown Source)
at org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher.doFinal(Unknown Source)

What can I do to remove this error? And what I must to change in this function to get ability to encrypt files.

Upvotes: 0

Views: 3891

Answers (2)

kelheor
kelheor

Reputation: 174

Finally, I found problem, I don't have initialized aesCipher. When I added method aesCipher.init(true, aesCBCParams); it started working.

And also I changed some code:

int numRead = 0;
        while ((numRead = fin.read(buf)) >= 0) {
            if (numRead == 1024) {
                byte[] plainTemp = new byte[aesCipher.getUpdateOutputSize(numRead)];
                int offset = aesCipher.processBytes(buf, 0, numRead, plainTemp, 0);

                final byte[] plain = new byte[offset];
                System.arraycopy(plainTemp, 0, plain, 0, plain.length);
                fout.write(plain, 0, plain.length);
            } else {
                byte[] plainTemp = new byte[aesCipher.getOutputSize(numRead)];
                int offset = aesCipher.processBytes(buf, 0, numRead, plainTemp, 0);
                int last = aesCipher.doFinal(plainTemp, offset);
                final byte[] plain = new byte[offset + last];
                System.arraycopy(plainTemp, 0, plain, 0, plain.length);
                fout.write(plain, 0, plain.length);
            }
        }

Upvotes: 1

rossum
rossum

Reputation: 15685

You have a problem with your padding. This may mean that the incoming cyphertext was encrypted with a different padding, not PKCS7. It may mean that the incoming cyphertext was encrypted in a different mode (not CBC). It may mean that you have the wrong key, so the last block decrypts as random. If your message is only one block long then it may mean you have a faulty IV, so again the padding is corrupt.

You need to check that the key, mode, padding and IV are identical at both ends. This means checking key and IV byte by byte.

Upvotes: 0

Related Questions