views:

355

answers:

3

Hi,

This is my original xml:

<?xml version="1.0" encoding="UTF-8"?>
<table>
    <row>
     <id>12</id>
     <name>Mickey Mouse</name>
    </row>
</table>

This is the output after going through encryption/decryption process

<?xml version="1.0" encoding="UTF-8"?>
<table>
    <row>
     <id>12</id>
     <name>Mickey Mouse</name>
    </row>
</

As you can see, few characters are missing.

here is my code.

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

public class Decrypter
{

    /**
     * @param args
     * @throws IOException
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     */
    public static void main(String[] args) throws IOException,
        NoSuchAlgorithmException, NoSuchPaddingException,
        InvalidKeyException, IllegalBlockSizeException, BadPaddingException
    {
    // TODO Auto-generated method stub
    File iFile = new File("normal.xml");
    FileInputStream fis = new FileInputStream(iFile);

    File oFile = new File("normal.xml.encrypted");
    FileOutputStream fos = new FileOutputStream(oFile);

    String algorithm = "DESede";
    byte[] keyBytes = new byte[] { 0x34, 0x11, 0x12, 0x06, 0x34, 0x11,
     0x12, 0x06, 0x34, 0x11, 0x12, 0x06, 0x34, 0x11, 0x12, 0x06,
     0x34, 0x11, 0x12, 0x06, 0x34, 0x11, 0x12, 0x06 };

    SecretKeySpec key = new SecretKeySpec(keyBytes, algorithm);

    // generates encrypted output from normal.xml.
    Cipher cipher = Cipher.getInstance(algorithm);
    cipher.init(Cipher.ENCRYPT_MODE, key);
    CipherOutputStream cos = new CipherOutputStream(fos, cipher);

    int b;
    while ((b = fis.read()) != -1)
    {
        cos.write(b);
    }

    fos.close();
    fos = null;
    fis.close();
    fis = null;

    System.out.println("done");

    // decrypt encrypted xml to normal xml. 
    File ieFile = new File("normal.xml.encrypted");
    FileInputStream fies = new FileInputStream(ieFile);

    Cipher ieCipher = Cipher.getInstance(algorithm);
    ieCipher.init(Cipher.DECRYPT_MODE, key);
    CipherInputStream cis = new CipherInputStream(fies, ieCipher);

    File oeFile = new File("normal.xml.encrypted.xml");
    FileOutputStream foes = new FileOutputStream(oeFile);

    int c;
    while ((c = cis.read()) != -1)
    {
        foes.write(c);
    }

    foes.close();
    cis.close();
    fies.close();

    System.out.println("done done");
    }

}

Please help. Thanks.

+1  A: 

Try closing (or at least flushing) your CipherOutputStream (cos) as there may be some bytes that never got written to the original encrypted file.

Adam Batkin
I tried to flush them before closing the foscos.flush();fos.flush();fos.close();cos.close();Still doesn't work.
janetsmith
Flushing is not enough since the CipherOutputStream needs to know that there will be no more data before it can write the final block.
Rasmus Faber
+6  A: 

Found the problem. Do

     cos.close();

before the line:

     fos.close();

At least, that fixed it on my box.

Don Branson
Thanks! Never thought the closing sequence of io stream will affect the result. The moral of the story: Always close the outer layer of input/output stream.
janetsmith
+3  A: 

After writing the encrypted output, call

cos.close();

instead of

fos.close();

Closing the cos object also closes the underlying fos object.

jkf