Search code examples
javaencryptionbouncycastlerijndael

Pad block corrupted error decoding Rijndael 256 with BouncyCastle


This is my decoding class, it's using Bouncycastle, Rijndael 256 decryption. I have a error on:

mode.doFinal(decoded, bytesProcessed);

Stacktrace:

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)
    at com.imocom.cryptography.Decoder.decrypt(Decoder.java:71)
    at TestingLauncher.main(TestingLauncher.java:46)

This is the php code doing the encoding:

<?php 
    $string = "This is a sample string.";
    $secret = "1234567890987654321234567898765";

    $result = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256,
                                            $secret,
                                            $string,
                                            MCRYPT_MODE_CBC,
                                            "1234567890123455555555555555555"
                                           ));

    echo $result."\n";

    $back = mcrypt_decrypt(MCRYPT_RIJNDAEL_256,
                          $secret,
                          base64_decode($result),
                          MCRYPT_MODE_CBC,
                          "12345678999999999999999999999999");

    echo $back."\n";
    ?>

This is the call:

byte[] decoded;
decoded = decoder.decrypt(Base64.decodeBase64(encodedTextFromServer));

Can anyone help me, why is this happening ?

public class Decoder {

byte[] IV = null;
byte[] encryptionKey = null;
Cipher cipher;
SecretKeySpec key;
BlockCipher blockCipher;
ParametersWithIV _param;

PaddedBufferedBlockCipher mode;
int blockSize;

public Decoder() {

    Security.addProvider(new BouncyCastleProvider());

    try {

        IV = "1234543333333333333333333333333".getBytes("UTF-8");
        encryptionKey = "12222222222222222222222222222222".getBytes("UTF-8");

        blockCipher = new CBCBlockCipher(new RijndaelEngine(256));
        _param = new ParametersWithIV(new KeyParameter(encryptionKey), IV);
        mode = new PaddedBufferedBlockCipher(blockCipher);
        blockSize = blockCipher.getBlockSize();

    } catch (Exception e) {

    }

}

public byte[] decrypt(byte[] encodedText) {

    byte[] decoded = new byte[mode.getOutputSize(encodedText.length)];

    try {
        mode.init(false, _param);


        int bytesProcessed = mode.processBytes(encodedText, 0, encodedText.length, decoded, 0);

        mode.doFinal(decoded, bytesProcessed);
    } catch (Exception e) {
        e.printStackTrace();
    }

    return decoded;
}

Solution

  • From the JavaDoc of the constructor PaddedBufferedBlockCipher in Bouncy Castle:

    Create a buffered block cipher PKCS7 padding

    However PHP by default does not use a good padding mode, instead it simply adds zero valued bytes until the end of the block is reached. This is known as ZeroBytePadding in Bouncy Castle.

    So please use either ZeroBytePadding, or better, implement PKCS#7 padding in PHP.