0

I'm having a trouble with Rijndael encryption implementation with BouncyCastle API for Java.

I'm getting the OutputLengthException when I execute cipher.doFinal(inputTextBytes, intOutOff);:

org.bouncycastle.crypto.OutputLengthException: output buffer too short

I do not fully understand how to generate that integer to execute the doFinal() method.

Here is what I'm tried:

public class RijndaelAndRFC2899Implementation {

    final static String WORD = "763059";
    final static String PASSWORD = "515t3ma5m15B4d35";
    final static byte[] SALT = new byte[]{1, 2, 3, 4, 5, 6, 7, 8};
    final static int KEY_SIZE = 256;
    final static int BLOCK_SIZE = 128;
    final static int ITERATIONS = 1000;

    public static void main(String[] args) throws Exception {
        BufferedBlockCipher cipher = getCipher(PASSWORD, true);
        byte[] inputText = WORD.getBytes("UTF-8");
        byte asd[] = new byte[cipher.getOutputSize(inputText.length)];
        int l = cipher.processBytes(inputText, 0, inputText.length, asd, 0);
        int n = cipher.doFinal(inputText, l); //<---HERE PRODUCES OutputLengthException
    }

    private static BufferedBlockCipher getCipher(String password, boolean encrypt) throws Exception {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        md.update(password.getBytes("UTF-8"));
        byte[] newPassword = md.digest();

        PKCS5S2ParametersGenerator generator = new PKCS5S2ParametersGenerator();
        generator.init(newPassword, SALT, ITERATIONS);

        ParametersWithIV iv = ((ParametersWithIV) generator.generateDerivedParameters(KEY_SIZE, BLOCK_SIZE));

        RijndaelEngine engine = new RijndaelEngine();
        BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(engine));   
        cipher.init(encrypt, iv);

        return cipher;
    }

}

Can you help me by understanding what I'm doing wrong?

TimeToCode
  • 901
  • 2
  • 16
  • 34

1 Answers1

2

The call to doFinal() should have the output array as the first arg - not the input you were processing:

public static void main(String[] args) throws Exception {
    BufferedBlockCipher cipher = getCipher(PASSWORD, true);
    byte[] inputText = WORD.getBytes("UTF-8");
    byte asd[] = new byte[cipher.getOutputSize(inputText.length)];
    int l = cipher.processBytes(inputText, 0, inputText.length, asd, 0);
    int n = cipher.doFinal(asd, l); // <--- Change to asd
}

(I have not validated the rest of the implementation!)

Not a JD
  • 1,864
  • 6
  • 14
  • 1
    Also pay attention to the return value from doFinal ('n'); depending on the cipher algorithm, getOutputSize may have overestimated the actual output size, so the output may not have completely filled the output buffer ('asd'). The return value is the incremental output length, so you probably also want "int n = l + cipher.doFinal(asd, l);" instead. – Peter Dettman Apr 17 '19 at 08:13