Flavian
Flavian

Reputation: 65

Bouncycastle java encoding/decoding. Missing bytes?

I need to encode/decode a text using CBC Rijndael encryption.

Input: The force is strong in this looooooooooooooooooo000000000oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong String

Encoded input: ?†´Ú½mΗ“AŽyÝ¢ƒô]5X-å;’Bdž.̵¼èüÈíÖXÈ*©Ã¼ç–hKBµ$híƒEu-ȸU ¤‘AÓÈÿ?Ÿûä¸:OW?B>ÐZ²ñ ,­zÅë(C’®5ÐixRópE%€.@vhrm6µ5©bŠ?Ç¡$q¿J^÷g“e†ì??bt ì%q‘ÕQÚ5µã?ƒ

Decoded input: "The force is strong in this looooooooooooooooooo000000000ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo " - and 32 spaces in place of the ending (byte value is 0)

I'm missing the final bytes. Can anyone tell me why ?

This is my code:

public class BouncyDecoder {

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

PaddedBufferedBlockCipher mode;
int blockSize;

public BouncyDecoder() {
    Security.addProvider(new BouncyCastleProvider());
    try {
        IV = "1234567891234567891234567891234".getBytes("UTF-8");
        encryptionKey = "1234567891123453456789123456781".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 = 0;
        int i=0;
        for (i = 0; i < (encodedText.length / 32) ; i++){               
            bytesProcessed += mode.processBytes(encodedText, i * blockSize, blockSize, decoded, bytesProcessed);
        }

        mode.doFinal(decoded, (i-1)*blockSize);
    } catch (Exception e) {
    }
    return decoded;
}

public byte[] encrypt(byte[] normalText) {
    byte[] encryptedText = new byte[mode.getOutputSize(normalText.length)];
    try {
        mode.init(true, _param);

        int bytesProcessed = 0;
        int i=0;
        for (i = 0; i < (normalText.length / 32); i++) {
            bytesProcessed += mode
                    .processBytes(normalText, i * blockSize, blockSize, encryptedText, bytesProcessed);
        }

        mode.doFinal(encryptedText, (i-1)*blockSize);

    } catch (Exception e) {
        e.printStackTrace();
    }
    return encryptedText;
}

}

Upvotes: 1

Views: 700

Answers (1)

default locale
default locale

Reputation: 13446

Your loop doesn't seem process all of the bytes in input string:

for (i = 0; i < (normalText.length / 32); i++) {
        bytesProcessed += mode
                .processBytes(normalText, i * blockSize, blockSize, encryptedText, bytesProcessed);
}

it only processes bytes from 0 to (text.Length/32)*blockSize.

So if length of input array is 35 bytes, last 3 bytes are never getting processed.

What about using something like this instead:

bytesProcessed = mode.processBytes(normalText, 0, normalText.length, encryptedText,0);
//second argument of doFinal is offset in output buffer.
mode.doFinal(encryptedText, bytesProcessed);

If this one is going to work you'll definitely know that the problem is off-by-one error in loop counter.

UPDATE: Or you can try something like this if you want to encrypt a block at a time:

for(int i=0; i<=(normalText.length/blockSize); i++) {
     int offset = i*blockSize;
     //To handle last block of bytes in input
     int len = Math.min(blockSize,normalText.length-offset);
     bytesProcessed += mode.processBytes(normalText,offset,len,encryptedText,bytesProcessed);
}
mode.doFinal(encryptedText, bytesProcessed);

Same goes for decryption

Upvotes: 1

Related Questions