1

New to bouncyCastle, any help appreciated. I am trying to decrypt a file encrypted by third party on my system using bounncycastle java API. It seems to decrypt file fine except for the blob of junk data at the beginning on the decrypted file.Code below

PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new CBCBlockCipher(
                    new AESEngine()));
            CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(DatatypeConverter.parseHexBinary(keyInfo.getKey())),
                    DatatypeConverter.parseHexBinary(keyInfo.getInitializationVector()));
            aes.init(false, ivAndKey);

            byte[] decryptedBytes = cipherData(aes, Base64.decodeBase64(inputStreamToByteArray(new FileInputStream(encryptedFile))));

            return new ByteArrayInputStream(decryptedBytes);

private static byte[] cipherData(PaddedBufferedBlockCipher cipher, byte[] data)
        throws Exception {
    int minSize = cipher.getOutputSize(data.length);
    byte[] outBuf = new byte[minSize];
    int length1 = cipher.processBytes(data, 0, data.length, outBuf, 0);
    int length2 = cipher.doFinal(outBuf, length1);
    int actualLength = length1 + length2;
    byte[] result = new byte[actualLength];
    System.arraycopy(outBuf, 0, result, 0, result.length);
    return result;
}
private byte[] inputStreamToByteArray(InputStream is) throws IOException {

    ByteArrayOutputStream buffer = new ByteArrayOutputStream();

    int numberRead;
    byte[] data = new byte[16384];

    while ((numberRead = is.read(data, 0, data.length)) != -1) {
        buffer.write(data, 0, numberRead);
    }

    buffer.flush();

    return buffer.toByteArray();
}

Decrypted data blob looks fine except for the beginning "???&??ovKw?????C??:?8?06??85042| | "

The openssl command to decrypt the file works fine command below. In fact I am using the key and iv printed out by openssl when decrypting.

openssl aes-256-cbc -d -salt -in encryptedfile.txt -pass pass:password -a -p

  • When printing out random bytes, please use the BouncyCastle `Hex.encodeToString(byte[])` method. – Maarten Bodewes Jun 07 '15 at 19:15
  • Usually [`EVP_BytesToKey`](http://wiki.openssl.org/index.php/Manual:EVP_BytesToKey(3)) is one of the issues. See [Java equivalent of C++ encryption](http://stackoverflow.com/q/12920740/608639), [How to use OpenSSL generated keys in Java?](http://security.stackexchange.com/q/9600/29925), [Java openssl encryption / decryption key generation](http://stackoverflow.com/q/34502705/608639), [Password to key function compatible with OpenSSL commands?](http://stackoverflow.com/q/9488919), [How to decrypt file in Java encrypted with openssl command using AES?](http://stackoverflow.com/q/11783062), etc. – jww Sep 27 '17 at 10:55

1 Answers1

2

The solution is simple: skip the first 16 bytes of the ciphertext blob. The encrypted blob starts with a magic (you can try and read the first 8 bytes as ASCII text), then 8 bytes of random salt that are used together with the password to derive the key and the IV (using an OpenSSL proprietary password hashing mechanism called EVP_BytesToKey).

Because the previous block is used as a vector for the next block in CBC the followup block of 16 bytes is also affected, giving you 32 random bytes at the start. Instead byte 16 to 31 should have been XOR'ed with the IV.

Here's a Java implementation of BytesToKey posted by using my old nickname.

Community
  • 1
  • 1
Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • Thanks a lot, makes much more sense now. From your pointers ended up deriving key and IV from password and skipping 16 bytes on ciphertext to get rid of the blob. – eatcodelift Jun 08 '15 at 07:00
  • That's the ticket. Note that the BytesToKey is not the best PBKDF (Password Based Key Derivation Function). It only uses a single iteration by default; if possible you should switch to PBKDF2 and/or a high iteration count. Or you can use really strong passwords of course. – Maarten Bodewes Jun 08 '15 at 07:02