views:

34

answers:

1

I got an annoying problem here I have no clue about how to solve...

A system writes encrypted data to files, some are serialized objects, others text (XML) files. The base class that does the decryption when needed initializes a Cipher with AES encryption, prepares a key (read from a file) and has to ways to access data:

A way to get an InputStream:

public InputStream getInputStream(File pFile) throws IOException {
  return
    new CipherInputStream(
      new BufferedInputStream(new FileInputStream(pFile)),
      getCipher(Cipher.DECRYPT_MODE)
    );
}

and a method to read an object that just wraps an ObjectInputStream around the InputStream derived from this method and reads the object using ObjectInputStream.readObject().

Now. Within the software system, everything works this way. What I wanted to write is a command line tool to help decrypt files for the support. So, I used exactly the same methods to get my Cipher, I even used the identical class and the InputStream built there.

But: no matter what I do: only the first 208 (!) bytes get decrypted, the rest stays encrypted!

I tried to simply "copy" the data from this InputStream to a new OutputStream using a byte buffer, but I also tried just getting a String from the data to see what's happening in a Debugger. => effect is always the same. Up to this "border" of 208 bytes, I see clear text - followed by trash.

I have no idea what could go wrong here! Any clues??

The Cipher is created like this:

public Cipher getCipher(int opMode) throws IOException {
    Cipher cipher = null;

    try {
        cipher = Cipher.getInstance("AES");
    } catch (NoSuchAlgorithmException e) {
        throw new MdmFatalInternalErrorException("Getting instance of cipher failed. Should never happen. BUG ", e);
    } catch (NoSuchPaddingException e) {
        throw new MdmFatalInternalErrorException("Getting instance of cipher failed. Should never happen. BUG ", e);
    }
    try {
        cipher.init(opMode, readKey());
    } catch (InvalidKeyException e) {
        throw new MdmInvalidKeyException();
    } catch (ClassNotFoundException e) {
        throw new MdmInvalidKeyException();
    } catch (NumberFormatException e) {
        throw new MdmInvalidKeyException();
    }
    return cipher;
}

So, here's the code that actually uses the InputStream IN the software system:

String s = readStream(reader.getInputStream(file));

where readStream is implemented like this:

public String readStream(InputStream is) throws IOException {
    BufferedReader reader = new BufferedReader(new InputStreamReader(is));

    StringBuffer sb = new StringBuffer();
    String line = null;
    try {
        while ((line = reader.readLine()) != null) {
            sb.append(line).append('\n');
        }
    } finally {
        reader.close();
    }

    return sb.toString();
}

All this works (within the software)! But my attempt to read it the same way fails: the String s contains exactly 208 decrypted characters followed by garbage!!

The writing of the XML files is done exactly the other way around, but that really does not matter here because the shown code works within the system, but not in my simple copy program! I use exactly the same class there!! Why on earth all only 208 characters decrypted??

Thanks!